How a Prediction Is Made

One real week, end to end: 2024 Week 5, Ravens @ Bengals — the data gathered, the features built, both prediction machines run, and what actually happened.

Honesty box. Everything below is generated fresh from the real pipeline, walk-forward: the Week 5 prediction uses only 2016–2023 plus 2024 Weeks 1–4. This page runs the audited prior champion (already benchmark-scored on 2024 in the M5 market comparison) — the newer 66.6% model is deliberately withheld from 2024, which is preserved as its untouched one-shot confirmation window. The simulator trains only on seasons ≤2022. 2025–26 remain sealed. Final scores appear on this page only as after-the-fact truth for grading, never as inputs.

The two machines

Snapcount has two prediction systems with different jobs. Both ran on this game.

1 · The pregame predictor the scoreboard machine

One shot per player per week. Twenty gradient-boosted models (5 stats × 4 positions) each read ~100 features built from strictly-prior data and output one number. No play sequencing — game flow enters only through pregame context (the Vegas line, opponent trends). This machine holds every accuracy number on the Nine-Metric Scoreboard.

2 · The play-by-play simulator the reasoning machine

A state machine: it samples play 1, updates down / distance / clock / score, and lets that state shape play 2 — chaining ~124 plays into drives and a full game, then repeats the whole game 200 times. Game script emerges rather than being assumed. Measured honestly, it trails the pregame machine on accuracy (55.2% Tier A, below the naive bar) — so it powers demos, distributions and reasoning, not the scoreboard.

Machine 1 — the pregame pipeline, step by step

What actually executes when we predict Week 5. Every arrow is code in the repo; every step is walk-forward legal.

1 · Raw sources
nflverse: play-by-play, weekly stats, rosters, depth charts, injuries, NGS tracking, schedules with the Vegas lines. Pulled by ingest_raw.py.
2 · Free feature DB
freedb_player (147,457 player-weeks), freedb_team, freedb_game — every column already screened by the anti-leakage gate.
3 · The lag builder
For Week 5, every history column is computed through Week 4 and no further — last-week values, trailing means, share trends. The week being predicted contributes nothing to its own features.
4 · Seven feature families
Role shares · this-week structure · opportunity quality · efficiency/skill · volume lags · player trailing means · game context (Vegas + opponent).
5 · Twenty models
One XGBoost per (stat × position) cell, trained on 2016–2023 + 2024 W1–4, predicts W5. Retrained every week as the window walks forward.
6 · Graded later
After the game, the nine-metric harness scores every projection: within 25% = Tier A hit, within 10% = Tier B.

The featured game

“Explain the lag” — how Weeks 1–4 become Week 5 features

The model never sees the week it predicts. Here are two real players: what they did in Weeks 1–4, and the exact feature values the lag builder produced for Week 5.

Two kinds of lag: last-week values (rushing_yards_lag = the Week 4 number) capture recent form; trailing means (tm_* = the player's running average over every prior game) capture the level. The model weighs both, alongside the five other families — that combination is what separates it from “just averaging”: a pure average scores 62.3% Tier A, this machine 63.9–64.3%, and a perfect average — a leave-one-out oracle handed each player's true level — tops out at 65.4% on the 2023 tune window (ceiling study, 2026-07-25).

The feature families, with real Week 5 values

Yes, game statistics are in there: the context family carries the Vegas market's pregame read (implied team total, spread, game total), the opponent's lagged defensive EPA — strictly prior weeks, never this game's — and a divisional flag. Measured honestly, this family sharpens coherence more than raw accuracy (removing it moves Tier A by ~0.0 on 2023) — the forecastable part of game flow is mostly already priced into a player's role.

Machine 1's output vs what happened — as calibrated ranges

Every starter-pool player in the game. Each row shows the model's 70% likely range (floor → ceiling) around its projection, and where the truth actually landed. The range method is the shipped serving machinery: the projection ± the player's own lagged week-to-week volatility, conformal-calibrated on the model's 2023 out-of-sample errors — never on this week. Hover any row for detail.

70% likely range Projection Actual

The same machine on a normal Sunday

70% likely range Projection Actual

Where those two games sit in the week

All-nine-metric Tier A rate for each of the fourteen Week 5 games, one dot each.

Machine 2 — the same game, played 200 times

The simulator chains state play-by-play: GameState → sample a play → advance state → next play, drive by drive, then repeats the full game 200 times with different random draws.

One simulated possession (sim #1, opening drives)

Each line is one sampled play: the model picks run/pass from the game state, samples yardage and the ball-carrier from learned shares, then the state machine advances down, distance and clock. What happens on a play depends on everything before it — this is where game script lives.

Known simulator artifacts, shown rather than hidden: incompletions display at their true 0 yards (the raw sampler draws yardage independently of the completion flag — an open bug), and carrier allocation on designed runs is still loose — you may see receivers taking handoffs more often than a real coach would call. Both are on the fix list for the play-rollout build; this page shows the machine as it actually is today.

200 final scores, one dot each

Star player ranges across 200 sims — vs the one real outcome

Simulator p10–p90 range (dot = mean) Actual scrimmage yards

Read this chart honestly: in football's wildest weeks the truth lands far outside any average — this game beat the Vegas total by 30½ points. The simulator's ranges are also systematically low (its scoring is under-calibrated and QB passing isn't modeled yet), which is exactly why it was demoted from the scoreboard after measuring 55.2% Tier A. Its value is the mechanism — sequencing, usage flow, joint outcomes — not the point estimate.

What this one game teaches

The predictable part is volume. Chase Brown projected 47.0 and ran for 46; Andrei Iosivas 38.6 → 39; Justice Hill 15.3 → 17 — all Tier A hits built from role features that persist. Derrick Henry (117.5, actual 92) came from the same machinery — 70.6% of Baltimore's carries, 80% of red-zone carries, 199 rushing yards the week before — and missed the ±25% window by 2.5 yards. Volume gets you close; it cannot make you exact.

The unpredictable part is efficiency. Ja'Marr Chase projected 69.9 and produced 193 in an overtime shootout no pregame signal called — the market itself missed this game by 30½ points. That gap is not a fixable model error; it is the ~42% of weekly variance that belongs to the sport. It is why the honest ceiling for any pregame predictor is ~70% Tier A, and why our product direction is calibrated ranges — floor / projection / ceiling — rather than a single number pretending to certainty.

Division of labor. Machine 1 owns the scoreboard. Machine 2 owns sequencing, game script and joint outcomes — and will power the play-rollout demo. See the full accuracy picture on the Nine-Metric Scoreboard.

Generated from the live repo pipeline: champion = XGBoost + game context (cand_tree_context.py), walk-forward, trained through 2024 W4 at prediction time; simulator = snapcore/models/sim/ play-step + state machine, trained ≤2022, 200 Monte Carlo reps, seed-deterministic. Starter pool = top 32 QB / 64 RB / 96 WR / 32 TE that week. Vendor projections are never inputs.