Spaces:
Running
Running
| title: Reportes Racing | |
| emoji: ⚽ | |
| colorFrom: green | |
| colorTo: gray | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| # Reportes Racing | |
| Web privada para generar los reportes tácticos reales (pre-partido / | |
| head-to-head, post-partido y bloques z-score) sin setup local. La data se | |
| descarga desde Azure Data Lake; nada de datos en el repo. | |
| ## Cómo se usa (gente no técnica) | |
| 1. Abrir el link del Space (te invitan con tu cuenta de Hugging Face) e | |
| ingresar la contraseña si la web la pide. | |
| 2. **Reporte previo / Bloques**: elegir Equipo A y Equipo B (cualquier par, | |
| aunque no se hayan jugado), opcionalmente fechas desde/hasta para Bloques, | |
| y tildar qué reportes querés. Click en *Generar*. | |
| 3. **Reporte post-partido**: tocar *Cargar lista de partidos jugados*, elegir | |
| el partido y *Generar post-partido* (corre también el previo de ese | |
| partido automáticamente). | |
| 4. Aparece una pantalla de progreso que se actualiza sola. Puede tardar | |
| varios minutos (especialmente la primera vez del día). Al terminar muestra | |
| los links para **Ver** y **Descargar** cada reporte. | |
| ## Deploy en Hugging Face Spaces (privado) | |
| 1. Crear un Space tipo **Docker**, visibilidad **Private**. | |
| 2. Conectarlo a este repo (o `git push` al remoto del Space). | |
| 3. En *Settings → Variables and secrets* cargar los secrets de Azure | |
| (Service Principal con permiso de lectura sobre el Data Lake): | |
| ``` | |
| AZURE_TENANT_ID=... | |
| AZURE_CLIENT_ID=... | |
| AZURE_CLIENT_SECRET=... | |
| AZURE_STORAGE_ACCOUNT=stdlprodfrancecentral001 | |
| AZURE_FILESYSTEM=fs-dl-prod-francecentral-001 | |
| AZURE_PREPROCESSED_ROOT=raw/eventing/processed | |
| AZURE_REPORT_ARTIFACTS_ROOT=raw/eventing/report_artifacts | |
| ACCESS_PASSWORD=una-clave-compartida # opcional, candado extra | |
| ``` | |
| 4. Build automático. El disco del Space es efímero: en un arranque en frío se | |
| vuelven a descargar los datasets desde Azure (lento la primera vez, luego | |
| queda cacheado mientras el Space siga vivo). | |
| Invitar a la gente al Space privado = control de acceso. | |
| ## Uso local (desarrollo) | |
| ```bash | |
| python -m venv .venv && source .venv/bin/activate | |
| pip install -e ".[dev]" | |
| cp .env.sample .env # editar credenciales | |
| az login # auth local (sin Service Principal) | |
| racing-reports-web # http://127.0.0.1:7860 | |
| ``` | |
| Para correr sin Azure (con datos ya locales) exportar | |
| `RACING_LOCAL_DATA_DIR=/ruta/con/preprocessed+artifacts`. | |
| ## Prerrequisito de datos en Azure | |
| Los reportes reales necesitan, además del preprocessed base, artifacts | |
| pesados y el preprocessed **etiquetado**. Subirlos una vez con: | |
| ```bash | |
| python scripts/upload_report_artifacts.py # parquets + bundles GNN | |
| python ../scripts/upload_preprocessed_labeled.py \ | |
| --local-path /ruta/preprocessed_..._etiquetado_final.csv \ | |
| --remote-name preprocessed_SSD_25-26_etiquetado_modelo.csv | |
| ``` | |
| ## Modelo de predicción de ataque (matchup GNN) | |
| El reporte previo / head-to-head puede mostrar la **distribución de ataque | |
| esperada por zona** (local y visitante) según un modelo de red neuronal. El | |
| modelo de producción es el **matchup GNN** (`train_attack_matchup_gnn.py`), que | |
| reemplaza al viejo `attack_distribution_gnn`: selecciona ~200 features de alta | |
| señal (en vez de ~950, atacando el sobreajuste), agrega una interacción bilineal | |
| explícita atacante × defensor por zona, y aprende un *delta* sobre el promedio | |
| del equipo. En test le gana al baseline "promedio de temporada" de forma | |
| estadísticamente robusta (IC bootstrap del 95% que excluye el cero). | |
| Las predicciones están **apagadas por defecto** (MVP). Hay dos formas de servir | |
| los artifacts del modelo; en ambas se activa con el secret | |
| `RR_ENABLE_NN_PREDICTIONS=1` en el Space. | |
| **Opción A — bundlear en el repo (sin Azure, recomendada).** El datastore usa los | |
| artifacts reales de `vendor/data/modeling/` antes de ir a Azure. Como la app | |
| recalcula los rolling al vuelo desde las columnas crudas, el dataset se recorta de | |
| **71 MB → ~10 MB** sin cambiar ninguna predicción: | |
| ```bash | |
| python ../scripts/build_app_modeling_subset.py --copy-bundles | |
| git add racing-reports/vendor/data/modeling/{attack_prediction_dataset.parquet,attack_matchup_gnn_bundle.pt,pv_distribution_gnn_bundle.pt} | |
| git commit -m "bundle modelo de ataque" # parquet ~10 MB: usar git-lfs si tu remoto lo pide | |
| ``` | |
| En el próximo arranque la app usa esos archivos directamente, sin tocar Azure. | |
| **Opción B — subir a Azure.** Si preferís no commitear artifacts: | |
| ```bash | |
| RR_ENABLE_NN_PREDICTIONS=1 python scripts/upload_report_artifacts.py --source /ruta/Racing/data --overwrite | |
| ``` | |
| En el cold start la app descarga `modeling/attack_matchup_gnn_bundle.pt` (y el de | |
| PV + el dataset) desde Azure. | |
| ## Actualizar la data y el modelo (pipeline) | |
| Un solo orquestador idempotente encadena todo el ciclo, desde los eventos crudos | |
| hasta el bundle publicado que consume la app: | |
| ```bash | |
| python ../scripts/run_attack_model_pipeline.py # todo (saltea lo que ya está al día) | |
| python ../scripts/run_attack_model_pipeline.py --list # ver los stages | |
| python ../scripts/run_attack_model_pipeline.py --only train --train-args "--top-k 200 --seeds 3" | |
| python ../scripts/run_attack_model_pipeline.py --from dataset --force | |
| ``` | |
| Stages: `events` → `zone_features` → `dataset` → `rolling` → `train` → `publish`. | |
| Los stages `events` y `publish` requieren credenciales de Azure. | |
| ## Salida | |
| ```text | |
| {RACING_REPORTS_OUTPUT_DIR}/{league}/{season}/{slug}/{report}.html | |
| {RACING_REPORTS_OUTPUT_DIR}/{league}/{season}/{slug}/manifest.json | |
| ``` | |