Playground

Build the chance.

Move the players. See how positions change the inputs and the estimate.

By Leonardo Ferreira

Decisions, evidence and limits

Behind the estimate

A playground for understanding goal-scoring chances and inspecting how data, modeling choices and engineering reach the number on screen.

What the number means

An estimate of 0.20 xG represents roughly 20 goals in 100 comparable shots according to this model. It is not an exact probability for a particular player. Here, the invented scene simplifies real context.

Source and population

We use StatsBomb Open Data with observed goal/non-goal outcomes; source xG is never the target. The population consists of male open-play foot shots. Headers, penalties and other situations are excluded from training. Event frames are the primary observation; optional 360 availability does not guarantee all defenders are visible. Missing keepers and singular goal-line cases are excluded, without imputation.

StatsBomb Open Data

Eight positional inputs

Geometry describes the opportunity; counts and distances describe observed opponents. The cone is the finite triangle between shot and posts. Positions use meters independently of SVG. With zero defenders, distance uses the pitch diagonal sentinel alongside the explicit count. Other attackers, identity, preferred foot, technique, speed and temporal context are omitted.

FeatureRationale
Shot distance (m)Distance to the goal center.
Goal opening angle (°)Opening between goalposts.
Lateral offset (m)Lateral asymmetry without distinguishing left/right.
Represented defendersNumber of represented opponents.
Defenders in coneOccupancy of the shot triangle.
Nearest defender (m)Proximity of the nearest observed opponent.
Keeper to goal (m)Keeper positioning relative to goal.
Keeper to shot (m)Proximity between keeper and shot.

Training, selection and freezing

Whole matches are separated into training, calibration, selection and test, avoiding shared match events between groups. Bounded search uses five folds on training only; logistic scaling is fitted within each fold. Three logistic regressions isolate geometry, defenders and all inputs. Shallow XGBoost tests nonlinear interactions. There is no class balancing or post-selection refit.

Match partitions
PartitionMatchesShotsGoals
Calibration1833,440314
Selection1803,643324
Final test3637,160Unopened during selection
Training1,08720,7771,966

The declared rule selected XGBoost using observed performance and the Brier deterioration guardrail for preferring simplicity. Selection intervals did not establish conclusive superiority. Sigmoid calibration did not meet adoption criteria. Freezing means fixing inputs, preprocessing, trees and calibration before opening the final test; the interface only executes those parameters.

XGBoost
300 trees · depth 2 · learning rate 0.05 · minimum child weight 5
Calibration
No recalibration (identity)

Validation and final test

Log loss penalizes confident wrong probabilities; Brier measures squared probability error. Lower is better. Selection chooses the model; final test evaluates the already fixed model. It was not used for retuning. The 95% intervals resample whole matches, preserving shot dependence.

Selection — not the final test

ModelShotsGoalsLog lossBrier
Constant prevalence3,6433240.3002650.08106
Logistic: geometry3,6433240.2458760.069567
Logistic: defenders3,6433240.2402040.067658
Full logistic3,6433240.2383550.067612
Full XGBoost3,6433240.2352080.066974

Final test held out until freezing

ModelShotsGoalsLog lossBrier
Full XGBoost7,1606550.2399650.068339
Full logistic7,1606550.2428710.069261
Constant prevalence7,1606550.3060080.083122

Paired final-test differences

XGBoost minus reference: negative values favor XGBoost. Overall intervals favor the candidate on this test; this does not guarantee an advantage in every slice or transfer to other competitions or scenes.

ReferenceScoreDifference95% interval
Constant prevalenceBrier-0.014783[-0.017492; -0.012139]
Constant prevalenceLog loss-0.066043[-0.075388; -0.056869]
Full logisticBrier-0.000922[-0.001781; -0.000067]
Full logisticLog loss-0.002906[-0.005424; -0.000343]

Calibration and sparse samples

The diagonal represents agreement between predicted mean and observed frequency. Bars show match-based 95% intervals of observed frequency; hollow points mark sparse bins. No supported bin was flagged, but high-probability ranges have few examples and do not support precision for extreme scenes.

Calibration and sparse samplesThe diagonal represents agreement between predicted mean and observed frequency. Bars show match-based 95% intervals of observed frequency; hollow points mark sparse bins. No supported bin was flagged, but high-probability ranges have few examples and do not support precision for extreme scenes.0%0%25%25%50%50%75%75%100%100%Predicted meanObserved frequency
The diagonal represents agreement between predicted mean and observed frequency. Bars show match-based 95% intervals of observed frequency; hollow points mark sparse bins. No supported bin was flagged, but high-probability ranges have few examples and do not support precision for extreme scenes.
Calibration and sparse samples
Prediction binShotsPredicted meanObserved frequency95% intervalSparse
0%–10%5,3243.5%3.7%3.1% – 4.2%Supported
10%–20%81814.3%13.6%11.2% – 15.9%Supported
20%–30%42924.8%21.7%17.9% – 25.6%Supported
30%–40%28234.4%33.7%28.2% – 39.6%Supported
40%–50%16444.4%47%39.6% – 53.5%Supported
50%–60%6954.7%49.3%37.3% – 60.3%Sparse
60%–70%4164%58.5%44.2% – 73.3%Sparse
70%–80%1774.2%82.4%62.5% – 100%Sparse
80%–90%985.3%55.6%20% – 87.5%Sparse
90%–100%791.8%100%100% – 100%Sparse

The adverse slice matters too

With two defenders inside the cone, XGBoost was worse than full logistic on this test. This refers to the cone count, not the total on the pitch. We keep this result visible; overall averages do not erase local failures.

Shots: 815 · Supported

XGBoost − Full logistic
ScoreDifference95% interval
Brier0.000877[-0.000344; 0.002305]
Log loss0.005375[0.000098; 0.011708]

Illustrative scenes and transfer

The descriptive reference uses neighbors in standardized training-only features, with a 99% threshold and a separate zero-defender cohort. We do not publish reference rows, so the interface does not calculate joint support for each edit. Four open-play presets fall outside this reference; being inside does not prove realism either. Rare scenes remain explorable. Comparisons are not causal effects; partial visibility, few defenders and other domains limit interpretation.

Execution and reproduction

TypeScript extracts the same eight inputs as the Python pipeline. The loader validates and captures immutable parameters; XGBoost preserves float32 comparisons/accumulation within 1e-7 tolerance. Trees may retain the result after small movements. Invalid inputs or unavailable models receive no substitute heuristic. Penalties use the fixed 0.76 convention, separate from the learned model.

Scientific review was accepted with limitations and distribution of the exact artifact was reviewed for the free/non-commercial scope. The original automatic status remains “needs_review”; review does not authorize publication. Private training and complete reproduction were run by the owner; the assistant reviewed aggregates/checks without rerunning private data.

Identity and review
Artifact
758526873b8a3a2681f655c064dee52f8bd33749accd499d015420dbe8e11b9a
Training run
222909fe801f4865897fea3541e023fed626f6736dca6ef69ceada1f7c57945a
Evidence
e579e10f9699077ddf05e7433af5ed63edf0e03c3ea8c7ca295844951d74ea08
Scientific review · Oct 11, 2026
Accepted with limitations
Original automated status
Needs review
Publication authorization
No
Final test held out until freezing
7,160 Shots · 655 Goals