Matchday Fate
A fair-play football predictor — tuned XGBoost calling Home/Draw/Away across Europe's top five leagues, with the bookmaker gap disclosed instead of hidden.
What was at stake
Prediction products live or die on honesty. The market is full of tipster sites that publish picks and hide methodology — and a model that trails the bookmaker but pretends otherwise gets found out the first losing weekend. The only viable position was radical disclosure: publish the metric, name the gap, say what the model can't do.
What it needed
- Call Home/Draw/Away before kickoff for the top five European leagues, from pre-match information only
- Prove the model honestly — measured against both a naive baseline and bookmaker-implied probabilities
- Serve live predictions through an API and a web app: fixtures, single-match calls, and a title-race simulator
- Guarantee train/serve parity so the numbers on the model page describe the model actually answering
- Keep odds data out of the features entirely, so every call is earned by form, Elo and head-to-head rather than borrowed from the market
How we delivered
- Tuned XGBoost multiclass classifier on 23 fair-play features — Elo, rolling form, head-to-head, rest days, goals, shots and corners
- FastAPI backend (fixtures, predict, evaluate, season record, Monte Carlo simulator) with a Next.js + TypeScript frontend
- A model page that publishes the full scoreboard: log-loss 0.985 vs 1.077 naive on a locked 1,752-match test, bookmaker 0.965 beside it
- Point-in-time test windows and leakage checks so no future information ever trains a past prediction
- 51-test pytest suite over parity, gates and API contracts, shipped in Docker with weekly refresh and monthly retrain ops
What changed
- Locked 2024/25 test (1,752 matches): log-loss 0.985 vs a 1.077 naive baseline — with the 0.965 bookmaker benchmark published alongside, not buried