Расчет рейтинга пользователей

6 апреля 2011 г.

На данный момент занимаюсь разработки системы рейтинга пользователей, комментариев, статей и т.п. Поэтому возникла необходимость понять и воплотить сущность расчета этой величины.

Расчет рейтинга

В данной статье я коснусь только процесса голосования за пользователей и расчета приращений рейтинга, потому как другие рейтинги (например, комментариев или статей) могут быть аналогичным образом.

Приращение рейтинга пользователя при голосовании за него (“+”) складывается из двух составляющих:

  • часть, которая зависит от Рейтинга этого пользователя
  • часть, которая зависит от Силы голосующего пользователя

Ниже я поясню, как рассчитываются эти части, а пока выберем параметр maxDeltaValue, значение которого является максимальным приращением рейтинга пользователя.

Примем, что первая часть приращения будет составлять 20% от максимального, а вторая — 80%. Т.е. основной вклад в приращение вносит именно Сила голоса голосующего пользователя.

В итоге имеем:
dРейтинг_а = f_1(Рейтинг_а) + f_2(Сила_б) <= maxDeltaValue

f_1 и f_2 — это некоторые функции, по которым рассчитываются составляющие приращения, зависящие от Рейтинга пользователя, за которого голосуют и Силы того, кто голосует соответственно.

Первая часть приращения

В этой части нужно выбрать убывающую функцию, чтобы значение данного приращения уменьшалось с ростом рейтинга пользователя. Это сделано, чтобы поддерживать новичков и рейтинги старичков не взлетали до небес (с этой точки зрения). Я выбрал экспонентциальную зависимость:
f_1® = a * exp(-b*R)

F_1®

Указанная функция будет стремиться к 0 с ростом значения рейтинга. Максимальное значение функции будет достигаться в точке с нулевым рейтингом в диапазоне рейтингов от 0 до бесконечности. Это значение равно параметру a указанной функции. Коэффициент b отвечает за скорость убывания функции, его можно выбрать любым (я выбрал b=0.005 для большей плавности).
Т.к. мы предположили, что первая часть приращение вносит вклад в общее приращение до 20%, сл. параметр a = 0.2 * maxDeltaValue.

// Приращение за счет рейтинга пользователя:
function f_1($rating)
{
global $maxRatingValue;$a = 0.2 * $maxRatingValue;
$b = 0.005;

return ($a * exp(-$b*$rating));
}

Вторая часть приращения

Здесь я использую возрастающую функцию. В данном случае — логарифм (натуральный). Сначала хотел использовать функцию, имеющую асимптоту.
Параметром функции является Сила пользователя (сила его голоса), которая, в моем случае, не является отдельной величиной, а выражается через рейтинг.

Сила также выражается логарифмической зависимостью, причем график функции такого логарифма должен проходить через точки:

  • (0;1) — при нулевом рейтинге (новый пользователь) Сила голоса равна 1.
  • (-N; 0), где -N — это значение рейтинга, при котором пользователь фактически теряет Силу голоса.

Потеря силы голоса

Решив простую систему уравнений можно получить функцию логарифма.
S® = log(((b - 1) / N) * R + b)

Значение Силы будет зависеть от основания логарифма и параметра b, который также зависит от основания. Если брать десятичный логарифм, то b = 10. При натуральном логарифме — b равно экспоненте. N – абсолютное значение рейтинга, когда пользователь теряет Силу.
В своей задаче я выбрал десятичный логарифм и N = 10.

function getSkill($rating)
{
$b = 10;
$N = 10;return(log10((($b - 1) / $N) * $rating + $b));
}

Вернемся к расчету второй части приращения:
f_2(S) = log(a*S + b)

Будем считать, что Сила пользователя изменяется от 0 до максимум 6 (значения больше 6 не рассматриваем). Сначала получим общую функцию логарифма, график которого проходит через точки (0;0) и (2; locMax), где locMax – некоторое условно максимальное значение.

f_2(S) = ln(((exp(locMax) - 1) / 2) * S + 1)

F_2(S)

Однако необходимо выполнить условие, что значение этой функции не будет превышать 80% от maxDeltaValue. Поэтому, точку (2; locMax) нельзя брать как максимальную. Поэтому найдем значение этой функции в точке с Силой равной 6 (как было предположено ранее, это максимальное значение Силы). В этой точке и примем максимум.
В итоге получаем следующую формулу:
f_2(S) = ln(((exp(0.8 * maxDeltaValue) - 5) / 6) * S + 1)

Силу пользователя можно получить из его рейтинга с помощью указанной выше функции getSkill().

// Приращение за счет Силы голосующего:
function f_2($rating)
{
global $maxRatingValue;$a = 0.8 * $maxRatingValue;

return (log(((exp($a) - 5) / 6) * getSkill($rating) + 1));
}

Итог

Итоговое приращение рейтинга пользователя равно сумме указанных выше двух частей. Стоит отметить, что эти части являются абсолютными значениями, то есть рассмотрено голосование в сторону “+”. Думаю, понятно, как это будет работать при голосовании в “-“.

Угасание рейтинга

Многими была предложена идея угасания рейтинга с течением времени. Я предлагаю ввести множество «несгораемых» значений рейтинга, достигнув которые, нельзя будет потерять со временем. «Сбить» с них можно будет уменьшением рейтинга другими пользователями.
Угасание рейтинга

Падение значения рейтинга со временем будет идти по экспонентам с различными скоростями угасания.

  • Похожие статьи
  • Предыдущие из рубрики