Skip to content
All projects

Tennis match prediction

My first model was 90% accurate. That was the problem.

Tools
Python, SQL, XGBoost, Streamlit
Timeline
Aug 2026 to now
Status
Ongoing

The problem

I wanted to know which stats actually decide a tennis match, and whether a model could call the winner before the first serve. I had written code in classes but had never built my own model.

What I did

  • Pulled more than 73,000 ATP matches going back to 2000 out of large match databases with SQL.
  • Built features from serve stats, break-point conversion, surface history and recent form, then trained an XGBoost model on them.
  • Tested it on whole seasons the model had never seen, not a random split, because that is how it would be used.
  • Filled the gaps with Coursera, YouTube, research papers on sports prediction, and a lot of watching real matches.

Result

Version one scored over 90%. It was cheating: some features were stats that only exist after a match ends.

Rebuilt on pre-match information only, the model is right 68% of the time on held-out seasons. Most of that comes from matches with a clear favorite, so the real work now is the close, 50/50 matches.

What I learned

  • A great accuracy number is a reason to check your data, not to celebrate.
  • Always compare against a simple baseline, like picking the higher-ranked player.
  • Validate a model the way it will actually be used.