Football Intelligence Copilot
From raw event data to a new way of measuring the game.
Building an xG model, an Expected Threat model, and an experimental predictability metric borrowed from language modeling — and the bugs, debugging, and dead ends along the way.
Why this project
Football clubs sit on an enormous amount of data and, like a lot of data-rich organisations, don't always have the tooling to turn it into decisions. I wanted to build that pipeline end to end, myself, on real data — not to replicate what StatsBomb or Opta already sell clubs, but to actually go through the process: pull raw event data, turn it into models, validate those models properly, and be honest about where they break.
It also gave me a reason to combine three things I care about separately: machine learning, football, and — by the end, somewhat unexpectedly — natural language processing. That last one wasn't part of the plan. It showed up because football, looked at the right way, is played sequentially, the same way language is written sequentially. More on that later.
Read it topic by topic
The Data
Five StatsBomb open-data leagues, a normalization layer, and the schema rule that kept it from sprawling.
Expected Goals
A logistic regression on shot geometry and context — and a bug that hid behind three suspiciously exact zeros.
Expected Threat
Valuing every action, not just shots, with an iterative PageRank-style model — and wiring it into a real API.
Surprisal
An experimental predictability metric borrowed from language modeling, three sparsity bugs, and nine honest limitations.
What's Next
Where the project goes from here, and attribution for the underlying data.