Player-Level Team Strength

Status

Roadmap: v4 (post-tournament model upgrade) — Not yet implemented. Captures the
literature and approach for moving from team-level attack/defense multipliers to
per-player xG aggregation.

Versioning reconciled 2026-06-15. This page originally said "v2", which
collided with two now-concrete meanings: the sports-prediction-mvp PLAN's
Milestone v2 (Dixon-Coles + ELO + ensemble + knockouts) and the model
registry's poisson_dc_v2 (the Dixon-Coles version). Player/xG is neither —
it is PLAN Milestone v4, ranked #3 by expected ROI, scheduled after v3
(betting) and behind recalibration and bivariate Poisson. The PLAN is
authoritative for scheduling; this page is authoritative for the method.


Motivation

The standard Poisson model uses team-level attack/defense multipliers (e.g., λ = league_avg × attack_team × defense_opponent). These are coarse — they treat "Man City" as a single entity. A player-level model would:

  • Capture the difference between Man City with Haaland vs without him
  • Weight contributions by minutes played
  • Allow in-season updates as lineups change
  • Improve predictions for matches where key players are missing

Literature

Arntzen & Hvattum (2021)

"Predicting match outcomes in association football using team ratings and player ratings"
- Compares team-level ELO vs individual player ratings (plus-minus variant)
- Uses average player rating from starting XI as team strength covariate
- Team-level ELO remains strong baseline; player ratings provide incremental improvement
- Source: SAGE Journals, 2021

Karlis & Ntzoufras (2003)

"Bivariate Poisson model for football"
- Jointly models home/away goals (addresses independence violation)
- Foundation for multivariate Poisson extensions
- Does not incorporate player-level data; standard upgrade path alongside player ratings

Frontiers (2025)

Bundesliga match analysis paper explicitly identifies player-level info as a gap:

"Including such individual player information (e.g., by analyzing the starting line-up of both teams) could potentially enhance the model’s predictive power"
- Confirms this is a known, open problem in the literature


Approach for v2

Step 1 — Rate individual players

Two components needed per player:

  • xG created — expected goals from shots the player contributed to (via key passes, pre-assists, etc.)
  • xG conceded — expected goals the player allowed to the opponent while on the pitch

Standard methods:
- Plus-Minus — net goal impact per 90 minutes
- RAPM (Regularized Adjusted Plus-Minus) — plus-minus with ridge regression regularization to handle sparse data
- VAEP (Valuing Actions by Estimating Probabilities) — more sophisticated, includes defensive actions

Step 2 — Aggregate to team λ

For a given lineup, team attack λ is the sum of individual player xG contributions:

λ_attack_team = Σ(player_xG_created_per_90 × minutes_fraction) / 90
λ_defense_team = Σ(player_xG_conceded_per_90 × minutes_fraction) / 90

Then plug into the Poisson framework:

λ_home = league_avg × f(λ_attack_home, λ_defense_away)
λ_away = league_avg × f(λ_attack_away, λ_defense_home)

Where f() is a calibrated function (could be log-linear, could be learned via regression).

Step 3 — Handle lineup uncertainty

  • Model a distribution over possible lineups (injury/suspension news → probability weights)
  • Run the model over the distribution and take a weighted average
  • Track "player availability" as a separate signal

Challenges

  1. Context dependence — striker xG and defender xG are in different units; aggregation needs careful normalization
  2. Sample size — individual player ratings are noisy with few minutes; need shrinkage toward position averages
  3. Lineup changes — 11 players × ~5 subs × ~34 league games = large combinatorial space for lineup combinations
  4. Data availability — getting per-player xG data at scale requires StatsBomb / Opta / Wyscout subscription; not free
  5. Independence violation remains — player-level aggregation doesn't fix the Dixon-Coles problem

See Also