Я хочу создать систему рейтинга для пользователей на моем сайте. Ранги будут зависеть от ряда факторов, таких как, как долго они были участником, сколько постов они создали и т. Д. Каждый элемент данных также делится на «вес», определенный мной, чтобы он был более представительным для фактическая активность пользователя — я не хочу, чтобы 1 сообщение было таким же значительным, как 1 день для пользователя. После взвешивания все характеристики складываются в общую сумму.
Затем я должен нормализовать итоги, чтобы они присваивались разрядам в диапазоне от 1 до 20, поскольку у некоторых участников есть всего несколько очков активности, а у некоторых ветеранов есть тысячи очков. Я делаю это, нормализуя данные и уменьшая их до рангового диапазона 1-20 с помощью этой функции:
function normalize($userTotal, $minOriginalRange, $maxOriginalRange, $minNewRange, $maxNewRange){
return $minNewRange + ((($maxNewRange - $minNewRange) * ($originalValue - $minOriginalRange)) / ($maxOriginalRange - $minOriginalRange));
}
Обычно это называется так:
normalize (getUserTotal (), 0, getHighestTotalOfAllMembers (), 1, 20);
И в результате я получил это, ключ — ранг, а значение — количество членов, которые получили бы этот ранг:
Array
(
[1] => 7418
[2] => 1918
[3] => 289
[4] => 102
[5] => 62
[6] => 28
[7] => 21
[8] => 14
[9] => 1
[10] => 8
[11] => 6
[12] => 5
[13] => 1
[14] => 1
[17] => 1
[20] => 1
)
Как видите, есть тонны пользователей с низким рейтингом, и очень немногие получают средние и высокие оценки. Я хотел бы исправить это, рассчитав ранг, назначенный с использованием логарифмической шкалы, чтобы легко подниматься по рангу на более низких уровнях и становиться все сложнее и сложнее, чем выше вы поднимаетесь. Таким образом, он должен распределяться более равномерно, и больше пользователей получат ранги в середине.
Однако я не знаю, как к этому подойти, я никогда не использовал логарифмические шкалы и всегда прибегал к простой арифметике в своем коде.
Вы должны использовать математическую функцию логарифма php и отобразить ее в конечном массиве, например:
function logfunction($v){
return round(log1p($v),2);
}
$simple_array = [7418, 1918, 289, 102, 62, 28, 21, 14, 1, 8, 6, 5, 1, 1, 1];
$logarithmic_array = array_map(logfunction, $simple_array);
print_r($logarithmic_array);
Выше я использую log1p()
функция, которая возвращается log(1 + number)
рассчитывается таким образом, что является точным, даже если значение числа близко к нулю (см .: http://php.net/manual/en/function.log1p.php). Затем я округляю результат до 2 знаков после запятой для удобства чтения. Результирующий $logarithmic_array
вывод:
Array
(
[0] => 8.91
[1] => 7.56
[2] => 5.67
[3] => 4.63
[4] => 4.14
[5] => 3.37
[6] => 3.09
[7] => 2.71
[8] => 0.69
[9] => 2.2
[10] => 1.95
[11] => 1.79
[12] => 0.69
[13] => 0.69
[14] => 0.69
)
Других решений пока нет …