我想在我的网站上为用户创建排名系统。排名将由许多因素决定,例如他们成为会员的时间,他们创建了多少帖子等。每个数据项也除以我确定的“权重”,因此它更具代表性实际的用户活动 - 我不希望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
)
正如你所看到的,有很多用户排名很低,很少有人被分配到中高级别。我想通过计算使用对数刻度分配的等级来解决这个问题,这样就可以很容易地爬上较低等级的等级,并且越高越好。这样它应该更均匀地分布,更多的用户将在中间排名。
我不知道如何处理这个问题,但是我从来没有使用过对数标度,而且总是在我的代码中使用简单的算法。
答案 0 :(得分:0)
您将使用php math logarithm函数并将其映射到最终数组,例如:
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
)