algorithm used to calculate 5 star ratings
Asked Answered
L

13

100

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.

Levitus answered 17/4, 2012 at 18:6 Comment(1)
embed.plnkr.co/5STGsgya9mq7HLrbJtrT A Verbose program to show average star calculation.Penstock
C
213

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
Chieftain answered 17/4, 2012 at 18:9 Comment(6)
How is this different from a "regular" average?Janniejanos
@Jeff, the weights are different than one, which is what most people call an "average".Chieftain
it's the same as regular averageHeckelphone
Yeah its the same as regular average. we are (adding total stars) divided by total users. It looks like weighted coz of multiplication in numerator. But if we rephrase it, we would essentially add all 5s, all 4s etc. since 5s are 252 times, it ends up being 5*252 and so on.Biotic
(5*1 + 4*1 + 3*1 + 2*1 + 1*1) / (1+1+1+1+1) = 3 but we expect 2.5, aren't?Dissimilar
@Natan, it would be 2.5 if the rating scale was from 0-5 instead of 1-5. For 0-5: (5*1 + 4*1 + 3*1 + 2*1 + 1*1 + 0*1) / (1+1+1+1+1+1) = 15 / 6 = 2.5Bollard
Q
31

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
Questioning answered 17/9, 2015 at 13:33 Comment(0)
D
16

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!

Decisive answered 8/11, 2018 at 8:25 Comment(3)
What does the 5 used in sum_of_max_rating_of_user_count stand for? Is it the highest rating given by any user?Coney
Please explain....sum_of_max_rating_of_user_count: 6 x 5 = 30 ???Zither
6 is total users who rated.. 5 is max num of stars (e.g usually we use 5 star rating)Decisive
E
11

Yes, you can average them out:

(5 * 252 + 4 * 124 + 3 * 40 + 2 * 29 + 1 * 33) / 478 = 4.11
Essayist answered 17/4, 2012 at 18:8 Comment(0)
Y
9

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
Yester answered 14/7, 2016 at 15:46 Comment(3)
you've make rating array, how do i make this array using mysql. my data is save in databaseSnood
@AliRaza i've updated the answer, you'd need to do several joins or pull the data with 5 separate queriesYester
i would say you were the person who actually gave me the idea and i just work on it, this query works for me SELECT SUM(rating = 1) AS one_s ,SUM(rating = 2) AS two_s ,SUM(rating = 3) as three_s FROM reviews where product_id = 9Snood
H
4

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
Hutcherson answered 17/4, 2012 at 18:11 Comment(0)
G
3

According to your question your solution will be like this.

Sum of (Rate*TotalRatingOfThatRate)/ TotalNumberOfReviews

((5*252)+(4*124)+(3*40)+(2*29)+(1*33)) / (252+124+40+29+33)

output will be 4.1

Grunion answered 13/3, 2020 at 10:5 Comment(0)
S
2

Weighted average, sum the number of stars times its weight, and then divide it through by the total number of reviews.

Stapleton answered 17/4, 2012 at 18:11 Comment(0)
K
1

in Javascript

function 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));
Kravits answered 12/6, 2019 at 5:1 Comment(0)
S
1

In addition, I am just trying to make practical and full code for all.

My Json Object Array

var yourRatingData =[{
        review_id:1,
        customer_id:5,
        customer_name:"Faysal",
        rating:5,
        review_content:"I like this product it's cool and best in quality"
    },
    {
        review_id:2,
        customer_id:6,
        customer_name:"Adams",
        rating:4,
        review_content:"It's quality product though price a bit high"
    },
    {
        review_id:3,
        customer_id:8,
        customer_name:"Jane",
        rating:3,
        review_content:"I like but should improve quality"
    },
    {
        review_id:4,
        customer_id:9,
        customer_name:"Julia",
        rating:1,
        review_content:"It's not good"
    }];

Rating Calculation

let _5star = yourRatingData.filter(r=>r.rating==5).length;
let _4star = yourRatingData.filter(r=>r.rating==4).length;
let _3star = yourRatingData.filter(r=>r.rating==3).length;
let _2star = yourRatingData.filter(r=>r.rating==2).length;
let _1star = yourRatingData.filter(r=>r.rating==1).length;

//Sum of individual star.
let sumOfRating = parseInt( _5star + _4star + _3star + _2star + _1star );

//Total number of rating
let overallRating = parseInt( 5*_5star + 4*_4star + 3*_3star + 2*_2star +1*_1star );

//Average of all rating
let averageRating = parseFloat(overallRating/sumOfRating);

//Percentage of each star rating
let _5starPercentage = parseInt((_5star/totalRating)*100);
let _4starPercentage = parseInt((_4star/totalRating)*100);
let _3starPercentage = parseInt((_3star/totalRating)*100);
let _2starPercentage = parseInt((_2star/totalRating)*100);
let _1starPercentage = parseInt((_1star/totalRating)*100);

I think it's helpful.

Solanaceous answered 12/10, 2020 at 6:18 Comment(0)
M
1

This is an example method using flutter,

double starRating = 5.0;
  getRating() {
    // ! Check Already Accepted by others or Not -----------------------------------
    //
    int totalof5s = 0;
    int totalof4s = 0;
    int totalof3s = 0;
    int totalof2s = 0;
    int totalof1s = 0;
    //
    FirebaseFirestore.instance
        .collection('usersRating')
        .where("passengerUid", isEqualTo: "GNblJJJsjicaA2vkXJNJ6XCAiwa2")
        .snapshots()
        .forEach((querySnapshot) {
      if (querySnapshot.size > 0) {
        querySnapshot.docs.forEach((element) async {
          if (element["rating"] == 5) {
            totalof5s++;
          } else if (element["rating"] == 4) {
            totalof4s++;
          } else if (element["rating"] == 3) {
            totalof3s++;
          } else if (element["rating"] == 2) {
            totalof2s++;
          } else if (element["rating"] == 1) {
            totalof1s++;
          }
          //
          if (this.mounted) {
            setState(() {
              starRating = (5 * totalof5s +
                      4 * totalof4s +
                      3 * totalof3s +
                      2 * totalof2s +
                      1 * totalof1s) /
                  (totalof5s + totalof4s + totalof3s + totalof2s + totalof1s);
            });
          }
        });
        
      } else {
        // This is default one in any case these user doesn't have any rating document exists
        if (this.mounted) {
          setState(() {
            starRating = 5.0;
          });
        }
      }
    });
  }
Mannikin answered 24/8, 2021 at 10:30 Comment(0)
D
0

(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

Decurrent answered 4/10, 2019 at 8:7 Comment(0)
D
0

I used this way to calculate ratings and it is working perfectly

let one_star = 0;
let two_star = 0;
let three_star = 0;
let four_star = 0;
let five_star = 0;

Object.values(reviews).forEach(({ rating }) => {
  switch (rating) {
    case 1: one_star++; break;
    case 2: two_star++; break;
    case 3: three_star++; break;
    case 4: four_star++; break;
    case 5: five_star++; break;
  }
});

let sum = one_star + two_star + three_star + four_star + five_star;

let average = ((5 * five_star) + (4 * four_star) + (3 * three_star) + (2 * two_star) + (1 * one_star)) / (sum);

console.log(average);
Defy answered 17/1, 2023 at 14:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.