Model performance
A practical view of how the historical shot-quality model estimates chances, with source context kept separate.
Expected goals estimates the chance that a shot becomes a goal based on the shot context. A 0.10 xG shot means similar shots are scored about 10% of the time.
The model describes shot quality in available historical data. It does not claim a player will score from a future location.
Production model
xgboost_xg_model
XGBoost was selected as the production expected-goals model because it performed best on log loss among the production candidates.
World Cup squads mix players from many leagues, competitions, and data sources. Training an xG model gives the dashboard one consistent way to translate historical shot locations and shot context into chance quality. For fans, that means the site can compare whether a player or team generated high-quality chances in available data, then clearly separate those chance-quality estimates from recent club context like FBref, Understat, and percentile profiles.
Long shot
Low chance
0.03 xG
A hopeful shot from distance. Similar chances are rarely scored.
Box shot
Medium chance
0.12 xG
A shot inside the box with some angle or defensive pressure.
Big chance
High chance
0.35 xG
A close-range chance where similar shots are scored much more often.
These are the headline validation metrics for the model used by the dashboard historical xG layer.
Log loss
0.283
Rewards calibrated probabilities
Brier score
0.081
Measures probability error
ROC-AUC
0.795
Ranks goals above non-goals
Accuracy
0.899
Secondary for xG
These are the dashboard's original production model candidates. The XGBoost model remains the production expected-goals layer.
| Model | Log loss | Brier | ROC-AUC | Accuracy | Rows |
|---|---|---|---|---|---|
| xgboost_xg_modelBest | 0.283 | 0.081 | 0.795 | 0.899 | N/A |
| baseline_logistic_regression | 0.286 | 0.082 | 0.789 | 0.899 | N/A |
Research experiments compare StatsBomb-only, Understat-only, combined-source, and reduced-feature xG models. These results are shown for transparency and are not automatically promoted into the dashboard's production player xG layer.
| Model | Test Source | Log loss | Brier | ROC-AUC | Accuracy | Rows |
|---|---|---|---|---|---|---|
| StatsBomb-only rich model StatsBomb | overall | 0.283 | 0.081 | 0.796 | 0.899 | 21,657 |
| StatsBomb-only rich model StatsBomb | StatsBomb | 0.283 | 0.081 | 0.796 | 0.899 | 21,657 |
| Understat-only model Understat | overall | 0.261 | 0.075 | 0.819 | 0.907 | 103,044 |
| Understat-only model Understat | Understat | 0.261 | 0.075 | 0.819 | 0.907 | 103,044 |
| Understat published xG benchmarkBest Understat published model | Understat | 0.248 | 0.070 | 0.836 | 0.908 | 103,044 |
| Combined-source shared model StatsBomb + Understat | overall | 0.271 | 0.077 | 0.802 | 0.904 | 124,701 |
| Combined-source shared model StatsBomb + Understat | StatsBomb | 0.284 | 0.081 | 0.787 | 0.899 | 21,741 |
| Combined-source shared model StatsBomb + Understat | Understat | 0.268 | 0.077 | 0.806 | 0.905 | 102,960 |
This tests your friend's idea directly: richer features versus reduced or missing event context. Accuracy barely moves, so calibration metrics matter more.
| Model | Missing Ref Features | Log loss | Brier | ROC-AUC | Accuracy | Rows |
|---|---|---|---|---|---|---|
| statsbomb_full_rich_features StatsBomb | 0% | 0.283 | 0.081 | 0.796 | 0.899 | 21,657 |
| statsbomb_geometry_only StatsBomb | 40% | 0.299 | 0.086 | 0.757 | 0.896 | 21,657 |
| statsbomb_understat_style_reduced StatsBomb | 10% | 0.284 | 0.082 | 0.794 | 0.898 | 21,657 |
| understat_only_reduced_features Understat | 10% | 0.261 | 0.075 | 0.819 | 0.907 | 103,044 |
| combined_source_shared_features StatsBomb + Understat | 10% | 0.271 | 0.078 | 0.802 | 0.904 | 124,701 |
Log loss
Lower
Sensitive to confident wrong probabilities.
Brier score
Lower
Average squared probability error.
ROC-AUC
Higher
Ranks goals above non-goals across thresholds.
Accuracy
Secondary
Can be misleading because most shots are not goals.
Streamlit was used as an early prototype for model exploration and validation. The production portfolio path is a precomputed artifact pipeline served through FastAPI and rendered in Next.js.
Step 1
StatsBomb Open Data
Historical shot events
Step 2
Pandas cleaning + feature engineering
Shot coordinates, distance, angle, context
Step 3
scikit-learn / XGBoost model training
Chance-quality probability model
Step 4
MLflow experiment tracking
Metrics, model runs, artifacts
Step 5
Dashboard JSON artifacts
Precomputed team and player profiles
Step 6
FastAPI backend
Clean API layer for the frontend
Step 7
Docker deployment
Portable app runtime
Step 8
AWS S3 / EC2
Portfolio deployment target
Step 9
Next.js + Tailwind frontend
Fan-friendly scouting dashboard
How to read this dashboard
Past shot samples used by the expected-goals model. Not a 2026 prediction.
25/26 percentile scouting profiles. Percentiles are not raw stats and are not model inputs.
Recent club and league form context. Not used by the trained expected-goals model.
Club expected-goals context from covered leagues, plus a separate experimental xG check where clearly labeled.
Known model limits