2025–2026 · Live
Predictorous
Football analytics and match predictor: data pipeline, probability model and 3D dashboard for the top five European leagues
A system that turns raw football data into calibrated match-outcome probabilities, publishes them before kickoff, and grades itself afterwards. It ingests fixtures, results, xG and event data for the top five European leagues, rates teams, predicts every match, and shows the reasoning on a dashboard with a 3D pitch. The rule throughout: nothing ships unless it beats the baseline on a frozen out-of-sample season.
Role
Solo developer — data engineering, statistical model, backtesting, API, dashboard, deployment.
Outcome
Model validated on a frozen out-of-sample season; predictions published daily; live at predictorous.com.
Links
What I built
- Ingestion pipeline in Python: fixtures and results from fbref, per-match xG from Understat, and shot and pass event streams, for five leagues across multiple seasons. Incremental scrapes with rate-limit handling, date-stamped snapshots, everything as parquet and JSON on disk with no database.
- Model: decay-weighted xG strength ratings feed a Poisson score grid with per-league home advantage; a logistic draw classifier trained on eleven seasons and about 17,000 matches unifies the probabilities. A nine-zone territory layer built from shot events explains each prediction.
- Validation discipline: walk-forward backtests on frozen seasons, calibration reports, and a rejected-experiments log. Several plausible upgrades were tested and dropped because they did not improve out-of-sample results. Top-ranked draw predictions hit 28.9% against a 24.8% base rate; high-confidence favorites land at 65 to 67% across three samples.
- Append-only ledger: every prediction is written before kickoff and graded automatically against the final score and real xG. A scheduled daily run scrapes, rates, predicts and grades end to end.
- FastAPI backend exposing leagues, players, fixtures, predictions and plots; Jinja admin pages restricted to localhost.
- Next.js dashboard exported statically and deployed to Cloudflare Pages: predictor table, team pages with pass networks and shot maps, head-to-head view, ratings, history, and a React Three Fiber 3D pitch with formation and territory views.
Architecture
Sources
fbref
fixtures · results · squads
Understat
per-match xG
Event streams
shots · passes
Pipeline
Incremental scrapers
rate-limited · snapshot archive
Ratings builders
xG strength · Elo · zones
Daily run
scrape → rate → predict → grade
Model
Poisson score grid
per-league home advantage
Draw classifier
logistic · 11 seasons
Walk-forward backtests
frozen seasons · calibration
Output
Prediction ledger
append-only · auto-graded
FastAPI
JSON export for the web
Static dashboard
Next.js · 3D pitch · Cloudflare
- →Every prediction is committed to the ledger before kickoff; the next daily run grades it. Nothing is edited after the fact.
- →The dashboard is a static export of the ledger and derived metrics, so the scrapers, raw data and credentials never leave the machine.
Stack
- Data & model
- Python · pandas · numpy · scipy · soccerdata · matplotlib / mplsoccer
- Backend
- FastAPI · Pydantic · Jinja · scheduled daily run
- Frontend
- Next.js (static export) · TypeScript · React Three Fiber · Tailwind CSS
- Hosting
- Cloudflare Pages · Docker
Screens
hover to scroll · click to enlarge