Forked from mbadolato/WilsonConfidenceIntervalCalculator.php
Last active
August 29, 2015 14:10
-
-
Save aligundogdu/67f37e463ce09809a560 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
/* | |
* (c) Mark Badolato <[email protected]> | |
* | |
* This content is released under the {@link http://www.opensource.org/licenses/MIT MIT License.} | |
*/ | |
namespace Bado\ScoreCalculator; | |
/** | |
* Calculate a score based on a Wilson Confidence Interval | |
* | |
* Based on concepts discussed at @link http://www.evanmiller.org/how-not-to-sort-by-average-rating.html | |
*/ | |
class WilsonConfidenceIntervalCalculator | |
{ | |
/** | |
* Computed value for confidence (z) | |
* | |
* These values were computed using Ruby's Statistics2.pnormaldist function | |
* 1.959964 = 95.0% confidence | |
* 2.241403 = 97.5% confidence | |
*/ | |
const CONFIDENCE = 2.241403; | |
public function getScore($positiveVotes, $totalVotes) | |
{ | |
return $totalVotes ? $this->lowerBound($positiveVotes, $totalVotes) : 0; | |
} | |
private function lowerBound($positiveVotes, $totalVotes) | |
{ | |
$phat = 1.0 * $positiveVotes / $totalVotes; | |
$numerator = $this->calculationNumerator($totalVotes, self::CONFIDENCE, $phat); | |
$denominator = $this->calculationDenominator($totalVotes, self::CONFIDENCE); | |
return $numerator / $denominator; | |
} | |
private function calculationDenominator($total, $z) | |
{ | |
return 1 + $z * $z / $total; | |
} | |
private function calculationNumerator($total, $z, $phat) | |
{ | |
return $phat + $z * $z / (2 * $total) - $z * sqrt(($phat * (1 - $phat) + $z * $z / (4 * $total)) / $total); | |
} | |
} |
This file contains hidden or 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 | |
/* | |
* (c) Mark Badolato <[email protected]> | |
* | |
* This content is released under the {@link http://www.opensource.org/licenses/MIT MIT License.} | |
*/ | |
namespace Bado\Tests\ScoreCalculator; | |
use Bado\ScoreCalculator\WilsonConfidenceIntervalCalculator; | |
class WilsonConfidenceIntervalCalculatorTest extends \PHPUnit_Framework_TestCase | |
{ | |
/** @var WilsonConfidenceIntervalCalculator */ | |
private $calculator; | |
/** @test */ | |
public function calculateFiftyTwoPositiveOutOfSeventySixTotal() | |
{ | |
$this->floatAssertion(0.556480, $this->getScore(52, 76)); | |
} | |
/** @test */ | |
public function calculateNoPositiveOutOfTenTotal() | |
{ | |
$this->floatAssertion(0, $this->getScore(0, 10)); | |
} | |
/** @test */ | |
public function calculateNoVotes() | |
{ | |
$this->floatAssertion(0, $this->getScore(0, 0)); | |
} | |
/** @test */ | |
public function calculateOneOutOfTwo() | |
{ | |
$this->floatAssertion(0.077136, $this->getScore(1, 2)); | |
} | |
/** @test */ | |
public function calculateTenPositiveOutOfTenTotal() | |
{ | |
$this->floatAssertion(0.665607, $this->getScore(10, 10)); | |
} | |
/** @test */ | |
public function calculateTenPositiveOutOfTwentyTotal() | |
{ | |
$this->floatAssertion(0.275967, $this->getScore(10, 20)); | |
} | |
protected function setUp() | |
{ | |
$this->calculator = new WilsonConfidenceIntervalCalculator(); | |
} | |
private function floatAssertion($expected, $result) | |
{ | |
$this->assertEquals($expected, $result, '', 0.000001); | |
} | |
private function getScore($positiveVotes, $totalVotes) | |
{ | |
return $this->calculator->getScore($positiveVotes, $totalVotes); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment