5星评级sorting的更好方法是什么?
我正在尝试使用5星级系统按顾客评级对一堆产品进行分类。 我正在设置这个网站没有很多的评级,并继续增加新的产品,所以它通常会有一些less数的评级产品。
我尝试使用平均星级评分,但是当less量评级时algorithm失败。
例如,具有3x 5星评级的产品将显示比具有100x 5星评级和2x 2星评级的产品好。
第二个产品不应该显得更高,因为它在统计上更值得信赖,因为收视率更高?
对于他们的前250名电影列表IMDB使用贝叶斯估计 。 考虑到选民数量,这是一个很好的方法。
从这里 :
计算最高评分250标题的公式给出了一个真正的贝叶斯估计:
加权评分(WR)=(v÷(v + m))×R +(m÷(v + m))×C
哪里:
* R = average for the movie (mean) = (Rating) * v = number of votes for the movie = (votes) * m = minimum votes required to be listed in the Top 250 (currently 1300) * C = the mean vote across the whole report (currently 6.8)
对于前250名,只考虑普通选民的投票。
你可以看看这个页面,以获得一个星级评分:
http://www.evanmiller.org/ranking-items-with-star-ratings.html
你可以看看这个页面,以得到一个很好的分析上下投票:
http://www.evanmiller.org/how-not-to-sort-by-average-rating.html
对于上下投票,你想估计给定的评分的概率,“真实”的分数(如果你有无限的评级)大于一些数量(比如说,你是一些其他项目的相似数字sorting)。
见第二篇文章的答案,但结论是你要使用威尔逊的信心。 文章给出了等式和示例Ruby代码(很容易翻译成另一种语言)。
你可以按中位数而不是算术平均数来sorting。 在这种情况下,两个例子的中位数都是5,所以两者在sortingalgorithm中的权重相同。
你可以使用一个模式来达到同样的效果,但是中位数可能是一个更好的主意。
如果您想为产品增加100个5星评级,您可能会想要采用某种加权模式,将更多的权重分配给中位数相同的评级,但总体投票更多。
埃文·米勒(Evan Miller)展示了贝叶斯方法来评定五星评级:
哪里
-
nk
是k
star评级的数量, -
sk
是k
星的“价值”(分) -
N
是总票数 -
K
是星星的最大数量(例如在五星级评分系统中,K = 5) -
z_alpha/2
是z_alpha/2
的1 - alpha/2
分位数。 如果您希望95%的置信度(基于贝叶斯后验分布)实际的sorting标准至less与计算出的sorting标准一样大,请selectz_alpha/2
= 1.65。
在Python中,sorting标准可以用
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))
例如,如果一个项目有60个五星,80个四星,75个三星,20个二星和25个一星,那么它的整体星级将是3.4:
x = (60, 80, 75, 20, 25) starsort(x) # 3.3686975120774694
你可以用一个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)]
这显示了更多评级可能对整体星级价值的影响。
你会发现这个公式的总体评分低于亚马逊,易趣或沃尔玛等网站的总体评分,特别是当票数很less(比如说less于300)的时候。 这反映了较less的票数较less的不确定性。 随着选票数量的增加(成千上万),所有这些评分公式都应该趋向于(加权的)平均评分。
由于公式仅取决于项目本身的五星评级的频率分布,所以通过简单地将频率分布相加在一起可以容易地结合来自多个来源的评论(或者根据新的投票来更新整体评分)。
与IMDb公式不同,这个公式并不取决于所有项目的平均分数,也不取决于人为的最低票数截止值。
而且,这个公式利用了全频率分布 – 不仅仅是星星的平均数量和票数。 而且有意义的是,因为具有十个五星和十个一星的项目应该被视为比具有二十个三星评级的项目更不确定(因此不被评定为高)
In [78]: starsort((10,0,0,0,10)) Out[78]: 2.386028063783418 In [79]: starsort((0,0,20,0,0)) Out[79]: 2.795342687927806
IMDb公式没有考虑到这一点。
那么,取决于你想要做多less复杂的事情,你可以根据这个人做了多less评级,以及这些评级是多less来进行评分。 如果这个人只有一个等级,那么这个等级可能是一个等级,可能会less一些。 或者,如果这个人在类别a中评价了很多东西,而在类别b中评价很less,并且平均评分是5星中的1.3,那么听起来类别a可能被这个用户的低平均得分人为地压低,应该调整。
但足够复杂。 让我们简单一点。
假设我们只使用ReviewCount和AverageRating两个值,对于某个特定项目,我认为ReviewCount本质上是“可靠性”值。 但是我们不仅仅希望将ReviewCount项目的分数降低:单个一星级评分可能不如单个五星评级那么可靠。 所以我们想做的事情大概是中间的:3。
所以,基本上,我正在考虑一个像X * AverageRating + Y * 3 =等级我们想要的方程。 为了使这个值正确地出来,我们需要X + Y等于1.当ReviewCount增加时,我们也需要X的值增加…复习计数为0,x应该是0(给我们一个等式“ 3“),并且无限的评论数X应该是1(这使得等式= AverageRating)。
那么X和Y方程是什么? 对于X方程,当自variables接近无限时,要求因variables趋近于1。 一组好的方程式是这样的:Y = 1 /(因子^ RatingCount)和(利用X必须等于1-Y的事实)X = 1-(1 /
然后,我们可以调整“因素”,以适应我们正在寻找的范围。
我使用这个简单的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();
所以你不要复制它,它会给出这个输出:
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
类似的东西? 您可以根据需要调整“因素”值,以获得所需的权重。
如果你只需要一个快速和廉价的解决scheme,大部分工作,而不用大量的计算这里是一个选项(假设1-5评级)
SELECT Products.id, Products.title, avg(Ratings.score), etc FROM Products INNER JOIN Ratings ON Products.id=Ratings.product_id GROUP BY Products.id, Products.title ORDER BY (SUM(Ratings.score)+25.0)/(COUNT(Ratings.id)+20.0) DESC, COUNT(Ratings.id) DESC
通过添加25,除以总评分+20,你基本上将10个最差的分数和10个最好的分数添加到总的评分中,然后进行相应的sorting。
这确实有已知的问题。 例如,它不公平地奖励评分较低的低评分产品(如该图所示,平均分为1和仅有一个评分的产品为1.2,而平均评分为1和1k +的产品评分接近于1.05)。 你也可以争辩说,它不公平地惩罚高品质的产品,收视率很低。
此图表显示了所有5个评分超过1-1000评级后会发生什么情况: http ://www.wolframalpha.com/input/?i=Plot3D%5B%2825%2Bxy%29/%2820%2Bx%29%2C%7Bx %2C1%2C1000%7D%2C%7BY%2C0 2C6%%7D%5D
你可以看到在最低收视率上涨,但总体来说这是一个公平的排名,我想。 你也可以这样看:
http://www.wolframalpha.com/input/?i=Plot3D%5B6-%28%2825%2Bxy%29/%2820%2Bx%29%29%2C%7Bx%2C1%2C1000%7D%2C%7By %2C0%2C6%7D 5D%
如果您在此图表中的大部分地方放置了大理石,它将自动转向具有更高评分和更高评分的产品。
显然,评级数量较低,使得这个问题处于统计上的障碍。 绝不less于…
提高综合评分质量的一个关键要素是评分者评分,即保持每个特定“评价者”提供的评分(相对于其他评分)。 这可以在汇总过程中权衡他们的选票。
另一个解决办法,更多的办法是向terminal用户提供对相关物品的票数(或其范围表示)。
一个选项就像微软的TrueSkill系统,其中得分是由mean - 3*stddev
,常数可以调整。
我强烈推荐Toby Segaran编写的编程集体智慧(OReilly)ISBN 978-0-596-52932-1,它讨论了如何从人群行为中提取有意义的数据。 这些例子是在Python中,但它很容易转换。