Viz*_*rai 64 sorting statistics user-experience rating bayesian
我正在尝试使用5星系统按客户评级对一堆产品进行排序.我设置的网站没有很多评级,并继续添加新产品,所以它通常会有一些评级较低的产品.
我尝试使用平均星级评级,但是当评级很少时,该算法会失败.
例如,具有3x5星评级的产品将比具有100x5星评级和2x2星评级的产品更好.
第二个产品是否应该显得更高,因为它在统计上更值得信赖,因为评级数量更多?
Mar*_*ris 71
在2015年之前,互联网电影数据库(IMDb)公开列出了用于对其250强电影列表进行排名的公式.报价:
计算最高额定250标题的公式给出了真正的贝叶斯估计:
Run Code Online (Sandbox Code Playgroud)weighted rating (WR) = (v ÷ (v+m)) × R + (m ÷ (v+m)) × C哪里:
- R =电影的平均值(平均值)
- v =电影的投票数
- m =要求列入前250名的最低票数(目前为25000)
- C =整个报告的平均投票数(目前为7.0)
对于前250名,只考虑普通选民的投票.
这并不难理解.公式是:
rating = (v / (v + m)) * R +
(m / (v + m)) * C;
Run Code Online (Sandbox Code Playgroud)
可以在数学上简化为:
rating = (R * v + C * m) / (v + m);
Run Code Online (Sandbox Code Playgroud)
变量是:
[1, 5].等等.)[2, 3, 5, 5].C是3.75,这些数字的平均值.)所有公式都是:在计算平均值之前,添加m个虚构的投票,每个投票的值为C.一开始,当没有足够的数据(即投票数远远小于m)时,这会导致空白用平均数据填充.然而,随着选票的累积,最终虚构的选票将被真实的投票淹没.
在这个系统中,投票不会导致评级大幅波动.相反,他们只是在某个方向上稍微扰乱它.
当存在零票时,仅存在虚构的投票,并且所有投票都是C.因此,每个项目以C的评级开始.
也可以看看:
unu*_*tbu 17
Evan Miller采用贝叶斯方法对五星评级进行排名:

哪里
nk是k星级评分的数量,sk是k恒星的"价值"(以分为单位),N 是总票数K 是最大星数(例如K = 5,在5星评级系统中)z_alpha/2是1 - alpha/2正态分布的分位数.如果您希望95%置信度(基于贝叶斯后验分布)实际排序标准至少与计算排序标准一样大,则选择z_alpha/2= 1.65.在Python中,可以使用计算排序标准
def starsort(ns):
"""
http://www.evanmiller.org/ranking-items-with-star-ratings.html
"""
N = sum(ns)
K = len(ns)
s = list(range(K,0,-1))
s2 = [sk**2 for sk in s]
z = 1.65
def f(s, ns):
N = sum(ns)
K = len(ns)
return sum(sk*(nk+1) for sk, nk in zip(s,ns)) / (N+K)
fsns = f(s, ns)
return fsns - z*math.sqrt((f(s2, ns)- fsns**2)/(N+K+1))
Run Code Online (Sandbox Code Playgroud)
例如,如果一个项目有60颗五颗星,80颗四颗星,75颗三颗星,20颗两颗星和25颗一颗星,那么它的整体星级评分约为3.4:
x = (60, 80, 75, 20, 25)
starsort(x)
# 3.3686975120774694
Run Code Online (Sandbox Code Playgroud)
你可以用5种星级排序列表
sorted([(60, 80, 75, 20, 25), (10,0,0,0,0), (5,0,0,0,0)], key=starsort, reverse=True)
# [(10, 0, 0, 0, 0), (60, 80, 75, 20, 25), (5, 0, 0, 0, 0)]
Run Code Online (Sandbox Code Playgroud)
这显示了更多评级可能对整体恒星价值产生的影响.
您会发现这个公式的整体评分往往略低于亚马逊,Ebay或沃尔玛等网站报告的整体评分,特别是在投票数较少(比如少于300)时.这反映了较少的选票带来的更高的不确定性.随着投票数增加(成千上万)所有这些评级公式应该倾向于(加权)平均评级.
由于该公式仅取决于项目本身的五星评级的频率分布,因此通过简单地将频率分布加在一起,很容易组合来自多个来源的评论(或者, 根据新投票更新总体评级).
与IMDb公式不同,此公式不依赖于所有项目的平均分数,也不依赖于人工最小投票截止值.
此外,这个公式利用了全频率分布 - 不仅仅是平均星数和投票数.它应该是有道理的,因为具有10个5星和10个1星的项目应该被视为具有更多的不确定性(因此没有被评为高度)具有20个3星评级的项目:
In [78]: starsort((10,0,0,0,10))
Out[78]: 2.386028063783418
In [79]: starsort((0,0,20,0,0))
Out[79]: 2.795342687927806
Run Code Online (Sandbox Code Playgroud)
IMDb公式没有考虑到这一点.
那么,根据你想要制作它的复杂程度,你可以根据这个人制作了多少评分以及这些评分是多少来对收视率进行加权.如果这个人只做了一个评级,那么它可能是一个评级,并且可能算得更少.或者如果这个人在类别a中评定了很多东西,但在类别b中评分很少,并且平均评分为1.5星的5星级,则听起来像a类别可能会被该用户的低平均分数人为压低,并且应该调整.
但足以让它变得复杂.让我们简单一点.
假设我们只使用两个值,即ReviewCount和AverageRating,对于特定项目,我认为将ReviewCount视为"可靠性"值是有意义的.但我们并不只是希望将得分降低至较低的ReviewCount项目:单个一星评级可能与单个5星评级不可靠.所以我们想要做的可能是中间平均值:3.
所以,基本上,我正在考虑一个像X*AverageRating + Y*3 =我们想要的评级这样的等式.为了使这个值正确,我们需要X + Y等于1.此外,当ReviewCount增加时,我们需要X增加值...审查计数为0,x应为0(给我们一个等式" 3"),并且无限复查计数X应为1(这使得等式= AverageRating).
那么什么是X和Y方程?对于X方程,当自变量接近无穷大时,希望因变量渐近逼近1.一组好的方程式如下:Y = 1 /(factor ^ RatingCount)和(利用X必须等于1-Y的事实)X = 1 - (1 /(factor ^ RatingCount)
然后我们可以调整"因子"以适应我们正在寻找的范围.
我用这个简单的C#程序尝试了几个因素:
// We can adjust this factor to adjust our curve.
double factor = 1.5;
// Here's some sample data
double RatingAverage1 = 5;
double RatingCount1 = 1;
double RatingAverage2 = 4.5;
double RatingCount2 = 5;
double RatingAverage3 = 3.5;
double RatingCount3 = 50000; // 50000 is not infinite, but it's probably plenty to closely simulate it.
// Do the calculations
double modfactor = Math.Pow(factor, RatingCount1);
double modRating1 = (3 / modfactor)
+ (RatingAverage1 * (1 - 1 / modfactor));
double modfactor2 = Math.Pow(factor, RatingCount2);
double modRating2 = (3 / modfactor2)
+ (RatingAverage2 * (1 - 1 / modfactor2));
double modfactor3 = Math.Pow(factor, RatingCount3);
double modRating3 = (3 / modfactor3)
+ (RatingAverage3 * (1 - 1 / modfactor3));
Console.WriteLine(String.Format("RatingAverage: {0}, RatingCount: {1}, Adjusted Rating: {2:0.00}",
RatingAverage1, RatingCount1, modRating1));
Console.WriteLine(String.Format("RatingAverage: {0}, RatingCount: {1}, Adjusted Rating: {2:0.00}",
RatingAverage2, RatingCount2, modRating2));
Console.WriteLine(String.Format("RatingAverage: {0}, RatingCount: {1}, Adjusted Rating: {2:0.00}",
RatingAverage3, RatingCount3, modRating3));
// Hold up for the user to read the data.
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)
所以你不打扰复制它,它给出了这个输出:
RatingAverage: 5, RatingCount: 1, Adjusted Rating: 3.67
RatingAverage: 4.5, RatingCount: 5, Adjusted Rating: 4.30
RatingAverage: 3.5, RatingCount: 50000, Adjusted Rating: 3.50
Run Code Online (Sandbox Code Playgroud)
那样的东西?显然,您可以根据需要调整"因子"值,以获得所需的权重.