CoolFace
Datasetpublic

ClementeH/statsbomb-open-data-shots

StatsBomb Open Data β€” Football Shots (xG) 88,023 shot-level football records extracted from StatsBomb Open Data, spanning 67 years of football (1958–2025) across 21 competitions, 48 seasons, 308 teams, and 6,147 players. Includes StatsBomb's own xG values as labels, making this the most complete open football shot dataset available on HuggingFace for training Expected Goals models. Highlights πŸ† Lionel Messi β€” 2,670 shots, the most of any player in the dataset… See the full description on the dataset page: https://huggingface.co/datasets/ClementeH/statsbomb-open-data-shots.

sourceHugging Facecc-by-sa-4.0updated 5mo agoView on Hugging Face
0likes82downloads
Dataset Card

StatsBomb Open Data β€” Football Shots (xG)

88,023 shot-level football records extracted from StatsBomb Open Data, spanning 67 years of football (1958–2025) across 21 competitions, 48 seasons, 308 teams, and 6,147 players.

Includes StatsBomb's own xG values as labels, making this the most complete open football shot dataset available on HuggingFace for training Expected Goals models.

Highlights

  • β€”πŸ† Lionel Messi β€” 2,670 shots, the most of any player in the dataset (18 La Liga seasons at Barcelona)
  • β€”πŸŒ Historical depth β€” FIFA World Cup data from 1958 to 2022
  • β€”βš½ Both genders β€” FA Women's Super League, Women's World Cup, UEFA Women's Euro included
  • β€”πŸ“Š StatsBomb xG labels β€” use as regression target or benchmark for your own model
  • β€”πŸŽ― Benchmark β€” A GradientBoosting model trained on this dataset achieves ROC-AUC 0.8047, reaching 98% of StatsBomb's professional xG model performance (ROC-AUC 0.8198) using only 9 features

Dataset Statistics

MetricValue
Total shots88,023
Goals9,790 (11.1%)
Unique players6,147
Unique teams308
Competitions21
Seasons48
Date range1958-06-24 β†’ 2025-07-27
Mean xG per shot0.107

Coverage by Competition

CompetitionShotsGoalsPlayersSeasons
La Liga21,2102,6581,31218
Premier League10,8371,0826412
Ligue 110,3461,1057393
Serie A10,0339554752
1. Bundesliga8,7479475602
FA Women's Super League8,3219623303
FIFA World Cup3,9044438908
Women's World Cup2,9943275762
UEFA Euro2,6292815472
Champions League5947419318
+ 11 more competitions

Splits

SplitShotsGoals
train70,4187,825 (11.1%)
validation8,802979 (11.1%)
test8,803986 (11.2%)

Stratified by is_goal to preserve goal rate across splits.

Features

ColumnTypeDescription
xfloatShot x-coordinate (StatsBomb pitch: 0–120, attacking direction)
yfloatShot y-coordinate (StatsBomb pitch: 0–80)
distance_to_goalfloatEuclidean distance to goal center (120, 40)
angle_to_goalfloatAngle to goal in degrees
under_pressureboolShooter was under defensive pressure
shot_body_part_namestringRight Foot / Left Foot / Head / Other
shot_technique_namestringNormal / Volley / Half Volley / Lob / Overhead Kick / Backheel
shot_type_namestringOpen Play / Free Kick / Corner / Penalty
play_pattern_namestringRegular Play / From Corner / From Free Kick / etc.
shot_outcome_namestringGoal / Saved / Blocked / Off T / Wayward / Post
xg_statsbombfloatStatsBomb's official xG value β€” use as regression label or benchmark
is_goalint1 if goal, 0 otherwise β€” binary classification label
playerstringPlayer full name
teamstringTeam name
competition_namestringCompetition name
season_namestringSeason (e.g. 2019/2020)
match_datestringMatch date (YYYY-MM-DD)
match_idintStatsBomb match identifier

Pitch Coordinates

StatsBomb uses a 120Γ—80 coordinate system:

  • β€”x=0 is the defensive goal line, x=120 is the attacking goal line
  • β€”y=0 is the left touchline, y=80 is the right touchline
  • β€”Goal center is at (120, 40)

Quick Start

python
from datasets import load_dataset

ds = load_dataset("ClementeH/statsbomb-open-data-shots")
df = ds["train"].to_pandas()

# All Messi shots
messi = df[df["player"] == "Lionel AndrΓ©s Messi Cuccittini"]
print(f"Messi: {len(messi)} shots, {messi['is_goal'].sum()} goals, mean xG {messi['xg_statsbomb'].mean():.3f}")

# Train a simple xG model
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.preprocessing import LabelEncoder

features = ["x", "y", "distance_to_goal", "angle_to_goal", "under_pressure"]
X = df[features].astype(float)
y = df["is_goal"]

model = GradientBoostingClassifier(n_estimators=200, max_depth=4)
model.fit(X, y)

Benchmark: xG Model Performance

A GradientBoosting model trained on this dataset (9 features) vs StatsBomb's professional xG:

ModelBrier Score ↓ROC-AUC ↑
Logistic Regression (baseline)0.08580.7706
GradientBoosting (this dataset)0.08030.8047
StatsBomb xG (professional)0.07700.8198

The open model reaches 98% of professional xG performance using only position, body part, technique, shot type, and pressure.

See `ClementeH/football-xg` for the trained model (coming soon).

Attribution

Data provided by StatsBomb via [StatsBomb Open Data](https://github.com/statsbomb/open-data). Licensed under CC BY-SA 4.0. You are free to share and adapt this data for any purpose, provided you give appropriate credit to StatsBomb and distribute your contributions under the same license. This dataset was processed and packaged for HuggingFace by ClementeH.

Related Resources