如何对给定平均值的加权五星分布进行逆向工程


How to reverse engineer a weighted five star distribution when given its average value?

我将在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中求解x1x5,需要在只有1星和5星的投票中选择满足算术平均值方程的x1x5:

(1 * x1 + 5 * x5) / (x1 + x5) = avg

它有助于解决x1T,其中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 }