Elo for sports prediction: a baseline, not a finish line
Why Elo first
Elo is a rating system with one job: update a rating after a result. It is cheap, explainable, and strong enough to beat most naive models. If a feature heavy model cannot beat Elo, the features are not earning their complexity.
def update(rating_a, rating_b, score_a, k=20):
expected_a = 1 / (1 + 10 ** ((rating_b - rating_a) / 400))
rating_a += k * (score_a - expected_a)
rating_b += k * ((1 - score_a) - (1 - expected_a))
return rating_a, rating_b
The time split
Random splits leak the future. Use a cutoff, train on matches before it, and evaluate after it. For F1 and boxing, the cutoff is a date. For a tournament, the cutoff is the start of the tournament.
The metric
Accuracy is not enough. Report log loss and a Brier score. A model that says 0.9 and is right 60 percent of the time is worse than a model that says 0.6.
The failure
A feature that includes the result of the current match, or a rating updated after the match, is leakage. The fix is a feature availability timestamp. If the timestamp is after the event start, the feature is out.
Lesson
Elo is the baseline. The model has to beat it on a time split, with calibration, and on a sample large enough to matter.