-
-
Save julienbourdeau/77eaca0fd1e4af3fde9fe018fdf13d7d to your computer and use it in GitHub Desktop.
| <?php | |
| /* | |
| |-------------------------------------------------------------------------- | |
| | 5 Star Rating | |
| |-------------------------------------------------------------------------- | |
| | | |
| | Lower bound of Wilson score confidence interval for a Bernoulli parameter (0.9604) | |
| | | |
| | See: | |
| | * http://www.evanmiller.org/how-not-to-sort-by-average-rating.html | |
| | * https://gist.github.com/richardkundl/2950196 | |
| | * https://onextrapixel.com/how-to-build-a-5-star-rating-system-with-wilson-interval-in-mysql/ | |
| | | |
| */ | |
| function score($positive, $negative) { | |
| return ((($positive + 1.9208) / ($positive + $negative) - 1.96 * sqrt((($positive * $negative) / ($positive + $negative)) + 0.9604) / ($positive + $negative)) / (1 + 3.8416 / ($positive + $negative))); | |
| } | |
| function fiveStarRating($one, $two, $three, $four, $five) { | |
| $positive = $two * 0.25 + $three * 0.5 + $four * 0.75 + $five; | |
| $negative = $one + $two * 0.75 + $three * 0.5 + $four * 0.25; | |
| return score($positive, $negative); | |
| } | |
| function fiveStarRatingAverage($avg, $total) | |
| { | |
| $positive = ($avg * $total - $total) / 4; | |
| $negative = $total - $positive; | |
| return score($positive, $negative); | |
| } | |
| // Examples | |
| echo fiveStarRating(10, 1, 2, 6, 90); // 0.80390178246001 | |
| echo fiveStarRating(80, 1, 2, 6, 90); // 0.46188074417216 | |
| echo fiveStarRating( 0, 1, 2, 6, 0 ); // 0.33136280289755 | |
| echo fiveStarRating(10, 1, 2, 0, 2 ); // 0.079648861762752 | |
| echo fiveStarRatingAverage(4.8000001907349, 10); // 0.65545605272928 | |
In fiveStarRating, each arguments is the number of vote for the note.
If there was 3 votes for 1 star and 4 votes for 5 stars, you would use:
fiveStarRating(3, 0, 0, 0, 4);The fiveStarRatingAverage version can be used when you don't know the distribution of votes and you only have the average rating and the number of votes.
Got it. Thanks!
How do fiveStarRating and fiveStarRatingAverage compare in terms of the quality of the sorting? Do you have any data or examples?
Do you have a reference for the fiveStarRating algo, or is it rather arbitrary?
Thanks, and thank you for sharing this snippet.
I don't know how different the result would be. I'd expect fiveStarRating to be "better" and I'd use fiveStarRatingAverage only if I lost the details and only stored avg and count but I don't really know.
My feeling is that this should only be one criteria and that it's hard to say that 0.46188074417216 is definitely better than 0.46188074417301`.
I'd expect
fiveStarRatingto be "better"
Actually I proved they're equal. Let's say that I want to implement fiveStarRatingAverage with fiveStarRating's parameters:
function fiveStarRatingAverage2($one, $two, $three, $four, $five)
{
// Doesn't compile, $avg, $total not defined
$positive = ($avg * $total - $total) / 4;
$negative = $total - $positive;
return score($positive, $negative);
}Let's complete the implementation:
function fiveStarRatingAverage2($one, $two, $three, $four, $five)
{
$total = $one + $two + $three + $four + $five;
$avg = ($one * 1 + $two * 2 + $three * 3 + $four * 4 + $five * 5) / $total;
$positive = ($avg * $total - $total) / 4;
$negative = $total - $positive;
return score($positive, $negative);
}Now let's inline $total and $avg into $positive:
function fiveStarRatingAverage2($one, $two, $three, $four, $five)
{
$total = $one + $two + $three + $four + $five;
$positive = (($one * 1 + $two * 2 + $three * 3 + $four * 4 + $five * 5) - ($one + $two + $three + $four + $five)) / 4;
$negative = $total - $positive;
return score($positive, $negative);
}And simplify:
function fiveStarRatingAverage2($one, $two, $three, $four, $five)
{
$total = $one + $two + $three + $four + $five;
$positive = $two * 0.25 + $three * 0.5 + $four * 0.75 + $five;
$negative = $total - $positive;
return score($positive, $negative);
}Voila! We got the same calculation for $positive. It's not difficult to figure out that $negative is also equal for both functions.
Hi, thanks for the PHP implementation)
Explain, please, what is the meaning of parameters in this function:
I'm trying to sort a group of objects rated from 1 to 5, each object can be rated more than once.
Also, what's the difference between
fiveStarRating()andfiveStarRatingAverage()?Thank you!