This is fun, but as a stats nerd, I have to do something beyond just play. As such, last summer I began ranking the teams in my league. I started out intending to use an RPI-style formula, but it seemed from my reading that there were better algorithms out there. In particular, I liked Sagarin's ELO rankings, which do not take into account margin of victory. Fortunately, I found the Sauceda ratings, which do, since I think they are significant in my summer league.
After a little tinkering with the constants, I came up with a python module to perform the Sauceda calculations, and another one 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 here if you didn't click on the link already.
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.
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:
gp = 1 - .4 ** (1 + (pd / pdv))
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.
Next up, we calculate each team's winning expectancy, where Ra is the current team's rating, and Rb is their opponent's rating:
we = 1 / (1 + 10 ** ((Rb - Ra) / 400)
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:
R_new = R0 + K * (gp - we)
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.
Thanks go to Eduardo Sauceda and Ken Massey for publishing the algorithm, which I've used with only tweaks to the parameters.