From Bioreactors to Brier Scores: Building Model90, a Football Prediction Engine

By | July 5, 2026


By day I build models of what is happening inside bioreactors: soft sensors, state estimators, the whole Bayesian apparatus for inferring quantities you cannot measure directly. Model90 is what happened when I pointed that same toolkit at something with a much crueller test set. Football.

Thank you for reading this post, don't forget to subscribe!

The result lives at model90.app. It is a statistical forecasting engine for the FIFA World Cup 2026, plus the major domestic leagues and the UEFA competitions, and it refreshes its numbers every thirty minutes as new data arrives. Before anything else, the boring but important part: this is a probability model built for curiosity and entertainment. It is not betting advice, it carries an 18+ label, and there is a responsible gambling page for a reason. Probabilities are not promises.

Why football, and why now

A World Cup is a rare gift to anyone who models uncertainty for a living: a dense, high-stakes, well-documented stream of events that arrives on a fixed schedule and then tells you, brutally and in public, whether your numbers were any good. You cannot argue with a full-time whistle. That feedback loop is the thing I actually wanted.

How the engine works

Under the hood, Model90 is an eight-stage pipeline rather than a single clever trick. Raw match data flows through a chain of model layers, each contributing a different view of the same question, and a final layer decides how much to trust each one.

  • Dixon-Coles bivariate Poisson. Every team carries an attack strength and a defense weakness, fitted by weighted maximum likelihood, with a home-advantage term and a low-score correction that fixes the well-known Poisson mis-calibration on results like 0-0 and 1-1. Recent matches count for more: the fit uses temporal decay, so last month matters more than last year.
  • An Elo edge. A dynamic team-strength rating updated after every result, following the FIFA convention with a goal-difference multiplier and a home offset, then converted into home, draw and away probabilities through an empirical draw model.
  • An expected-goals layer. Shots on target are turned into xG and run through a parallel Poisson model, blended in at thirty percent weight when the data exists, with a graceful fall back to a goals-only model when it does not.
  • Six contextual signals. Form, squad, altitude and the rest: the adjustments a pure goals model is blind to.
  • An ensemble blend and a meta-model. The component models are combined, then a logistic-regression stacking layer learns how much weight each one has earned, and the output is calibrated so that a stated 70 percent actually behaves like 70 percent over the long run.

Being honest about the numbers

Here is the part most prediction sites quietly skip. On the first 24 group-stage matches of the World Cup, the engine called 54 percent correctly and posted a Brier score of 0.193, against a random-guess baseline of 0.222, which it logs as roughly 38 percent better than chance.

Fifty-four percent might sound modest if you were expecting an oracle. It should. Football is a low-scoring, high-variance sport where the better side loses often enough to keep the neutrals watching, and any model claiming 80 percent hit rates on match outcomes is either overfit or lying. The metric I actually care about is the Brier score, because it grades the calibration of the probabilities, not just whether the single most likely outcome happened to land. A model that says “55 percent home win” and is right 55 percent of the time is doing its job, even when it is technically “wrong” on any given Saturday.

The engine is also honest about its own ignorance. Early in a competition, or deep in the qualifying rounds where teams have barely played, matches are flagged with low confidence and a “limited data” note, and the confidence map shows where the model is speaking from evidence versus where it is essentially shrugging politely.

Where the model disagrees with the market

One feature I find genuinely interesting is the value flag. Model90 compares its own probability for an outcome against the probability implied by bookmaker odds and highlights the cases where the two disagree by a wide margin. To be clear about what that is and is not: it is a disagreement between two estimates of the same unknown, nothing more. Sometimes the model has spotted something the market has been slow to price. Sometimes the market knows about an injury the model has not ingested yet. It is a conversation starter, not a tip.

The bioprocess connection I did not expect

What surprised me is how little I had to change my thinking. Forecasting a match turns out to be the same shape of problem as soft-sensing a bioreactor: you have a latent state you cannot observe, a handful of noisy and partial measurements, and a need to update your beliefs as fresh data arrives without overreacting to every wobble. Swap glucose and viable cell density for form and expected goals, and the machinery is remarkably familiar. A football match, if you squint, is just a very poorly instrumented bioreactor with twenty-two actuators that flatly ignore your setpoints.

Under the bonnet, and where to poke around

Model90 is a Next.js application fed by live data from API-Football, with the engine recomputing on a thirty-minute cadence. If you would rather explore than read, the knockout bracket and trophy race project the tournament forward, the research notes document the methodology, the changelog tracks how the model has evolved, and there is an API if you want to consume the numbers programmatically.

It is, like most of what I build in my own time, a working excuse to learn something. The World Cup just happens to be a spectacular dataset with a global audience keeping score. If you want to see what the model thinks about tonight, start at model90.app. And when it calls a result wrong, which it will, that is precisely what the Brier score is there to measure.


Model90 provides probability-driven statistical forecasts for informational and entertainment purposes only. Nothing on it constitutes financial, betting or gambling advice. 18+. If gambling is causing you harm, support is available via BeGambleAware.

Find me elsewhere: GitHub · LinkedIn · X · Website · Contact