我将在PHP中说明这一点,但这个问题或多或少与语言无关。
我有一个用五星评级系统投票的产品的平均评分。我们说对于这个乘积$averageRating = 3.43
。我想创建一个模拟的选票分布来得出这个平均值。考虑到你已经有了投票分布,下面是如何确定平均值的:
$distribution = array(
1 => $oneStarVotes,
2 => $twoStarVotes,
3 => $threeStarVotes,
4 => $fourStarVotes,
5 => $fiveStarVotes
);
foreach ($distribution as $key => $value) {
$weightedTotal += $key * $value;
}
$totalVotes = array_sum($distribution);
$averageRating = $weightedTotal / $totalVotes;
有没有人能想到一种方法来逆向工程,这样你就可以为变量$oneStarVotes, $twoStarVotes...etc.
创建值,如果你有$averageRating
?
由于你在寻找任何分布,这是一个简单的代数问题,并考虑找到合理的整数。
我将这样处理这个问题(用伪代码):
Case 1: avg = 1.0
distribution <- { x1, 0, 0, 0, 0 } for any positive integer x1.
Case 2: avg = 5.0
distribution <- { 0, 0, 0, 0, x5 } for any positive integer x5.
Case 3: avg is within (1.0, 5.0)
distribution = { x1, 0, 0, 0, x5 } for some positive integers x1 and x5.
换句话说,将问题简化为只选择1星和5星的选票计数。
要在情况3中求解x1
和x5
,需要在只有1星和5星的投票中选择满足算术平均值方程的x1
和x5
:
(1 * x1 + 5 * x5) / (x1 + x5) = avg
它有助于解决x1
和T
,其中T
是总票数(x1 + x5 = T
)。
通过代数可以写成
x1 = T * (5 - avg) / 4
你可以任意为x1
选择一个值并求解T
,但这并不能保证T
是一个整数。
然而,通过选择一个足够大的x1
值,你可以舍入 T
,比x1
小的时候误差更小。
例如,如果avg = 3.43
(如你的问题所示),我们任意选择x1 = 100
,那么我们得到
avg = 3.43
x1 = 100
T = 254.78
TRounded = 255
x5 = 155
当你把这些值代入算术平均值时,你得到
(1 * 100 + 5 * 155)/255 = 3.431
在这里等于原来的avg
,小数点后2位。情形3的结束公式是
Case 3 (cont.):
x1 <- (a large enough integer)
T <- round (x1 * 4 / (5 - avg))
x5 <- T - x1
distribution <- { x1, 0, 0, 0, x5 }