eheinzen / elo

An R package to calculate Elo ratings
https://eheinzen.github.io/elo/
37 stars 3 forks source link

Outcome probabilities for multi-team matchups #54

Closed TheMathNinja closed 4 years ago

TheMathNinja commented 4 years ago

I'm wondering if I can use/extend this package for multi-team matchups.

Presently, I'm asking the question: "Given 32 distinct Elo ratings for the 32 teams in my fantasy football league, what is the probability Team X wins the weekly money prize for top score?" Or, in a more simple scenario...in a 3-team, one-week playoff match, what's the probability each team will win and advance (if I already have Elo for each). Is this package able to handle a problem like this?

eheinzen commented 4 years ago

Oh man, what a rabbit hole this question led me to!

In short: Elo is really only meant to model pairwise matchups. Your situation isn't that, so Elo is probably not the most appropriate.

Nevertheless, the Wikipedia page on Elo scores got me thinking about the logistic function, which is essentially how we calculate the Elo probabilities. This is also related to multinomial regression, in which the logistic function is (essentially) extrapolated, which led me to the softmax function, which basically confirmed my hunch that the way to extrapolate is something like this:

> elos <- c(Team1 = 1500, Team2 = 1400, Team3 = 1600)
> n <- 10^(elos / 400)
> n / sum(n)
    Team1     Team2     Team3 
0.2993456 0.1683344 0.5323201
TheMathNinja commented 4 years ago

Wow thank you for this! Yes it's looking like this is quite good/helpful. Any chance this means multi-team Elo functionality could be coming to this package? Looks like a pretty smooth integration! I know you said Elo is only meant for pairwise but this function seems like it does the job, right?

Also...and this might be outside the realm of this thread or your expertise (as an Elo guru) but I'm curious if, for my purposes, Elo might not be optimal, what ranking algorithm you might recommend? My basic scenario/problem is this: Every week, my 32 fantasy football teams play the same game (start the best 21 players you can and get the highest sum of scores). How can I utilize all the information available to me about how they perform that week to create a ranking system for them which maximally predicts their ranking for the coming week? And then how do I do it again next week? At present, I've been utilizing Elo whereby I assign the "All-play" win-loss record as a performance to each, i.e. the top performer is 31-0, the second is 30-1, etc. But like you said...this isn't a strict pairwise scenario (I could use head-to-head records, but this is throwing out a ton of useful information since I know how everyone would have performed against everyone). I was thinking about other problems where this same approach would be needed. Golf rankings came to mind, as each golfer players the same course, and their results are continuous and can be formed into a ranking, which could be utilized for the next round or next tournament. It seems like Sagarin takes this similar approach of using "all-play" performance of the golfers, and I know his systems are somewhat Elo-based. Anyway...I've found some success using Elo for this problem, but wonder if you know of any better ranking algorithms. I've struggled to find others.

eheinzen commented 4 years ago

The framework you describe is probably the way I would do it if you wanted to use Elo. You'd probably want to only update after all "matches" (pairwise matchups: the overall winner wins 31 "matches", the second wins 30 "matches") are completed, which the current implementation doesn't do. I don't think it'd be that hard to implement, though. I'll keep this issue open for my own motivation to implement it.

That being said, the Markov-chain- and Colley-matrix-based methods might work, since they simultaneously estimate the rankings (instead of iteratively like Elo does). More details on those methods are in the vignettes.

eheinzen commented 4 years ago

The framework you describe should now be possible with the group() function. I'll write you an example soon

eheinzen commented 4 years ago

However, the prediction I have yet to incorporate (the original question: who would win if they all were pitted against each other)

eheinzen commented 4 years ago

Go ahead and do a remotes::install_github("eheinzen/elo") and check out ?elo.run.multiteam