Tennis Live Analytics
A real-time data and ML project that estimates each player's chance of winning live tennis matches, evaluated with paper trading.
Role: Project design and development
- Python
- Machine Learning
- JSON
- CLI
Problem
A tennis match changes point by point, and with every point the probability that each player wins the set and the match changes too. Following that by hand is impossible, and doing it well takes two things at once: data that arrives in real time and a model that can turn it into a believable probability.
What makes it interesting as an engineering problem is that it has an objective judge. A well-calibrated probability can be measured: if the model says 70% in a hundred similar situations, it should be right about seventy times. That lets me evaluate the work with numbers instead of impressions.
Solution and key features
Tennis Live Analytics is a real-time data and machine learning experiment. It reads the score of live matches, estimates the probability of winning the set and the match, and keeps a log of every signal so it can be analyzed later. It is written in Python and driven from the command line. It is not a published product and has no public demo.
These are its main pieces:
- Live score reading through adapters, one per data source, that convert it to a common format.
- A per-set logistic model, combined with an Elo rating for each player, to estimate the probability at every moment.
- A signal engine that gathers the estimates and the rules, and writes every decision to a JSONL log.
- A backtest over historical matches and a calibration report with the Brier score, which measures how close the probabilities are to what really happened.
- Evaluation with paper trading: everything is recorded in a simulated way to compare what the system decides with what happens.
- Latency targets to watch many matches at once and react to a score change within a few seconds.
How I work on it
The project moves in short cycles. First I measure, with the backtest and the calibration, how well a rule or a model works on my own data. Then I review a report with proposed changes and their sample size, and only then do I approve what goes in. That order keeps a good or bad streak from pushing me into impulsive decisions.
I also make sure every stage can be measured on its own: data reading, signal and log. If latency goes up, I want to know exactly where the time is lost, not just that something is slow.
I describe it as what it is: a personal experiment, useful for learning and for showing how I approach a data problem with rigor. I do not present it as a business or promise results. What I can show is the method: live data, a simple and explainable model, honest measurement and decisions that can be justified.
Architecture
Simplified diagram; internal details omitted for privacy.
- Adapters convert every data source into one common match format.
- The engine combines the per-set model with Elo and writes every signal to a JSONL log.
- That log drives the backtest, the calibration and the paper trading evaluation.
Technical decisions
One adapter per data source, all feeding a single match format.
- Why
- Every source delivers the score in its own shape. If the signal engine only knows one common format, switching sources or adding another does not touch the model logic.
- Trade-off
- A translation layer has to be written and maintained per source, and any data that does not fit the common format is lost or gets complicated.
Rule changes are proposed in a report and I approve them before they are applied.
- Why
- Tuning rules by looking at recent results almost always leads to overfitting: the rule works on the past and fails on new data. Asking for a proposal with its sample size forces a check on whether the evidence is enough.
- Trade-off
- Iterating is slower than letting the system tune itself, in exchange for every change being justified and reversible.
The model is exported to a plain JSON file and inference runs without machine learning libraries.
- Why
- In a live setting latency and simplicity matter. With the coefficients in JSON, predicting is a weighted sum that runs in microseconds with no heavy dependencies.
- Trade-off
- Only simple models fit, such as a logistic one. Trying a more complex architecture would mean changing how it is executed.
Gallery
My role
I design and build it on my own as a personal experiment: from reading the live score to the model, the backtest and the calibration reports. I use it to practice data engineering and machine learning on a problem that changes every second.