A decision intelligence system for managing player risk, performance and exposure under real-world football constraints.
Transforming predictive signals into optimal squad decisions through risk-aware optimization and multi-match planning.
This project implements a Decision Intelligence system designed to support football clubs in translating predictive signals into optimal squad-level decisions.
Unlike traditional analytics pipelines, this system does not stop at estimating:
- player performance
- injury risk
Instead, it answers the operational question:
Given all available information, what should we do?
The Football Decision Engine integrates:
- player value (performance contribution)
- availability risk (injury / exposure)
- squad-level constraints
- tactical structure
- match context across a planning horizon
to produce actionable, explainable and optimized decisions:
startlimit_minutesbench
These decisions are not made independently.
They are allocated through a global optimization process that ensures consistency across the entire squad, from player-level actions to formation-constrained lineups and multi-match exposure planning.
- End-to-end decision system (not just models)
- Config-driven MILP optimization layer
- Multi-match planning under congestion
- Interpretable outputs (
decision,reason,priority_score) - Modular architecture ready for extension (uncertainty, tactics)
In professional football environments:
- key players operate under injury risk
- match congestion forces trade-offs across games
- decisions must balance performance, availability and long-term exposure
However, most analytics systems stop at:
- estimating performance
- quantifying risk
They do not answer:
What is the optimal decision at squad level?
This project addresses that gap by formalizing decision-making as an optimization problem.
| Feature | Description |
|---|---|
| Decision Engine | Converts predictive signals into optimized squad decisions |
| Policy-driven | Fully configurable thresholds & rules |
| MILP Optimization | Globally optimal decision allocation |
| Risk-aware utility | Explicit trade-off between performance and availability |
| Explainability | Human-readable reasoning for each decision |
| Lineup Optimization | Formation-constrained starting XI |
| Multi-Match Planning | Horizon-aware exposure allocation under congestion |
| Config-driven MILP | Fully parameterized optimization layer (no hardcoded logic) |
| Layer | Tech |
|---|---|
| Language | Python |
| Data | pandas |
| Optimization | PuLP (MILP), SciPy |
| Config | JSON |
| Architecture | Modular / production-style |
- π§ System Design
- π Documentation
- π Case Study
- π― Demo
- β‘ Quick Start
- π§ Project Objective
- β½ Real-world Use Case (Matchday Scenario)
- π Notebooks (Progressive Demonstrations)
- π’ V0.8 β Multi-Match Planning
- π System Architecture
- β Decision Flow
- π§© Component Responsibilities
- π Project Structure
- π₯ Input Output
- β Limitations
- π Future Improvements
- π― Why This Project
- π€ Author
- π License
- System Design β high-level decision intelligence framework
- System Architecture
- Decision Logic
- Optimization Layer
- Multi-Match Planning
A realistic match congestion scenario showing how the system supports squad-level decision-making:
π Read full case study π View slide case study
The following examples illustrate how the system evolves from player-level evaluation to full squad planning under realistic constraints.
Players are evaluated based on:
risk_scorevalue_score
This defines the initial decision policy:
startlimit_minutesbench
The system builds an optimal XI considering:
- formation constraints (4-3-3)
- positional eligibility
- player utility
- risk management
Across multiple matches, the system:
- allocates player exposure
- manages fatigue accumulation
- rotates squad intelligently
- adapts to match importance
The result is not just a lineup, but a planning strategy across matches.
git clone https://github.com/manuelpeba/football-decision-engine.git
cd football-decision-enginepython -m venv .venv
source .venv/bin/activate # macOS / Linux
.venv\Scripts\activate # Windowspip install -r requirements.txtStart with:
jupyter notebookRun in order:
01_decision_boundary_elite.ipynb02_matchday_simulation_elite.ipynb03_lineup_optimization_elite.ipynb04_multi_match_planning_elite.ipynb
PYTHONPATH=src python run.py- Player-level decision logic
- Matchday simulation
- Optimized starting XI
- Multi-match exposure planning
- Fatigue-aware squad management
Move from:
Prediction β Decision
Instead of building isolated models, this project focuses on:
- decision systems
- trade-off modeling
- optimization under constraints
A club is preparing for a high-intensity match with:
- a key attacker with high injury risk
- several rotation players
- limited starting slots
- match congestion in upcoming fixtures
The staff must decide:
- who starts
- who is protected
- how to manage exposure
The engine evaluates each player using:
risk_scorevalue_score
and produces decisions such as:
| Player Profile | Decision |
|---|---|
| High value + high risk | limit_minutes |
| High value + low risk | start |
| Low value | bench |
All decisions are optimized jointly, not individually.
The project includes a set of notebooks that illustrate the evolution of the system from simple decision rules to horizon-aware planning:
| Notebook | Focus |
|---|---|
01_decision_boundary_elite.ipynb |
Risk vs value decision space |
02_matchday_simulation_elite.ipynb |
Policy-based matchday decisions |
03_lineup_optimization_elite.ipynb |
Formation-constrained optimization |
04_multi_match_planning_elite.ipynb |
Multi-match planning under congestion |
These notebooks are not independent analyses, but progressive layers of the same decision system.
The system has been extended from single-match optimization to multi-match planning under congestion.
Instead of optimizing decisions in isolation, the engine now allocates player exposure across a sequence of matches with different:
- match importance
- opponent strength
- recovery windows
Move from:
Match-level optimization β Horizon-level planning
The system decides:
- who starts each match
- who is protected (
limit_minutes) - who is benched strategically
- how fatigue evolves across the sequence
Each player is assigned one of:
| Decision | Meaning |
|---|---|
start |
Full exposure |
limit_minutes |
Controlled load |
bench |
No exposure |
These decisions are optimized jointly across matches, not independently.
The system learns structurally different strategies per unit:
- Goalkeeper β deterministic (fixed starter)
- Defence β stability (binary decisions)
- Midfield β load balancing (frequent partial exposure)
- Attack β risk-managed allocation (rotation + protection)
Across a three-match horizon:
- core players maintain consistent exposure
- high-risk attackers are selectively protected
- lower-priority matches absorb rotation
- fatigue accumulates and influences later decisions
The project now follows a clear progression:
Prediction β Policy β Matchday Optimization β Multi-Match Planning
This final layer transforms the system into a Football Decision Intelligence Engine.
flowchart LR
A[Input Data] --> B[Decision Logic]
B --> C[Initial Decisions]
C --> D[MILP Optimization]
D --> E[Final Decisions]
E --> F[Planning Layer]
This architecture ensures a clear separation between:
- policy definition (how players are evaluated)
- decision logic (how actions are derived)
- optimization layer (how decisions are allocated globally)
This mirrors real-world football decision workflows across performance, medical and coaching staff.
flowchart TD
A[risk_score + value_score] --> B[Policy Rules]
B --> C[Initial Decision]
C --> D[Utility Computation]
D --> E[Optimization]
E --> F[Formation-Constrained Lineup]
F --> G[Multi-Match Planning]
G --> H[Final Output]
| Component | Responsibility |
|---|---|
engine.py |
Orchestration |
decision.py |
Rule-based classification |
policies.py |
Config validation |
constraints.py |
Squad constraints |
optimizer_milp.py |
Global optimization |
notebooks/ |
Progressive demonstrations of the system |
docs/ |
Technical and conceptual documentation |
assets/demo/ |
README demo visuals |
assets/
βββ demo/
βββ decision_space.png
βββ optimized_lineup_M1.png
βββ multi_match_planning.png
βββ case_study/
βββ case_study_slide.pptx
docs/
βββ system_design.md
βββ architecture.md
βββ decision_logic.md
βββ optimization.md
βββ multi_match_planning.md
βββ case_study.md
notebooks/
βββ README.md
βββ 01_decision_boundary_elite.ipynb
βββ 02_matchday_simulation_elite.ipynb
βββ 03_lineup_optimization_elite.ipynb
βββ 04_multi_match_planning_elite.ipynb
src/
βββ football_decision_engine/
βββ __init__.py
βββ engine.py
βββ decision.py
βββ policies.py
βββ constraints.py
βββ optimizer.py
βββ optimizer_milp.py
βββ planning.py
βββ schemas.py
βββ utils.py
tests/
βββ test_decision.py
βββ test_engine.py
βββ test_optimizer_milp.py
βββ test_policy_validation.py
run.py| Column | Description |
|---|---|
player_id |
Player identifier |
risk_score |
Injury / availability risk |
value_score |
Expected contribution |
| Column | Description |
|---|---|
decision |
start / limit_minutes / bench |
reason |
Explanation |
priority_score |
Utility |
The current version already includes:
- match context (importance, opponent)
- tactical constraints
- fatigue/load planning
- horizon-aware exposure allocation
Current limitations remain:
- no uncertainty layer over player availability
- no probabilistic scenario planning
- no opponent-specific tactical adaptation by role
- no robust optimization under multiple recovery scenarios
- static utility parameters calibrated manually
| Version | Feature |
|---|---|
| v1.0 | Config-driven decision engine with MILP optimization |
| v1.1 | Scenario-based planning under uncertainty |
| v1.2 | Opponent-aware tactical adaptation |
| v1.3 | Robust optimization across availability scenarios |
Most football analytics projects focus on:
- prediction
- dashboards
- ranking players
This project focuses on:
decision-making under constraints
It demonstrates the ability to:
- design systems (not just models)
- formalize trade-offs
- apply optimization to real problems
This project demonstrates a shift in football analytics:
From:
- predictive models
- player rankings
- dashboards
To:
- decision systems
- constrained optimization
- actionable outputs
This project reflects a shift towards how elite football organizations structure decision-making internally: combining data, constraints and optimization into coherent operational systems.
Manuel PΓ©rez BaΓ±uls
Data Scientist building decision systems for football | Risk, Value & Optimization
Specializing in:
- Sports analytics and forecasting
- Probabilistic simulation systems
- Machine learning for football prediction
- Production-ready data pipelines
π§ manuelpeba@gmail.com
MIT License


