Skip to content

jaime-oriol/CCV

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

220 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JO

CCV — Causal Clutch Value

TFM · Máster en Big Data Aplicado al Scouting Deportivo · Sports Data Campus
Jaime Oriol Goicoechea


Estimación causal del efecto del shock emocional (gol a favor / gol en contra / proximidad de eliminación) sobre el comportamiento del jugador en ventanas pre vs post de ±10 min, medido en cuatro canales (Empuje Ofensivo, Solidez Defensiva, Inteligencia Espacial Off-ball, Pulso Físico) sobre PFF FC World Cup Qatar 2022.

Output: ranking tridimensional de jugadores clutch (Indice Remontador post GA + Indice Cerrojo post GF + Pressure Response continuo en elim_prox) con intervalos de credibilidad bayesianos, agregado por bucket posicional (DEF/MED/ATA) y posicion granular (16 PFF labels).

Pipeline conceptual y arquitectura causal

El CCV se compone de dos mapas: el mapa conceptual describe qué descompone (tipo de shock × ruptura del bloque × signo de la reaccion sobre 4 canales) y el stack de 5 capas causales describe como aisla el efecto del jugador del empuje colectivo del equipo.

Mapa conceptual CCV

5 capas causales CCV

El pipeline tecnico se ejecuta como un DAG de 6 fases: extraccion -> WP backbone -> shocks/near-miss -> 4 canales en paralelo -> CATE jerarquico -> ensamblaje scout-facing.

Pipeline DAG CCV

Ficha scout-facing (ejemplo)

Radar ficha Mbappe

Estructura del repositorio

Datos raw originales (PFF tracking, StatsBomb, Wyscout) y documentacion interna del proyecto estan fuera del repositorio (.gitignore).

CCV/
├── README.md                                      # este fichero
├── TFM_CCV.pdf                                    # PDF compilado del TFM
├── run_pipeline.sh                                # E2E orquestador (auto detect cores + GPU)
├── data/parquet/
│   ├── pff/                                       # versionado: events (64) + metadata + rosters
│   └── derived/                                   # versionado: caches M03 a M14
│       ├── preprocess/, wp/, psxg/, nearmiss/, shocks/
│       ├── ataque/, defensa/, offball/, fisico/
│       ├── did/, did_validation/, aipw/, audit/
│       └── cate/                                  # M14 outputs (cate_nuts.pkl ignorado, 409 MB regenerable)
├── cache/vaep/                                    # versionado: features + labels VAEP por partido
├── src/
│   ├── extract/                                   # extractores raw a parquet (lossless)
│   ├── preprocess/pff_grades_extract.py           # priors PFF grades (input M14)
│   ├── M01_loader_pff.py                          # API PFF (events, tracking, metadata, rosters)
│   ├── M02_loader_public.py                       # API Wyscout + StatsBomb (polars nativo)
│   ├── M03_preprocess.py                          # direction, score state (SB ground truth), minutos, enrich_events
│   ├── M04_wp.py                                  # Win Probability bayesiana (numpyro SVI ordered logistic)
│   │                                              #   + leverage + ET Poisson + tanda parametrica + MC group elim_prox
│   ├── M05_psxg.py                                # Post shot xG (LightGBM + Optuna 60 + isotonic + freeze 360)
│   │                                              #   AUC OOF 0.968, holdout WC22 0.976 (vs SB 0.844)
│   ├── M05B_calibration.py                        # PSxG calibration (curve, ECE/MCE, Brier Murphy 1973)
│   ├── M06_nearmiss.py                            # Near miss 5 tipos (palo, offside 360, PSxG save, GLC, GLT)
│   ├── M07_shocks.py                              # 172 shocks gol + ventanas ±10min + LOO team_members
│   ├── M08_ataque.py                              # Empuje Ofensivo: atomic VAEP CatBoost + un xPass (Z06)
│   ├── M09_defensa.py                             # Solidez Defensiva: vdep_strict (Z04) + xpress (Z03)
│   │                                              #   + maejima (Z05) + def3rd + press_value
│   ├── M10_offball.py                             # Off ball OBSO + C OBSO (Spearman 2018 + Teranishi 2022)
│   │                                              #   PPCF Z02 + xG grid + tracking PFF 25Hz
│   ├── M11_fisico.py                              # Pulso Fisico Bradley 2024 + bayesiano jerarquico SVI
│   ├── M12_did.py                                 # DiD within player: ATE FE + Sun Abraham + BJS + HonestDiD
│   ├── M12B_validation.py                         # placebo + power + window sensitivity + stage stratified
│   ├── M13_aipw.py                                # AIPW DoubleMLIRM + DML PLR + DR learner + RDD + spec curve
│   ├── M14_cate.py                                # CATE bayesiano NUTS HMC 4 chains + 5 etas + LKJ
│   ├── M15_ccv.py                                 # tabla scout final + 16 cells contextualizados + buckets
│   ├── audit_models.py                            # auditoria 100% modelos predictivos (PSxG/VAEP/VDEP/exPress/unxPass)
│   ├── render_ficha.py                            # ficha visual scout facing por jugador
│   ├── Z01_vaep.py                                # atomic VAEP wrapper
│   ├── Z02_pitch_control.py                       # PPCF Spearman 2018 vectorizado
│   ├── Z03_xpress.py                              # exPress Lee 2025 P(recovery<5s|press)
│   ├── Z04_vdep.py                                # VDEP strict Toda 2022 (recovery + attacked)
│   ├── Z05_maejima.py                             # Atribución frame-level al defensor más cercano
│   └── Z06_unxpass.py                             # un xPass Robberechts 2023 creative decision
├── notebooks/
│   ├── regen_all.ipynb                            # regen E2E completa M03-M15 + Z03-Z06 en orden DAG
│   └── regen_m14_kaggle.ipynb                     # regen M14 NUTS HMC en Kaggle GPU
└── outputs/
    ├── ccv_table.parquet                          # tabla scout final (511 jug x 299 cols)
    ├── viz/                                       # figuras PNG (PPCF, radar, radar_report, scatter, scatter_team, event-study, mapa conceptual, capas causales, pipeline DAG)
    ├── assets/                                    # logos selecciones (33) + caras jugadores FotMob + logo JO + logo SDC
    └── ccv_aux/
        ├── top10_chasing_per_position.parquet     # 16 position_group granulares
        ├── top10_protecting_per_position.parquet
        ├── top10_pressure_per_position.parquet
        ├── top10_chasing_per_bucket.parquet       # 4 buckets (DEF/MED/ATA, GK aparte)
        ├── top10_protecting_per_bucket.parquet
        ├── top10_pressure_per_bucket.parquet
        ├── dual_clutch_top.parquet
        └── by_team.parquet

Estado del pipeline

E2E ejecutado al 100%. Outputs versionados en repo. Caches regenerables via notebooks/regen_all.ipynb o run_pipeline.sh.

Modulo Output principal Sanity verificado
M03 preprocess/events_enriched/{match_id}.parquet × 64 144,541 filas, 172 goles SB ground truth
M04 wp/per_minute.parquet 5,910 filas (64 partidos, minuto 1-120 con ET)
M05 psxg/{shots,model/psxg_lgb.pkl} AUC OOF 0.968, holdout WC22 0.976 (vs SB 0.844)
M05B psxg/calibration/{curve,brier,metrics,iso}.parquet ECE 0.011, Brier 0.037 (vs SB 0.083)
M06 nearmiss/nearmiss_table.parquet 70 near miss (12 woodw + 5 offs + 42 save + 2 GLC + 9 GLT)
M07 shocks/{shocks_table,shocks_team_members}.parquet 172 shocks x ~22 jug = 3,788 filas
M08 ataque/{per_minute,per_shock_window,model} atomic VAEP + un xPass; per_minute 57,520 filas
Z03 defensa/xpress/per_minute.parquet exPress Lee 2025; AUC 0.6174 (+24% baseline)
Z04 defensa/vdep_strict/per_minute.parquet VDEP Toda 2022; AUC rec 0.7950 / att 0.8308
Z05 defensa/maejima/per_minute.parquet Atribución defensor más cercano; 38.005 filas
Z06 ataque/unxpass/per_minute.parquet un xPass Robberechts 2023; AUC 0.8309
M09 defensa/{per_minute,per_shock_window,press_value,ctx} score_def_v4 = vdep + xpress + maejima; 57,466 filas
M10 offball/{per_minute,per_shock_window,xg_grid} OBSO + C OBSO; 105,214 filas; 64 partidos a 25 Hz full
M11 fisico/{raw_per_minute,per_minute,per_shock_window,model} Bradley 2024 + SVI multivariate; 145,351 filas
M12 did/{panel,ate_population,event_study,honest,diag} DiD within player + Sun Abraham + BJS; FE~BJS (max 4.2% SE)
M12B did_validation/{placebo,power,window,baseline_naive,stage} placebo 1000 perm + BH FDR (null); window fisico-GA ~8x w3-w10
M13 aipw/{panel_master,att_aipw,att_dml_plr,att_dr_learner} 163 shots con jug en campo; 12,416 filas panel; AIPW+DML+DR
M14 cate/{panel_delta,posterior_player,indices,rankings,diag} NUTS 4x1000+1000 GPU; 0 div; 108/144 R-hat<1.05; PPC 8/8
M15 outputs/ccv_table.parquet + ccv_aux/ 511 jug x 299 cols + 4 buckets posicionales (GK/DEF/MED/ATA)

Documento TFM

PDF completo del trabajo en el root del repo: TFM_CCV.pdf.

Reproducibilidad

# Clonar repo y arrancar pipeline E2E (cache hit en M03-M14 instantaneo)
git clone https://github.com/jaime-oriol/CCV.git
cd CCV
./run_pipeline.sh                # auto detect cores + GPU
# Outputs en outputs/ccv_table.parquet + ccv_aux/

Para regenerar desde cero (sin cache hit, requiere raw PFF + StatsBomb + Wyscout):

FORCE_CLEAN=1 ./run_pipeline.sh

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors