I need to calculate 5-star ratings like the one on Amazon website. I have done enough search to find what is the best algorithm, but I am not able to get a proper answer. For example, if these are the ratings
5 star - 252
4 star - 124
3 star - 40
2 star - 29
1 star - 33
totally 478 reviews
Amazon has calculated this to be "4.1 out of 5 stars". Can anyone tell me how this figure is arrived at? I am not able to get this just by doing average.
That's a weighted average, where you weigh each rating with the number of votes it got:
(5*252 + 4*124 + 3*40 + 2*29 + 1*33) / (252+124+40+29+33) = 4.11 and change
If you are start calculation of overall rating from beginning then this formula will help you.
Formula
((Overall Rating * Total Rating) + new Rating) / (Total Rating + 1)
Example
suppose you have no ratings till now then formula is like, overall rating is "0" till now. total rating "0" and given rating is "4"
((0*0)+4)/1 = 4
If overall rating is "4.11" Total rating is "478" And new rating giving by one user is "2"
then formula is like
((4.11 * 478)+ 2)/479 // 479 is increment of new rating from 478
There is a really great write up on this topic at evanmiller.org. He goes through and discusses the pros and cons of a few approaches and suggests a mathematically reliable way of weighting and calculating votes.
Yes, you can average them out:
(5 * 252 + 4 * 124 + 3 * 40 + 2 * 29 + 1 * 33) / 478 = 4.11
Super helpful reply by Blindy, here's the PHP code that's based on it. Some may find useful. The results will be 4.11 as per OP's example:
$ratings = array(
5 => 252,
4 => 124,
3 => 40,
2 => 29,
1 => 33
);
function calcAverageRating($ratings) {
$totalWeight = 0;
$totalReviews = 0;
foreach ($ratings as $weight => $numberofReviews) {
$WeightMultipliedByNumber = $weight * $numberofReviews;
$totalWeight += $WeightMultipliedByNumber;
$totalReviews += $numberofReviews;
}
//divide the total weight by total number of reviews
$averageRating = $totalWeight / $totalReviews;
return $averageRating;
}
How to build the above $ratings array
Example pseudo code, but which should work that explains how to build the $ratings array when info is stored in DB assuming you have a table called "ratings" and a column called "rating". In this case it's 1 join, you would need to do 4 joins to get all ratings, but this should get you started:
SELECT count(c1.rating) as one_star, count(c2.rating) as two_star
FROM ratings c1
LEFT OUTER JOIN
ratings c2
ON
c1.id = c2.id
WHERE
c1.rating = 1
AND
c2.rating = 2
another approach suggested in comments
SELECT SUM(rating = 1) AS one_s ,SUM(rating = 2) AS two_s ,SUM(rating = 3) as three_s FROM reviews where product_id = 9
This rating system is based on a weighted average or weighted mean. That is, they used the weight in terms of stars to compute a decimal value which rounds to 4.1. For example:
Sum of (weight * number of reviews at that weight) / total number of reviews
(5*252 + 4*124 + 3*40 + 2*29 + 1*33) / 478 = 4.1
Weighted average, sum the number of stars times its weight, and then divide it through by the total number of reviews.
You may want to check this algorithm out: Calculating Average Rating the Right Way using PHP and MySQL - there's no need of saving each "star" (aka rating grade) and its corresponding number of votes and then having to retrieve thousands of rows from the database every time you need to calculate their average. (unless you want to display exactly how many people rated the given item with 1, 2, 3, 4 & 5 stars)
a better way to do this,
rating = (sum_of_rating * 5)/sum_of_max_rating_of_user_count
example:
total users rated: 6
sum_of_max_rating_of_user_count: 6 x 5 = 30
sum_of_rating: 25
rating = (25 * 5) / 30
Done!
in Javascript
calcAverageRating(ratings) {
let totalWeight = 0;
let totalReviews = 0;
ratings.forEach((rating) => {
const weightMultipliedByNumber = rating.weight * rating.count;
totalWeight += weightMultipliedByNumber;
totalReviews += rating.count;
});
const averageRating = totalWeight / totalReviews;
return averageRating.toFixed(2);
}
const ratings = [
{
weight: 5,
count: 252
},
{
weight: 4,
count: 124
},
{
weight: 3,
count: 40
},
{
weight: 2,
count: 29
},
{
weight: 1,
count: 33
}
];
console.log(calcAverageRating(ratings));
(Total nunber of star / total number of persons who review * 5 ) * 5
= Answer
Fixed decimals in js to 1.
answer.toFixed(1);
Example the total reviews of 5 person is 20 star.
(20/5*5)*5 = 4.0
来源:https://stackoverflow.com/questions/10196579/algorithm-used-to-calculate-5-star-ratings