luxury-lakehouse/xg-shot-freeze-frames
Pre-Shot xG v3 — Shot Freeze Frames (Context Corpus) The context half of the training corpus for xg_model_v3, the canonical-SPADL-native pre-shot expected goals model from the luxury-lakehouse analytics platform. One row per (shot, player) — every player present in the shot's freeze frame is a row. The provider is the data_source column, not a separate file format. Sourced from bronze.shot_freeze_frames. Each shot's freeze-frame player set is joinable to its tabular shot record… See the full description on the dataset page: https://huggingface.co/datasets/luxury-lakehouse/xg-shot-freeze-frames.
Pre-Shot xG v3 — Shot Freeze Frames (Context Corpus)
The context half of the training corpus for xg_model_v3, the canonical-SPADL-native pre-shot expected goals model from the luxury-lakehouse analytics platform. One row per (shot, player) — every player present in the shot's freeze frame is a row. The provider is the data_source column, not a separate file format. Sourced from bronze.shot_freeze_frames.
Each shot's freeze-frame player set is joinable to its tabular shot record (dataset `xg-shot-data-v3`) on the shot identity `(match_key, action_id)` — action_id is per-match, NOT globally unique, so both keys are always required. The set encoder in xg_model_v3 sum-aggregates this player set into the shot's context vector.
Columns / contract
Coordinates are canonical SPADL 105×68, home-LTR — no provider is bent to StatsBomb units. StatsBomb-360 freeze frames (raw 120×80) are converted at compute time. One row per (shot, player); the ball row is dropped and the shooter is always included (the sum-aggregation requires actor-inclusion consistency across sources). (access_tier is used internally for the public/restricted split and is dropped before upload.)
Public / restricted split
RM SkillCorner and GradientSports partitions are license-restricted: they publish to a private org-members-only companion repo (`xg-shot-freeze-frames-restricted`) rather than this public dataset, per lakehouse ADR-049 / ADR-064. StatsBomb-360 freeze frames are public. The split is per-row (per-match access_tier), so a public-licensed SkillCorner match publishes here while a restricted one goes to the companion. A partition migrates here automatically once its license permits public redistribution. The `xg_model_v3` trainer reads BOTH repos.
Quick Start
Every row carries a data_source column. The dataset is split into one config per provider, so you can pull a single provider without downloading the rest:
from datasets import load_dataset
# All public providers at once (config "all" — the default):
ds = load_dataset("luxury-lakehouse/xg-shot-freeze-frames", "all", split="train")
df = ds.to_pandas()
print(df["data_source"].value_counts())
# Just one provider (downloads only that provider's parquet):
sb = load_dataset("luxury-lakehouse/xg-shot-freeze-frames", "statsbomb", split="train").to_pandas()
# Reassemble a single shot's freeze-frame set:
shot = sb[(sb["match_key"] == 12345) & (sb["action_id"] == 678)]Related artifacts
- `xg-shot-data-v3` — the tabular shot record (the other half of the corpus), joined on
(match_key, action_id) - `spadl-vaep-action-values` — the full action-level value corpus
Citation
@software{luxury_lakehouse,
title = {Luxury Lakehouse — Serverless Soccer Analytics Platform},
url = {https://github.com/karsten-s-nielsen/luxury-lakehouse}
}License
CC-BY-NC-4.0 — see repository for details.
