Backcheck
How it works · Method

The Model is the Newsroom

Backcheck writes a preview before every NHL game and a recap after every one — for all 32 teams, every night. No takes, no hot air. We lead with the computed result, separate process (, , ) from result (goals, wins) from luck (, , ), and always show the uncertainty.

See the validation study
The three layers

Every article, board and team report on this site reads the game through the same three layers — and never lets one impersonate another. A team can win the result and lose the process; the whole publication exists to say so out loud, with the numbers attached.

Process

The repeatable part of hockey — the chances a team creates and allows. Process predicts future wins better than wins do.

Every shot's scoring probability — judged on location, angle, shot type and game state — summed up.

A team's slice of all the expected goals in a game or season: xGF ÷ (xGF + xGA).

Share of all shot attempts — on goal, missed or blocked — while a team is on the ice at 5-on-5.

Shot attempts from the slot and crease — the ice where shots become goals most often.

Result

The scoreboard. It's where every story starts, and it's the least reliable thing on this page over a ten-game stretch.

Actual goals scored. The scoreboard.

Any counting stat scaled to a full 60 minutes of ice time.

Luck

The reconciliation layer. When result outruns process, one of these numbers is usually holding the bag — and it mean-reverts.

On-ice shooting % plus save % — the two bounce-driven numbers. The league averages almost exactly 1.000.

Actual goals minus expected goals — how far the results outran (or trailed) the chances.

Expected goals against minus actual goals against, for a goalie.

The model suite · trained

Five gradient-boosted models, trained on NHL play-by-play and MoneyPuck aggregates on the writer's machine. The metrics below are the honest ones — held-out performance, printed next to a naive baseline where it matters. When a model barely beats naive (game outcome does, narrowly), we say so and treat its output as a lean.

XGBoost classifier

Expected Goals (xG)

Scores every unblocked shot 0–1 on its probability of becoming a goal, from location, angle, shot type, rush/rebound state and strength. The spine of every recap.

0.758
AUC
0.225
Log loss
0.061
Brier
195,598
Shots trained
XGBoost classifier

Game Outcome

Pre-game win probability from each team's rolling goal, xG, Corsi, form and points-percentage profiles. Beats a naive baseline on Brier score.

58.9%
Accuracy
0.608
AUC
0.245
Brier
0.249
Naive Brier
XGBoost regressor

Goalie Performance

Projects a starter's save percentage above expected (GSAx) given workload, shot quality faced, rest and recent form.

0.032
MAE
0.212
0.037
Naive MAE
XGBoost classifier

Player Impact

Estimates whether a skater drove play in a game from shot share, xG, finishing-vs-expected and danger-rate inputs.

58.2%
Accuracy
0.622
AUC
0.238
Brier
XGBoost regressor

Development Curve

Models a young skater's production trajectory from usage, shot generation and finishing-luck signals — the highest-fit model in the suite.

0.826
0.037
MAE
0.109
Naive MAE
The proxy layer · estimated

Some numbers on this site stand in for data that doesn't publicly exist. We build them anyway — carefully — and label every single one model-est. where it appears. A proxy is useful for ordering (who is more valuable, which need is bigger) and unreliable for exact magnitudes. The full set:

Our all-in player value estimate, built from 5-on-5 on-ice impact. A proxy — not official RAPM-style WAR.

A skater's on-ice impact after adjusting for role, minutes and teammates — the input under the WAR proxy.

Six percentile dials per skater, versus the same position: offense, creation, defense, finishing, danger, two-way.

A blend of a U-23 skater's current impact, year-over-year xG growth, and the development model's projection.

Impact percentile minus market visibility: how far a player's on-ice value outruns his profile.

A 0–100 estimate of how visible a player is to the market: counting stats, minutes, team spotlight.

The value board's headline number: the size of the impact-vs-visibility gap, weighted by contract phase.

An estimate of contract stage from age and experience — ELC, bridge, prime, veteran. Not real contract data.

How much better a unit's observed xG share is than the sum of its members' individual baselines.

What a unit "should" produce: the additive xG-share baseline from its members' individual profiles.

A 0–1 similarity between how a candidate plays and how the acquiring club creates its offense.

A 0–1 guess at how gettable a player looks, from the selling club's points pace. Not real availability.

The trade board's blend: on-ice value × positional need × style fit × acquirability.

Fit score crossed with market-gap value: the candidates who plug the hole AND look like bargains.

A flagged assignment where an attacker's xGF/60 outruns the best available checker's xGA/60.

What we don't know

Credibility is mostly a list of things you refuse to pretend. Ours:

  • No salary or contract data.

    Nothing here reads a cap sheet. “Contract phase” is inferred from age and experience; “market visibility” stands in for price. When we say a player is a bargain, we mean the market's attention — not his AAV.

  • WAR* is a proxy, not RAPM.

    Public WAR models isolate a player with regression on stint-level data. Ours is built from on-ice impact rates, which share credit with linemates. It ranks players well; it does not measure wins to the decimal.

  • On-ice stats flatter good teammates.

    Every on-ice number partially describes the line, not the man. We adjust for position, minutes and teammate-relative share, and we still tell you to trust orderings over gaps.

  • The matchup optimizer isn't a coach.

    It assigns threats to suppressors from season-long 5v5 rates. It doesn't know about last change, line-matching in-game, or special teams.

  • Small samples lie.

    Line chemistry on 30 minutes, a goalie's month of GSAx, a rookie's hot ten games — we show the minutes and games next to the number so you can discount accordingly.

  • The win-probability model is barely clairvoyant.

    58.9% accuracy, a hair better than naive. That's real signal in a coin-flip sport — and a terrible reason to bet the house. We publish the Brier score so you can judge.

The pipeline
  1. 01
    Pull

    NHL play-by-play and MoneyPuck feed the models with every shot, location and on-ice state.

  2. 02
    Compute

    Five XGBoost models score the game: xG on every shot, win probability, GSAx, player impact, development.

  3. 03
    Write

    A deterministic engine drafts the full article for free; an optional small language-model pass polishes only the prose — never the numbers.

  4. 04
    Commit & serve

    Each article is written as self-contained JSON and committed. The site is fully static — no live backend, no per-request model calls.

Editorial laws
  • Every claim carries a number and a context band. Never “the power play is hot” — always the rate, the rank, and whether it's process or variance.
  • Process, result and luck are always separated. The scoreboard is the start of the story, not the end of it.
  • Everything is computed, not voted. Three stars, the turning point, the deserved winner — all derived, with the inputs shown.
  • The machine authorship is the product, not a secret. Every article is signed “By the Model.”
  • Every proxy is labeled at the point of use — in the cell, not in a footnote you'll never find.

Every dotted-underlined term anywhere on this site opens its definition in place; the complete vocabulary lives on the glossary page, and both are rendered from the same file — a definition can't drift from its tooltip.

On the roadmap · league-wide playoff-odds deltas on every recap · nightly regression watch across all 32 teams · a process-vs-result luck index. Data: NHL API, MoneyPuck. xG model AUC 0.758.