Last active
August 13, 2024 12:55
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 | |
I'd expect
fiveStarRating
to 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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't know how different the result would be. I'd expect
fiveStarRating
to be "better" and I'd usefiveStarRatingAverage
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`.