3

我将在 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吗?

4

1 回答 1

2

由于您正在寻找任何分布,这是一个简单的代数问题,并考虑找到合理的整数。

我将按如下方式处理问题(在伪代码中):

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并且满足仅 1 星和 5 星投票中算术平均值的方程:x5x1x5

(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 }
于 2013-01-03T08:27:03.200 回答