la-liga-score-predictor / MODEL_CARD.md
addweb-solution's picture
Upload folder using huggingface_hub
653c38a verified
|
Raw
History Blame Contribute Delete
12.5 kB
# La Liga Score Predictor Model Card
## Scope
This document describes the public La Liga Score Predictor model.
Included:
- model architecture
- feature families
- inference behavior
- output schema
- evaluation approach
Excluded on purpose:
- other internal model variants
- source-provider specific ingestion details
- private infrastructure
## Model Summary
- Model version: `la_liga_score_predictor`
- Public package version: `2026.04.1`
- Model type: `catboost_two_stage`
- Task: pre-match football score prediction
- Competition scope: Spanish La Liga only
- Primary outputs:
- expected home goals
- expected away goals
- predicted score
- home/draw/away probabilities
- confidence level
- abstain / score-range signal for fragile matches
## High-Level Architecture
The La Liga Score Predictor model is a two-stage CatBoost setup.
Stage 1:
- one CatBoost model predicts expected home goals
- one CatBoost model predicts expected away goals
Stage 2:
- one CatBoost model predicts match-outcome probabilities:
- `home_win`
- `draw`
- `away_win`
Final score decoding:
- score decode mode: `poisson_argmax`
- home Poisson scale: `1.10`
- away Poisson scale: `1.05`
Probability post-processing:
- temperature calibration: `0.93`
Low-confidence handling:
- abstain mode enabled
- score-range output enabled for fragile matches
## Competition Scope
This public release is intended only for Spanish La Liga fixtures.
It should not be treated as a validated model for other leagues without retraining or separate evaluation.
## What the Model Learns From
The model is trained on structured pre-match football features only.
It does not need interactive conversation context, database access, or any auxiliary external signal outside the supported feature schema for public inference.
## What This Public Package Does Not Include
This release does not include:
- a full production historical La Liga dataset
- a hosted or live data source
- a promise of reproducing a private/internal prediction environment exactly
The public package includes the model and the wrapper logic.
For `predict_match(...)`, the caller must still supply compatible historical match data.
This public release should be treated as:
- a model-and-inference bundle
- not a bundled football data service
## Feature Families
The current model artifact uses `48` numeric features.
### 1. Recent Scoring and Conceding
- recent average goals scored
- recent average goals conceded
- all-match context
- home-only or away-only context where appropriate
### 2. Recent Results Shape
- recent win rates
- recent draw rates
- recent goal-difference trends
### 3. Rest and Scheduling
- home rest days
- away rest days
### 4. Team Strength
- pre-match Elo values
- Elo difference
### 5. Team Identity Signals
- home team id
- away team id
### 6. Player Availability and Usage Aggregates
Aggregated over recent matches:
- minutes
- goals
- assists
- yellow cards
- red cards
- starter counts
- used-player counts
- injured-player counts
- suspended-player counts
### 7. Tactical and Staff Context
- home tactic id
- away tactic id
- home coach id
- away coach id
- tactic stability over recent matches
- tactic matchup encoding
## Exact Feature Columns
The model artifact currently expects these exact feature columns:
```text
home_avg_goals_last5_all
away_avg_goals_last5_all
home_avg_goals_last5_home
away_avg_goals_last5_away
home_avg_conceded_last5_all
away_avg_conceded_last5_all
home_avg_conceded_last5_home
away_avg_conceded_last5_away
home_win_rate_last10_all
away_win_rate_last10_all
home_win_rate_last10_home
away_win_rate_last10_away
home_draw_rate_last10
away_draw_rate_last10
home_goal_diff_last5
away_goal_diff_last5
home_rest_days
away_rest_days
home_elo_pre
away_elo_pre
elo_diff_pre
home_team_id
away_team_id
home_player_minutes_total_prev5
away_player_minutes_total_prev5
home_player_goals_total_prev5
away_player_goals_total_prev5
home_player_assists_total_prev5
away_player_assists_total_prev5
home_player_yellow_cards_total_prev5
away_player_yellow_cards_total_prev5
home_player_red_cards_total_prev5
away_player_red_cards_total_prev5
home_player_starters_count_prev5
away_player_starters_count_prev5
home_player_used_count_prev5
away_player_used_count_prev5
home_player_injured_count_prev5
away_player_injured_count_prev5
home_player_suspended_count_prev5
away_player_suspended_count_prev5
home_tactic_id
away_tactic_id
home_coach_id
away_coach_id
home_tactic_stability_last5
away_tactic_stability_last5
tactic_matchup_code
```
## Inference Flow
### Step 1: Validate Input
The predictor checks that every required feature exists and is numeric.
### Step 2: Sanitize Identifier-Like Fields
The inference path stabilizes:
- team ids
- coach ids
- tactic ids
This avoids malformed id-like values distorting predictions.
### Step 3: Predict Expected Goals
The home-goals and away-goals models produce expected goal values.
### Step 4: Predict Outcome Probabilities
The outcome model produces:
- home-win probability
- draw probability
- away-win probability
### Step 5: Apply Calibration
The probability distribution is temperature-calibrated.
### Step 6: Decode Final Score
The model uses Poisson-based score decoding to choose the final scoreline.
### Step 7: Compute Confidence
The response includes:
- `confidence_level`
- `confidence_score`
- `confidence_margin`
### Step 8: Optional Abstain Signal
If the match is fragile enough:
- `abstain_recommended = true`
- a score range is returned
## Reproducibility Note
This public release ships the same champion model artifact used by the public bundle, but exact outputs are still data-dependent.
In practice:
- same model + same feature row -> same prediction
- same model + different historical context -> potentially different prediction
That matters because `predict_match(...)` builds the feature row from historical input data before the model runs.
## Output Schema
Typical output fields:
```json
{
"model_version": "la_liga_score_predictor",
"model_type": "catboost_two_stage",
"expected_home_goals": 1.72,
"expected_away_goals": 0.94,
"predicted_home_goals": 2,
"predicted_away_goals": 1,
"predicted_score": "2-1",
"result_probabilities": {
"home_win": 0.54,
"draw": 0.25,
"away_win": 0.21
},
"confidence_level": "medium",
"confidence_score": 0.54,
"confidence_margin": 0.19,
"abstain_recommended": false
}
```
If abstain mode is triggered, output can also include:
```json
{
"predicted_score_range": {
"home_min": 1,
"home_max": 3,
"away_min": 0,
"away_max": 2
}
}
```
## Field Glossary
- `predicted_score`
- the final exact score chosen after expected-goal estimation, probability calibration, and score decoding
- `result_probabilities`
- calibrated `home_win`, `draw`, and `away_win` probabilities
- `raw_result_probabilities`
- the outcome probabilities before calibration
- `expected_home_goals`
- expected goals estimate for the home team
- `expected_away_goals`
- expected goals estimate for the away team
- `confidence_level`
- coarse confidence label: `high`, `medium`, or `low`
- `confidence_score`
- the highest calibrated outcome probability
- `confidence_margin`
- the gap between the top and second-highest calibrated outcome probabilities
- `abstain_recommended`
- flag indicating that the match is fragile enough to soften exact-score trust
- `predicted_score_range`
- optional score band returned when abstain mode is triggered
- `top_outcome`
- the strongest calibrated outcome class in the decoder diagnostics
- `top_outcome_probability`
- the probability of that strongest outcome class
- `second_outcome_probability`
- the probability of the runner-up outcome class
- `draw_probability`
- the calibrated draw probability
- `xg_delta`
- `expected_home_goals - expected_away_goals`
- useful for understanding which side carries the stronger expected scoring edge
- `close_call_draw_override`
- indicates a draw-favoring tie-break in a tightly balanced fixture
- `outcome_enforced`
- indicates that the outcome model was confident enough to force score direction
- `specialist_rule_triggered`
- indicates that an internal score adjustment rule ran
- `specialist_rule_name`
- the name of the triggered rule, if any
## Confidence Logic
The model exposes confidence for usability, not certainty.
Interpretation:
- `high`: clearer distribution separation
- `medium`: usable signal but not dominant
- `low`: fragile match, higher variance, score-range matters more
This is why public docs should explain:
- prediction is guidance
- not a guarantee
## Training and Selection Approach
The model was selected through offline evaluation and score-decoding guardrails.
Key ideas:
- no leakage from post-match information
- recent-window checks matter, not only full-history averages
- decode settings were selected to balance:
- exact score rate
- outcome accuracy
- total-goal error
From the current training report:
- selection method: `decode_sweep_no_retrain_recent_guardrails`
Current report snapshot:
- full-history exact: `0.2056`
- full-history outcome: `0.6177`
- recent-window exact: `0.1535`
- recent-window outcome: `0.5307`
These numbers are artifact-era selection metrics, not a promise for future live windows.
## Public Inference Requirements
For public use, inference needs only:
- the bundled model artifacts
- the three `.cbm` files referenced by them
- Python dependencies for CatBoost inference
- either:
- a compatible historical match CSV for `predict_match(...)`
- or one complete numeric feature row matching the required schema for `predict_features(...)`
It does not require:
- a live database
- a web server
- a scheduled pipeline
- any source-specific connector
## Public Inference Interfaces
The public package exposes four main inference methods.
### `predict_match(home_team, away_team, match_date)`
- builds features from a compatible historical match CSV
- best for normal application use
- returns the full response, including advanced fields and diagnostics
### `predict_match_simple(home_team, away_team, match_date)`
- builds features from a compatible historical match CSV
- best for lighter product integrations
- returns the smaller public response shape
### `predict_features(features)`
- expects the full numeric feature row
- best for advanced users managing engineered features directly
- returns the full response, including advanced fields and diagnostics
### `predict_features_simple(features)`
- expects the full numeric feature row
- best for advanced users who want a smaller public response shape
## Public Usage Example
The simplest public interface is:
```python
from la_liga_score_predictor import LaLigaScorePredictor
predictor = LaLigaScorePredictor.from_defaults(
dataset_csv_path="sample_history.csv"
)
prediction = predictor.predict_match(
home_team="Athletic",
away_team="Osasuna",
match_date="2026-04-21",
)
simple_prediction = predictor.predict_match_simple(
home_team="Athletic",
away_team="Osasuna",
match_date="2026-04-21",
)
```
Where:
- `predict_match()` is the easiest interface when you have a compatible history CSV
- `predict_match_simple()` is the lighter product-facing variant
- `predict_features()` is available for direct numeric feature rows
- `predict_features_simple()` is the lighter direct-feature variant
## Limitations
- The model is only as good as the input feature row.
- It is a pre-match model, not a live in-match model.
- It is league and feature-schema sensitive.
- It can miss chaotic or low-signal matches.
- Confidence is a helpful indicator, not certainty.
## What We Intentionally Exclude From the Public Technical Story
- source-provider implementation details
- private ingestion and refresh mechanics
- other internal model variants and experiment history
That keeps the public story clear:
- one champion model
- one inference path
- one reproducible public artifact
## Suggested Companion Files
This technical note works best alongside:
- `RELEASE_GUIDE.md`
- a public `README.md`
- a small `sample_history.csv`
- a simple `predict_one.py`
## Release Cadence Note
The public model artifact is planned to update twice per month.
For each public release, technical notes should be updated only if one of these changes:
- feature schema
- decode settings
- calibration behavior
- output contract
- artifact version