🔬 Model Lab

How the predictions work, and the receipts. Every pick this site makes is frozen in a database before kickoff and scored against the real result — the charts below are computed from that ledger, not curated after the fact.

The core idea — the most likely score is the wrong pick

The engine models both teams' goals as Poisson processes (Dixon-Coles), which produces a probability for every scoreline. But it never picks the most likely one — it picks the scoreline that maximises expected points under the game's scoring rules. Drag the sliders: in tight matches the two answers split.

Outcome: home 41% · draw 31% · away 27%
Most likely score: 11 (15.0% · EP 0.612)
Best pick: 11 (EP 0.612)
same pick here — try a tighter match
0
1
2
3
4
5
0
11
7
5
2
1
0
1
9
15
7
3
1
0
2
8
9
5
2
0
0
3
4
4
2
1
0
0
4
1
1
1
0
0
0
5
0
0
0
0
0
0
rows = home goals · cols = away goals · solid ring = best pick · dashed ring = most likely
Frozen picks scored102
Correct result63%
Points / game0.86
Exact scores12
Brier score0.166lower is better · 0.333 = guessing
Calibration — when it says 60%, is it right 60% of the time?
0%0%25%25%50%50%75%75%100%100%perfect calibrationpredicted 6% → happened 6% of the time (n=49)predicted 16% → happened 16% of the time (n=38)predicted 25% → happened 18% of the time (n=78)predicted 35% → happened 41% of the time (n=54)predicted 45% → happened 52% of the time (n=21)predicted 56% → happened 57% of the time (n=28)predicted 72% → happened 76% of the time (n=25)predicted 88% → happened 85% of the time (n=13)Predicted probabilityObserved frequency

Every win/draw/loss probability the model published, binned and compared with what actually happened. Points on the dashed line = honest probabilities. This is the chart most prediction sites won't show you.

Performance over the tournament (cumulative)
54%65%76%Jun 13 · after 4 picks: 75%Jun 14 · after 8 picks: 75%Jun 15 · after 12 picks: 75%Jun 16 · after 16 picks: 63%Jun 17 · after 20 picks: 70%Jun 18 · after 24 picks: 63%Jun 19 · after 28 picks: 57%Jun 20 · after 32 picks: 56%Jun 21 · after 36 picks: 58%Jun 22 · after 40 picks: 58%Jun 23 · after 44 picks: 59%Jun 24 · after 48 picks: 60%Jun 24 · after 52 picks: 62%Jun 25 · after 56 picks: 61%Jun 26 · after 60 picks: 58%Jun 27 · after 64 picks: 61%Jun 27 · after 68 picks: 62%Jun 28 · after 72 picks: 63%Jun 30 · after 76 picks: 62%Jul 1 · after 80 picks: 64%Jul 2 · after 84 picks: 64%Jul 4 · after 88 picks: 64%Jul 6 · after 92 picks: 64%Jul 7 · after 96 picks: 66%Jul 12 · after 100 picks: 64%Jul 15 · after 102 picks: 63%Jun 13Jun 25Jul 15Result accuracy, cumulative %
0.640.821.00Jun 13 · after 4 picks: 0.75Jun 14 · after 8 picks: 1.00Jun 15 · after 12 picks: 0.92Jun 16 · after 16 picks: 0.75Jun 17 · after 20 picks: 0.80Jun 18 · after 24 picks: 0.71Jun 19 · after 28 picks: 0.64Jun 20 · after 32 picks: 0.75Jun 21 · after 36 picks: 0.75Jun 22 · after 40 picks: 0.72Jun 23 · after 44 picks: 0.73Jun 24 · after 48 picks: 0.77Jun 24 · after 52 picks: 0.77Jun 25 · after 56 picks: 0.79Jun 26 · after 60 picks: 0.75Jun 27 · after 64 picks: 0.83Jun 27 · after 68 picks: 0.85Jun 28 · after 72 picks: 0.85Jun 30 · after 76 picks: 0.85Jul 1 · after 80 picks: 0.89Jul 2 · after 84 picks: 0.91Jul 4 · after 88 picks: 0.89Jul 6 · after 92 picks: 0.88Jul 7 · after 96 picks: 0.91Jul 12 · after 100 picks: 0.88Jul 15 · after 102 picks: 0.86Jun 13Jun 25Jul 15Points per game (3 exact / 1 result)
The pipeline
1,591 matches3 sports APIsDixon-Coles fitPython · 2×/day CITeam ratingsattack / defenceMarket calibration41 bookmakersEP-optimal pickper scoring rulesFrozen ledgergraded vs reality

Model: Dixon-Coles bivariate Poisson, maximum-likelihood fit (Python/scipy) on 1,591 international matches with time decay, 3× tournament weighting and a FIFA-ranking prior · refit twice daily by GitHub Actions · predictions calibrated to a de-vigged 41-bookmaker consensus · knockout markets convolved through extra-time + shootout models.

Honesty box