这取决于你想把它做得有多复杂,你可以根据一个人做了多少次评分,以及这些评分是什么,来对评分进行加权。如果一个人只做了一个评级,那么这可能是一个托儿的评级,可能会少一些。或者,如果这个人在 A 类中评价了很多东西,但在 B 类中评价很少,平均评分为1.3(满分5星) ,这听起来像是 A 类可能被这个用户的低平均分人为压低了,应该进行调整。
所以,基本上,我在考虑一个方程,比如 X * AverageRating + Y * 3 = the-atings-we-want。为了使这个值正确出来,我们需要 X + Y 等于1。另外,我们需要 X 来增加值,因为 ReviewCount 增加了... 如果评论数为0,x 应该是0(给我们一个“3”的方程式) ,如果评论数为无限,X 应该是1(这使得方程式 = AverageRating)。
那么 X 和 Y 方程是什么呢?对于 X 方程,当自变量趋于无穷大时,要求因变量渐近地逼近1。一组好的方程式是这样的:
Y = 1/(因子 ^ RatingCount)
和(利用 X 必须等于1-Y 的事实)
X = 1-(1/(因子 ^ 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();
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
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))