How the model does

Walk-forward validation on 2024-25 — measured, not asserted.

structured-0.1
2026-09-29

Our projection ranks players better than FPL's own.

Across 30 gameweeks of 2024-25, on the players who actually featured, ours correlates +0.075higher with realised points than FPL's figure as it stood before each deadline — and misses by less on average too.

We are not going to oversell that. A rank correlation of 0.37 means single gameweeks stay mostly unpredictable, for us and for everyone. It is an edge, not a crystal ball, and it sits alongside the reason this site exists: every number here opens up and reads term by term, and feeds tooling FPL gives you nothing like.

What we are comparing against, and why this page changed its mind twice

The public dataset's xPcolumn is FPL's own projection, but it is scraped aftereach gameweek finishes. FPL's number tracks its formfigure almost exactly, and form absorbs a gameweek's points the moment it ends — so the scraped value has already seen the result it is being asked to predict. Upstream documents this and recommends shifting the column by one gameweek or dropping it entirely.

Scored against it unshifted, FPL “beats” a hindsight oracle that knows a player's true season scoring rate and the minutes they actually played. That is the tell. Shifted to what a manager could actually see before the deadline, it scores 0.299, and this page uses that. The comparison rests on 29 gameweeks and 8,667 player-gameweeks.

Two corrections in one day, both published. This page first claimed we had the lower error — wrong, an artefact of averaging our score over every gameweek and FPL's over only the few where their column was populated. It then claimed FPL beat us outright — also wrong, from benchmarking against the contaminated column. Both are fixed. A page that quietly restates its numbers is worth nothing, so the history stays.

The caveat that runs against us: shifting takes FPL's snapshot from just after the previous gameweek, so it misses up to a week of team news before the next deadline. That handicaps them by an unknown amount. The caveat that runs for us: our live model reduces a projection when a player is flagged injured or doubtful, and the historical data carries no such column, so this test runs ours with that switched off. Neither is quantified. Both should be.

Players who featured

The honest test: everyone who got minutes, so the score isn't inflated by correctly guessing that a benched player scores nothing · 8,964 player-gameweeks

Ranking · per-GW Spearman
0.374ours0.299FPL's own
How well the projection ORDERS players against what they actually scored, averaged over gameweeks. Picking a squad is a ranking problem, so this is the metric that matters most.
Error · mean absolute
2.013 ptsours2.244 ptsFPL's own
How far off each individual projection is, on average. Lower is better — ours is closer in 29/29 gameweeks.

All players

Everyone in the pool, including non-starters — flattered on both sides by the easy did-they-play signal · 21,886 player-gameweeks

Ranking · per-GW Spearman
0.685ours0.608FPL's own
How well the projection ORDERS players against what they actually scored, averaged over gameweeks. Picking a squad is a ranking problem, so this is the metric that matters most.
Error · mean absolute
1.107 ptsours1.190 ptsFPL's own
How far off each individual projection is, on average. Lower is better — ours is closer in 28/29 gameweeks.

Error by position

Mean absolute error among players who featured. Forwards are hardest — their points come almost entirely from goals, which are rare and lumpy.

2.46GK
2.05DEF
1.85MID
2.35FWD

What we tried

Every change measured as a before/after on the same harness. The nulls are kept deliberately — a list containing only successes tells you nothing about the process that produced it.

What the model does not know

Absences, stated plainly. Anything on this list is something the site will not pretend to have an opinion about.

Price changes
There is no price-change forecast here. The site shows what prices HAVE done, never what they will do.
True effective ownership
Ownership is `selected_by_percent` — how many managers own a player, not how many captain them. Every differential and captain figure inherits that approximation.
Chip timing
Wildcard, Bench Boost, Triple Captain and Free Hit are not simulated.
Multi-gameweek planning
The optimiser maximises a single gameweek. It will not tell you to take a worse week now for a better run later.
Bench order and auto-subs
The bench is ranked but auto-substitution is not simulated, so a projection assumes your XI plays.
Promoted and low-data clubs
Clubs without enough history get a prior instead of estimated attacking shares, and are excluded from rankings rather than shown with a made-up number.
Team news beyond the official flag
Availability comes from FPL's own status field. A press-conference hint that hasn't reached the API has not reached this model either.
Where a team attacks
Shot-location and defensive-duel data would need Opta-grade inputs. The Understat approximation is built but its fetch adapters are currently broken upstream.

Method

engine
Dixon-Coles, fitted from scratch by maximum likelihood with time decay — not a library import. It emits a full scoreline probability matrix per fixture; every downstream number (clean sheet, BTTS, FDR) is a sum over that matrix.
xp
Expected points is a structured expected-value calculation, not a learned regressor: each scoring category is modelled separately and the terms sum to the total. That is why every projection on the site can be opened up and read term by term.
validation
Walk-forward on a completed season. For gameweek N the model sees only gameweeks before N — rolling rates and a match engine refit on earlier fixtures — then is scored against what actually happened. A leakage test guards the boundary.
metric
Per-gameweek Spearman rank correlation against realised points, averaged over gameweeks. Rank correlation rather than error, because picking a squad is a ranking problem: what matters is the ORDER, not the absolute points.
baseline
FPL's own published expected points for the gameweek, taken from the `xP` column of the community dataset and scored on exactly the same players in exactly the same gameweeks as ours. IMPORTANT: that column is not populated for every gameweek — a gameweek only counts here when BOTH projections exist for it, and `baseline_gws` says how many did. A thin baseline is reported as thin rather than averaged around.

Generated 2026-09-29 from 21,886 player-gameweeks across 30 gameweeks of 2024-25. Rebuild it with scripts/build_model_card.py. If this date is old, so is every number above — that is the point of printing it. See the projections themselves →