별 5 개 등급으로 정렬하는 더 좋은 방법은 무엇입니까?
5 성급 시스템을 사용하여 고객 등급별로 여러 제품을 분류하려고합니다. 이 사이트를 설정하는 사이트에는 등급이 많지 않고 계속해서 새로운 제품을 추가하므로 일반적으로 등급이 낮은 몇 가지 제품이 있습니다.
평균 별점 등급을 사용해 보았지만 등급이 적을 때 알고리즘이 실패합니다.
예를 들어 별점 5 개가 3 배인 제품은 별표 5 개가 100 배이고 별표가 2 개인 제품보다 더 잘 표시됩니다.
두 번째 제품이 더 많은 등급으로 인해 통계적으로 더 신뢰할 수 있기 때문에 더 높게 표시되어야하지 않습니까?
2015 년 이전에 인터넷 영화 데이터베이스 (IMDb)는 상위 250 개 영화 목록에 사용 된 공식을 공개적으로 나열했습니다 . 인용하려면 :
최고 평점 250 개 타이틀을 계산하는 공식은 진정한 베이지안 추정치를 제공합니다 .
weighted rating (WR) = (v ÷ (v+m)) × R + (m ÷ (v+m)) × C
어디:
- R = 영화 평균 (평균)
- v = 영화에 대한 투표 수
- m = Top 250 (현재 25000)에 등재되기 위해 필요한 최소 투표 수
- C = 전체 보고서에 대한 평균 투표 (현재 7.0)
Top 250의 경우 일반 유권자의 투표 만 고려됩니다.
이해하기 어렵지 않습니다. 공식은 다음과 같습니다.
rating = (v / (v + m)) * R +
(m / (v + m)) * C;
수학적으로 다음과 같이 단순화 할 수 있습니다.
rating = (R * v + C * m) / (v + m);
변수는 다음과 같습니다.
- R – 항목의 자체 등급입니다. R은 항목 투표의 평균입니다. (예를 들어 항목에 투표가 없으면 R은 0입니다. 누군가가 별 5 개를 주면 R은 5가됩니다. 다른 사람이 별표 1 개를 주면 R은 3이되고 평균은
[1, 5]
. 등이됩니다.) - C – 평균 항목의 등급. 현재 항목을 포함하여 데이터베이스의 모든 단일 항목의 R을 찾고 평균을 구합니다. 즉, C입니다. (데이터베이스에 4 개의 항목이 있고 해당 등급이
[2, 3, 5, 5]
. C는 해당 숫자의 평균 인 3.75입니다.) - v – 항목에 대한 투표 수. (다른 예를 들어, 5 명이 항목에 투표를했다면 v는 5입니다.)
- m – 조정 가능한 매개 변수. 등급에 적용되는 "평활화"의 양은 m과 관련된 투표 수 (v)를 기준으로합니다. 결과가 만족 스러울 때까지 m을 조정하십시오. 그리고 m에 대한 IMDb의 설명을 "상장에 필요한 최소 투표 수"로 잘못 해석하지 마십시오.이 시스템은 m보다 적은 투표로 항목의 순위를 매길 수 있습니다.
모든 공식은 평균을 계산하기 전에 각각 C 값을 가진 m 개의 가상 투표를 추가하는 것입니다. 처음에는 데이터가 충분하지 않을 때 (즉, 투표 수가 m보다 극적으로 적음) 이로 인해 공백이 평균 데이터로 채워집니다. 그러나 투표가 누적되면 결국 가상의 투표가 실제 투표에 의해 사라질 것입니다.
이 시스템에서는 투표로 인해 등급이 크게 변동되지 않습니다. 대신, 그들은 단지 어떤 방향으로 그것을 약간 교란합니다.
0 표가 있으면 가상의 표만 존재하고 모두 C입니다. 따라서 각 항목은 C 등급으로 시작됩니다.
또한보십시오:
참조 페이지 별 기반 평가 시스템의 좋은 분석을 위해, 그리고 이 일을 upvote- / downvote- 기반 시스템의 좋은 분석.
상향 및 하향 투표의 경우, "실제"점수 (무한 등급이있는 경우)가 일부 수량 (예 : 다른 항목에 대한 유사한 숫자)보다 클 확률을 추정하려고합니다. 다시 정렬).
답은 두 번째 기사를 참조하십시오. 결론은 Wilson 신뢰도를 사용하고 싶다는 것입니다. 이 기사는 방정식과 샘플 Ruby 코드 (다른 언어로 쉽게 번역됨)를 제공합니다.
Evan Miller는 베이지안 방식으로 별 5 개 등급을 매 깁니다.
어디
nk
-k
별 등급 의 수입니다 .sk
k
별 의 "가치"(포인트 단위)입니다 .N
총 투표 수입니다.K
최대 별 수입니다 (예 : 별 5 개 등급 시스템에서 K = 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))
예를 들어 항목에 별 5 개 60 개, 별 4 개 80 개, 별 3 개 75 개, 별 2 개 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)]
이것은 더 많은 등급이 전체 별 값에 미칠 수있는 영향을 보여줍니다.
이 공식은 특히 투표 수가 적을 때 (예 : 300 미만) Amazon, Ebay 또는 Wal-mart와 같은 사이트에서보고하는 전체 등급보다 약간 낮은 전체 등급을 제공하는 경향이 있음을 알 수 있습니다. 이는 투표 수가 적을수록 불확실성이 높아짐을 반영합니다. 투표 수가 수천 개로 증가함에 따라 이러한 모든 등급 공식은 (가중치) 평균 등급으로 향해야합니다.
공식은 항목 자체에 대한 별 5 개 등급의 빈도 분포에만 의존하기 때문에 빈도 분포를 함께 추가하기 만하면 여러 소스의 리뷰 를 결합 (또는 새 투표에 따라 전체 등급 업데이트) 하는 것이 쉽습니다 .
IMDb 공식과 달리이 공식은 모든 항목의 평균 점수 나 인위적인 최소 투표 수 컷오프 값에 의존하지 않습니다.
또한이 공식은 평균 별 수와 투표 수뿐만 아니라 전체 빈도 분포를 사용합니다. 10 개의 별 5 개와 1 개의 별표 10 개가있는 항목은 3 개의 별표 22 개를 가진 항목보다 불확실성이 더 높은 것으로 취급되어야하므로 (따라서 높은 등급이 아닌) 다음과 같이 처리해야합니다.
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 공식은이를 고려하지 않습니다.
산술 평균 대신 중앙값으로 정렬 할 수 있습니다. 이 경우 두 예제 모두 중앙값이 5이므로 정렬 알고리즘에서 둘 다 동일한 가중치를 갖습니다.
동일한 효과에 모드 를 사용할 수 있지만 중앙값이 더 나은 생각 일 수 있습니다.
100 개의 별 5 개 등급으로 제품에 추가 가중치를 할당하려면 일종의 가중치 모드를 사용하여 중간 값은 같지만 전체 투표 수가 더 많은 등급에 더 많은 가중치를 할당하는 것이 좋습니다.
글쎄, 당신이 그것을 얼마나 복잡하게 만들고 싶은지에 따라, 당신은 그 사람이 만든 평가의 수와 그 평가가 무엇인지에 따라 추가로 평가를 할 수 있습니다. 그 사람이 단 하나의 평가를했다면, 그것은 실점 일 수 있고 더 적게 계산 될 수 있습니다. 또는 그 사람이 카테고리 a에서는 많은 것을 평가했지만 카테고리 b에서는 거의 평가하지 않았고 평균 평점 5 점 만점에 1.3 인 경우, 카테고리 a는이 사용자의 낮은 평균 점수에 의해 인위적으로 무게가 가해질 수있는 것처럼 들립니다. 조정해야합니다.
그러나 그것을 복잡하게 만들기에 충분합니다. 간단하게합시다.
Assuming we’re working with just two values, ReviewCount and AverageRating, for a particular item, it would make sense to me to look ReviewCount as essentially being the “reliability” value. But we don’t just want to bring scores down for low ReviewCount items: a single one-star rating is probably as unreliable as a single 5 star rating. So what we want to do is probably average towards the middle: 3.
So, basically, I’m thinking of an equation something like X * AverageRating + Y * 3 = the-rating-we-want. In order to make this value come out right we need X+Y to equal 1. Also we need X to increase in value as ReviewCount increases...with a review count of 0, x should be 0 (giving us an equation of “3”), and with an infinite review count X should be 1 (which makes the equation = AverageRating).
So what are X and Y equations? For the X equation want the dependent variable to asymptotically approach 1 as the independent variable approaches infinity. A good set of equations is something like: Y = 1/(factor^RatingCount) and (utilizing the fact that X must be equal to 1-Y) X = 1 – (1/(factor^RatingCount)
Then we can adjust "factor" to fit the range that we're looking for.
I used this simple C# program to try a few factors:
// 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();
So you don’t bother copying it in, it gives this output:
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
Something like that? You could obviously adjust the "factor" value as needed to get the kind of weighting you want.
If you just need a fast and cheap solution that will mostly work without using a lot of computation here's one option (assuming a 1-5 rating scale)
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
By adding in 25 and dividing by the total ratings + 20 you're basically adding 10 worst scores and 10 best scores to the total ratings and then sorting accordingly.
This does have known issues. For example, it unfairly rewards low-scoring products with few ratings (as this graph demonstrates, products with an average score of 1 and just one rating score a 1.2 while products with an average score of 1 and 1k+ ratings score closer to 1.05). You could also argue it unfairly punishes high-quality products with few ratings.
This chart shows what happens for all 5 ratings over 1-1000 ratings: 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
You can see the dip upwards at the very bottom ratings, but overall it's a fair ranking, I think. You can also look at it this way:
If you drop a marble on most places in this graph, it will automatically roll towards products with both higher scores and higher ratings.
Obviously, the low number of ratings puts this problem at a statistical handicap. Never the less...
A key element to improving the quality of an aggregate rating is to "rate the rater", i.e. to keep tabs of the ratings each particular "rater" has supplied (relative to others). This allows weighing their votes during the aggregation process.
Another solution, more of a cope out, is to supply the end-users with a count (or a range indication thereof) of votes for the underlying item.
One option is something like Microsoft's TrueSkill system, where the score is given by mean - 3*stddev
, where the constants can be tweaked.
After look for a while, I choose the Bayesian system. If someone is using Ruby, here a gem for it:
https://github.com/wbotelhos/rating
I'd highly recommend the book Programming Collective Intelligence by Toby Segaran (OReilly) ISBN 978-0-596-52932-1 which discusses how to extract meaningful data from crowd behaviour. The examples are in Python, but its easy enough to convert.
참고URL : https://stackoverflow.com/questions/1411199/what-is-a-better-way-to-sort-by-a-5-star-rating
'IT TIP' 카테고리의 다른 글
'django_content_type이 이미 존재 함'을 어떻게 해결할 수 있습니까? (0) | 2020.11.20 |
---|---|
Angular2-앱 외부에서 구성 요소 함수를 호출하는 방법 (0) | 2020.11.20 |
64 비트 Windows에 SciPy를 어떻게 설치합니까? (0) | 2020.11.20 |
C #을 네이티브로 컴파일 하시겠습니까? (0) | 2020.11.20 |
Django를 다른 get 변수로 페이지 매김하는 방법은 무엇입니까? (0) | 2020.11.20 |