<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<link rel="self" href="/Atom/" />
	<id>http://billmill.org/</id>
	<title>My Name Rhymes</title>
	<subtitle>Bill Mill blogs irregularly</subtitle>
	<updated>2005-06-24T21:41:00Z</updated>
	<author>
		<name>Bill Mill</name>
		<email>bill.mill@gmail.com</email>
		<uri>http://billmill.org/</uri>
	</author>
	<link href="http://billmill.org/" />
	<entry>
		<title>Rating My Summer League With Python</title>
		<link href="http://billmill.org/elo_ratings.html" />	
		<id>http://billmill.org/elo_ratings.html</id>
		<updated>2005-06-24T21:41:00Z</updated>
		<summary type="html">I play &lt;a href="http://www.ultimatehandbook.com/uh"&gt;Ultimate&lt;/a&gt; (sometimes
incorrectly called &lt;a href="http://whatisultimate.com"&gt;ultimate frisbee&lt;/a&gt;), 
which is one of the
reasons I've been very light on blogging this summer. As well as playing for my
club &lt;a href="http://www2.upa.org/scores/scores.cgi?div=127&amp;page=3&amp;team=3448"&gt;team&lt;/a&gt;,
I play in the Connecticut &lt;a href="http://ctultimate.com"&gt;summer league&lt;/a&gt;.&lt;p&gt;
This is fun, but as a stats nerd, I have to do something beyond just play. As
such, last summer I began 
&lt;a href="http://llimllib.f2o.org/elo/elo.html"&gt;ranking&lt;/a&gt; the teams in my
league. I started out intending to use an 
&lt;a href="http://collegerpi.com/rpifaq.html#Formula"&gt;RPI&lt;/a&gt;-style formula, but
it seemed from my reading that there were better algorithms out there. In
particular, I liked 
&lt;a href="http://www.usatoday.com/sports/sagarin/bkt0405.htm"&gt;Sagarin's&lt;/a&gt; ELO
rankings, which do not take into account margin of victory. Fortunately, I
found the &lt;a href="http://www.masseyratings.com/theory/sauceda.htm"&gt;Sauceda&lt;/a&gt;
ratings, which do, since I think they are significant in my summer league.&lt;p&gt;
After a little tinkering with the constants, I came up with a python
&lt;a href="http://billmill.org/static/files/elo.py"&gt;module&lt;/a&gt; to perform the Sauceda
calculations, and another 
&lt;a href="http://billmill.org/static/files/webpage.py"&gt;one&lt;/a&gt; to print out a 
web page for me. The webpage module is likely to be of little use to anyone,
except to serve as an example of how to use the elo module. You can see the
output &lt;a href="http://llimllib.f2o.org/elo/elo.html"&gt;here&lt;/a&gt; if you didn't
click on the link already.&lt;p&gt;
&lt;h2&gt;The Sauceda Rating System&lt;/h2&gt;&lt;p&gt;
The basic idea of the Sauceda rating is that when two teams play a game, they
contest one "game point". This is then combined with a team's "winning
expectancy", which is a function of the difference in the two teams' ratings,
to update each team's rating.&lt;p&gt;
The "game point" division is done via the following formula, where pd is the
game's point differential (i.e. 4 if a team wins 9-5) and pdv is the relative
value of the point differential:&lt;p&gt;
&lt;code&gt;gp = 1 - .4 ** (1 + (pd / pdv))&lt;/code&gt;&lt;p&gt;
Unless a game is tied, in which case each team gets .5, I use this formula to
determine the winner's game point percentage, and the remainder goes to the
loser. Pdv is a parameter which should be tweaked to provide the
best results for the sport under consideration; I use 4.5 for Ultimate (games
go to 9 or 13 in summer league), while the
author of the ranking system uses 11 for basketball.&lt;p&gt;
Next up, we calculate each team's winning expectancy, where Ra is the current
team's rating, and Rb is their opponent's rating:&lt;p&gt;
&lt;code&gt;we = 1 / (1 + 10 ** ((Rb - Ra) / 400)&lt;/code&gt;&lt;p&gt;
Finally, once we know a team's win expectancy (we) and share of the game point
(gp), we can update their ranking, where R0 is their current ranking:&lt;p&gt;
&lt;code&gt;R_new = R0 + K * (gp - we)&lt;/code&gt;&lt;p&gt;
K is another parameter to tweak; I use 60, currently. I've tweaked all the
parameters based on last year's Connecticut ultimate season, so they work for
me, but you'll probably have to find values that work for whatever particular
sport or game you'll be ranking.&lt;p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
I just wanted to share the algorithm I've been using to rank teams in my summer
league, since I think it's pretty neat. There's a lot more interesting stuff
about rating algorithms to talk about, but I think I've rambled long enough for
now. If you haven't yet, you can go see
&lt;a href="http://llimllib.f2o.org/elo/elo.html"&gt;the ratings&lt;/a&gt; for my summer
league to get an idea of what, practically, this algorithm does. (You can also
see the neat diagrams I used matplotlib to generate).&lt;p&gt;
Thanks go to Eduardo Sauceda and Ken
Massey for publishing the algorithm, which I've used with only tweaks to the
parameters.
</summary>
		<content type="html">I play &lt;a href="http://www.ultimatehandbook.com/uh"&gt;Ultimate&lt;/a&gt; (sometimes
incorrectly called &lt;a href="http://whatisultimate.com"&gt;ultimate frisbee&lt;/a&gt;), 
which is one of the
reasons I've been very light on blogging this summer. As well as playing for my
club &lt;a href="http://www2.upa.org/scores/scores.cgi?div=127&amp;page=3&amp;team=3448"&gt;team&lt;/a&gt;,
I play in the Connecticut &lt;a href="http://ctultimate.com"&gt;summer league&lt;/a&gt;.&lt;p&gt;
This is fun, but as a stats nerd, I have to do something beyond just play. As
such, last summer I began 
&lt;a href="http://llimllib.f2o.org/elo/elo.html"&gt;ranking&lt;/a&gt; the teams in my
league. I started out intending to use an 
&lt;a href="http://collegerpi.com/rpifaq.html#Formula"&gt;RPI&lt;/a&gt;-style formula, but
it seemed from my reading that there were better algorithms out there. In
particular, I liked 
&lt;a href="http://www.usatoday.com/sports/sagarin/bkt0405.htm"&gt;Sagarin's&lt;/a&gt; ELO
rankings, which do not take into account margin of victory. Fortunately, I
found the &lt;a href="http://www.masseyratings.com/theory/sauceda.htm"&gt;Sauceda&lt;/a&gt;
ratings, which do, since I think they are significant in my summer league.&lt;p&gt;
After a little tinkering with the constants, I came up with a python
&lt;a href="http://billmill.org/static/files/elo.py"&gt;module&lt;/a&gt; to perform the Sauceda
calculations, and another 
&lt;a href="http://billmill.org/static/files/webpage.py"&gt;one&lt;/a&gt; to print out a 
web page for me. The webpage module is likely to be of little use to anyone,
except to serve as an example of how to use the elo module. You can see the
output &lt;a href="http://llimllib.f2o.org/elo/elo.html"&gt;here&lt;/a&gt; if you didn't
click on the link already.&lt;p&gt;
&lt;h2&gt;The Sauceda Rating System&lt;/h2&gt;&lt;p&gt;
The basic idea of the Sauceda rating is that when two teams play a game, they
contest one "game point". This is then combined with a team's "winning
expectancy", which is a function of the difference in the two teams' ratings,
to update each team's rating.&lt;p&gt;
The "game point" division is done via the following formula, where pd is the
game's point differential (i.e. 4 if a team wins 9-5) and pdv is the relative
value of the point differential:&lt;p&gt;
&lt;code&gt;gp = 1 - .4 ** (1 + (pd / pdv))&lt;/code&gt;&lt;p&gt;
Unless a game is tied, in which case each team gets .5, I use this formula to
determine the winner's game point percentage, and the remainder goes to the
loser. Pdv is a parameter which should be tweaked to provide the
best results for the sport under consideration; I use 4.5 for Ultimate (games
go to 9 or 13 in summer league), while the
author of the ranking system uses 11 for basketball.&lt;p&gt;
Next up, we calculate each team's winning expectancy, where Ra is the current
team's rating, and Rb is their opponent's rating:&lt;p&gt;
&lt;code&gt;we = 1 / (1 + 10 ** ((Rb - Ra) / 400)&lt;/code&gt;&lt;p&gt;
Finally, once we know a team's win expectancy (we) and share of the game point
(gp), we can update their ranking, where R0 is their current ranking:&lt;p&gt;
&lt;code&gt;R_new = R0 + K * (gp - we)&lt;/code&gt;&lt;p&gt;
K is another parameter to tweak; I use 60, currently. I've tweaked all the
parameters based on last year's Connecticut ultimate season, so they work for
me, but you'll probably have to find values that work for whatever particular
sport or game you'll be ranking.&lt;p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
I just wanted to share the algorithm I've been using to rank teams in my summer
league, since I think it's pretty neat. There's a lot more interesting stuff
about rating algorithms to talk about, but I think I've rambled long enough for
now. If you haven't yet, you can go see
&lt;a href="http://llimllib.f2o.org/elo/elo.html"&gt;the ratings&lt;/a&gt; for my summer
league to get an idea of what, practically, this algorithm does. (You can also
see the neat diagrams I used matplotlib to generate).&lt;p&gt;
Thanks go to Eduardo Sauceda and Ken
Massey for publishing the algorithm, which I've used with only tweaks to the
parameters.
</content>
	</entry>
</feed>
