Skip to content

Instantly share code, notes, and snippets.

@lyoshenka
Created January 24, 2014 21:18
Show Gist options
  • Save lyoshenka/8606689 to your computer and use it in GitHub Desktop.
Save lyoshenka/8606689 to your computer and use it in GitHub Desktop.
<?php
$options = [
'max_delta' => 0.01, // if percent change in scores falls below this, assume the scores are stable
'max_victory_ratio' => 1.5, // cap the margin of victory of an individual game at this ratio
];
protected static function computeRRIInternal($games, $teamsByTeamProxy, $options)
{
$delta = 1; // percent change in scores since last round
$round = 0;
$powerRating = array_fill_keys(array_unique($teamsByTeamProxy), 100); // every team starts at 100
$teamHasGames = array_fill_keys(array_unique($teamsByTeamProxy), false);
while ($delta > $options['max_delta'] && $round < 100)
{
$delta = 0;
$round++;
$updatePowerRating = $powerRating;
foreach($games as $game)
{
if ($game['home_score'] === null || $game['away_score'] === null)
{
continue;
}
$homeTeamId = $teamsByTeamProxy[$game['home_team_proxy_id']];
$awayTeamId = $teamsByTeamProxy[$game['away_team_proxy_id']];
$teamHasGames[$homeTeamId] = true;
$teamHasGames[$awayTeamId] = true;
$predictedHomeRatio = $powerRating[$homeTeamId] / $powerRating[$awayTeamId];
$actualHomeRatio = $game['home_score'] / ($game['away_score'] ?: 1);
if (isset($options['max_victory_ratio']))
{
$maxRatio = $options['max_victory_ratio'];
$minRatio = 1/$maxRatio;
$actualHomeRatio = min(max($minRatio, $actualHomeRatio), $maxRatio);
}
$homeDelta = 10 * (log($actualHomeRatio) - log($predictedHomeRatio)); // coefficient should be ~ 10% of the starting PR. this opinion is based on experimentation.
$updatePowerRating[$homeTeamId] += $homeDelta;
$updatePowerRating[$awayTeamId] -= $homeDelta;
}
foreach($powerRating as $teamId => $oldRating)
{
$delta += abs($oldRating - $updatePowerRating[$teamId]) / ($oldRating ?: 1);
}
$powerRating = $updatePowerRating;
}
foreach($teamHasGames as $teamId => $hasGames)
{
if (!$hasGames)
{
$powerRating[$teamId] = 0;
}
}
arsort($powerRating);
return $powerRating;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment