Масштабирование и нормализация данных с использованием логарифмической шкалы

Я хочу создать систему рейтинга для пользователей на моем сайте. Ранги будут зависеть от ряда факторов, таких как, как долго они были участником, сколько постов они создали и т. Д. Каждый элемент данных также делится на «вес», определенный мной, чтобы он был более представительным для фактическая активность пользователя — я не хочу, чтобы 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
)

Как видите, есть тонны пользователей с низким рейтингом, и очень немногие получают средние и высокие оценки. Я хотел бы исправить это, рассчитав ранг, назначенный с использованием логарифмической шкалы, чтобы легко подниматься по рангу на более низких уровнях и становиться все сложнее и сложнее, чем выше вы поднимаетесь. Таким образом, он должен распределяться более равномерно, и больше пользователей получат ранги в середине.

Однако я не знаю, как к этому подойти, я никогда не использовал логарифмические шкалы и всегда прибегал к простой арифметике в своем коде.

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
)
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]