Pre-tournament title odds, all 48 teams
The model's chance that each team reaches each round, from 50,000 simulations of the real 2026 bracket before a ball was kicked. Rank by a round, filter by group, search a team, and open a row for its full ladder. Outcomes are hidden until you ask.
How the ranking held up
Comparing the pre-tournament forecast with the real bracket. Computed from the table above and the 104 saved results.
Title favourites and where they finished
Biggest surprises
Actual stage reached minus the model's expected stage, in rounds survived (expected = the sum of its reach-round probabilities).
Were the probabilities calibrated?
All 48 teams times 6 milestones (reach R32, R16, QF, SF, final, win) give 288 predictions. Grouped by predicted probability, here is how often they came true. Dots on the diagonal mean calibrated. The milestones for one team are nested, so this is not 288 independent tests, and it is a single tournament.
All 104 matches, forecast against result
Each row shows the model's win, draw and loss probabilities for the first-named team (green), the draw (grey) and the second-named team (red), then the result. These are 90-minute probabilities from the model fit before the tournament, scored after the fact; the repo does not include a timestamped prediction log. For knockouts the "advancer" column is the team the model had advancing.
The backtest against bookmakers
Ranked probability score (RPS, lower is better) rewards putting probability near the true result. The model was tested walk-forward, training only on matches before each tournament, over 1,070 matches from 26 major finals (2014 to 2025). Bookmaker closing odds, with the margin removed, exist in the repo only for the 192 World Cup matches of 2014, 2018 and 2022, so that is the head-to-head sample.
Per World Cup, model vs bookmaker
De-vigged bookmakerModel (ensemble)
How the arms compare
Match by match: model vs market
Each dot is one World Cup match from the 192. Horizontal: the bookmaker's chance of a home (first-named) win. Vertical: the model's. Dots on the diagonal mean they agreed. Colour shows what happened after 90 minutes.
Select a dot or a row for detail.
All 26 editions, RPS by arm
From the repo's saved comparison. Spread across editions is large (0.13 to 0.22), which is why only pooled and paired figures should be quoted.
The live update loop
During the tournament the model nudged each team's rating from its results, using the scoreline rather than who advanced (a penalty-shootout win moves the rating down). The question is whether that helped. On the 104 scored matches it made no detectable difference.
Verdict from the saved evaluation
Rating change, before to after
How it works, and what to be careful with
The model in four lines
Every team gets one World Football Elo rating from about 49,000 international matches. The rating gap sets expected goals; a Poisson model with the Dixon-Coles low-score correction gives every scoreline. A LightGBM goals model is blended 50/50 with it. The 2026 bracket (48 teams, round of 32, extra time, penalties) is then simulated 50,000 times. Most of the repo's effort went into the evaluation harness: ideas such as squad market values, momentum, and an expected-goals signal were tested and rejected as nulls.
- The title table was re-run for this page. The repo saved only the top 12 (chart: Spain 21.4%). A fresh run of the same code (50,000 simulations, seed 20260611) gives Spain 20.9%, so expect differences of a few tenths of a point. Both put the same four teams on top. The README's "Spain ~32%" does not match any saved output and is not used.
- README figures are from an earlier run. The README quotes a production pooled RPS of 0.1842 and 0.2046 against 0.2001 for the market. The newer saved outputs, used here, say 0.1835 and 0.2065 against 0.2004.
- Retrospective scoring. The 104 match forecasts were produced by the pre-tournament model and scored afterwards. There is no timestamped log of them in the repo.
- The model trails the market and the gap is not statistically settled. It is 0.0061 RPS behind on 192 matches with a 95% interval of -0.004 to +0.016, which includes zero. It is not a betting tool, and it does not claim to be.
- Small samples. One tournament, 104 matches, 48 teams. Per-team and per-match differences are noisy.