World-Cup-2026

Machine learning pipeline that forecasts the probability of each team winning the 2026 FIFA World Cup using ~49K real international matches (1872-2026) and Monte Carlo bracket simulation.

0
0
0
Jupyter Notebook
public

World Cup 2026 Champion Forecaster βš½πŸ†

A machine learning pipeline that forecasts the probability of each remaining team winning the 2026 FIFA World Cup, using ~49,000 real international football matches played between 1872 and 2026.


Overview

This project uses real historical match data to:

  1. Compute running Elo ratings for every national team, updated match-by-match through the present day.
  2. Engineer match-level features β€” Elo difference, recent form, head-to-head history, rest days, and neutral-venue flag β€” using only information available before each match (no data leakage).
  3. Train a calibrated Gradient Boosting classifier to predict Home / Draw / Away outcomes, with isotonic probability calibration (essential for feeding probabilities into a Monte Carlo simulation).
  4. Validate the model using a time-based split (train on the past, test on the most recent slice), reporting log loss and Brier score.
  5. Monte Carlo-simulate the live knockout bracket (50,000 tournaments) to estimate P(champion) for each of the 16 teams still alive.

Data Source

File Description
international_results.csv ~49,000 international matches (1872–2026), sourced from martj42/international_results β€” a widely-used mirror of the Kaggle dataset β€œInternational football results from 1872 to 2026”.

The dataset already includes the 2026 World Cup fixtures. As of the current run, two Round-of-16 matches have been played and are treated as hard results:

Date Match Score
2026-07-04 France vs Paraguay 1–0
2026-07-04 Morocco vs Canada 3–0

The remaining six R16 matches and the entire knockout tree (QF β†’ SF β†’ Final) are forecast by the model.


Why Gradient Boosting?

Tabular data with tens of thousands of rows is the sweet spot for tree-based ensemble methods. Deep learning offers no advantage here without event-level tracking data (player positions, possession chains, etc.). Gradient Boosting is fast, interpretable, handles mixed feature types well, and β€” with isotonic calibration β€” produces the reliable probability estimates needed for bracket simulation.


Project Structure

.
β”œβ”€β”€ world_cup_forecast.py              # Main forecasting pipeline (5 steps)
β”œβ”€β”€ world_cup_forecast_analysis.ipynb  # Jupyter notebook with full analysis & visualizations
β”œβ”€β”€ international_results.csv          # Raw match data (~49K matches, 1872–2026)
β”œβ”€β”€ .gitignore
└── README.md

Requirements

Install dependencies:

pip install numpy pandas scikit-learn

Quick Start

# 1. Clone the repository
git clone https://github.com/andresveraf/World-Cup-2026.git
cd World-Cup-2026

# 2. (Optional) Create a virtual environment
python3 -m venv venv
source venv/bin/activate

# 3. Install dependencies
pip install numpy pandas scikit-learn

# 4. Run the forecaster
python world_cup_forecast.py

The script will print:

  • Model validation metrics (log loss, Brier score)
  • Current Elo ratings for the 16 teams still alive
  • A ranked table of champion probabilities from 50,000 Monte Carlo simulations

Pipeline Details

Step What it does
1. Load data Parses international_results.csv, separates played matches from upcoming fixtures
2. Feature engineering Builds Elo diff, form (last 10 matches), H2H win rate, rest days, neutral flag β€” all leak-free
3. Train + calibrate Gradient Boosting (250 trees) wrapped in CalibratedClassifierCV (isotonic, 3-fold)
4. Validate Time-based 90/10 split; reports log loss and Brier score
5. Monte Carlo Precomputes pairwise win probabilities, then simulates 50,000 complete tournaments through the real live bracket

Notes

  • Host nations (USA, Mexico, Canada) receive a small Elo bonus (+30) even at neutral venues to account for crowd support.
  • Knockout-stage draws are resolved via a penalty-shootout model: a near coin-flip nudged by the Elo difference between the two teams.
  • The random seed is fixed (42) for reproducibility.

License

This project is for educational and analytical purposes. The match data is sourced from the public martj42/international_results dataset.

v0.3.3[beta]