Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

Martin Eastwood

@martineastwood.co.uk
2K followers 120 following 62 posts

Somewhere in the middle of a Venn diagram of machine learning and football / soccer. www.pena.lt/y/blog.html

PostsRepliesMedia
Martin Eastwood @martineastwood.co.uk · 09/06/2026
Get started with: pip install -U penaltyblog Read the full release notes and documentation: penaltyblog.readthedocs.io/en/latest/ As always, feedback, bug reports, PRs and feature requests are welcome.
penaltyblog.readthedocs.io
penaltyblog: Football Data & Modelling Made Easy — penaltyblog documentation
031 3
Martin Eastwood @martineastwood.co.uk · 09/06/2026
🚀 penaltyblog v1.11.0 is out. This release adds: ⚡ predict_many() for fast batch forecasting 🏟️ Neutral venue support 📈 A bundled pre-trained xT model 🚄 ~4× faster Weibull Copula fitting 🤖 Context7 MCP documentation support
151 5
Martin Eastwood @martineastwood.co.uk · 27/03/2026
Looking forward to the Field Of Play Conference today. If you’re there as well then come over and say hi 👋
020 2
Martin Eastwood @martineastwood.co.uk · 28/02/2026
🚀 penaltyblog v1.9.0 is live! 🐍⚽️ New in this version: ✅ create_dixon_coles_grid(): Use lambdas from external ML models. ✅ goal_expectancy_extended(): Infer rho/lambdas from odds. 🛠️ Improved quarter lines (2.25/2.75) logic for totals market. ⚡️ More optimisations to FootballProbabilityGrid
A Python code snippet demonstrating the new 'create_dixon_coles_grid' function in the penaltyblog library. The code shows how to initialize a probability grid using expected goals (lambdas) for the home and away teams, and then calculate home win probabilities, over/under 2.5 goal totals, and Asian Handicaps directly from that grid.
090 9
Martin Eastwood @martineastwood.co.uk · 08/01/2026
Everything you need to get started is right here: pip install penaltyblog --upgrade 💻 Repo: github.com/martineastwo... 📖 Docs: penaltyblog.readthedocs.io 📦 PyPI: pypi.org/project/pena...
github.com
GitHub - martineastwood/penaltyblog: ⚽ High-performance football analytics toolkit: build data pipelines, scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀
⚽ High-performance football analytics toolkit: build data pipelines, scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀 - martineastwood/penaltyblog
020 2
Martin Eastwood @martineastwood.co.uk · 08/01/2026
Why build a custom MCMC sampler from scratch? In my latest blog post, I dig into the "why" and the "how". From the decision to drop heavy dependencies like Stan for this use case, to using Cython for speed, and how to interpret those "fuzzy caterpillar" plots. Read it here: pena.lt/y/2026/01/08...
A technical MCMC Trace Plot with two horizontal subplots labeled "attack_Arsenal" and "home_advantage." Each plot shows four overlapping colored lines (Chains 0 to 3) creating a dense, horizontal "fuzzy caterpillar" shape. This visualization indicates that the Bayesian model has successfully converged and is stable across 2,000 iterations.
120 2
Martin Eastwood @martineastwood.co.uk · 08/01/2026
What can you do with v1.8.0? ✅ Bayesian Dixon-Coles: Quantify uncertainty, not just point estimates ✅ Hierarchical Models: Learn league-wide variance to handle small sample sizes ✅ Built-in trace plots: Ensure model convergence ✅ Familiar API: Works seamlessly with existing scrapers and weights
110 1
Martin Eastwood @martineastwood.co.uk · 08/01/2026
Bayesian goal models are back in penaltyblog v1.8.0 - and this time, they’re dependency-free! ⚽️📈
A dark-themed code editor window showing Python code using the penaltyblog library. It demonstrates initializing a HierarchicalBayesianGoalModel with home/away goals and teams, fitting the model using MCMC sampling with parameters like 2000 samples and 4 chains, and finally predicting match probabilities for an Arsenal vs. Manchester City fixture
1133 13
Martin Eastwood @martineastwood.co.uk · 29/12/2025
⚽ penaltyblog v1.7.1 is now available: Added params_array and param_indices functions to goal models to make it easier to work with the model's parameters. Thank you to Sebastian Velandia for this contribution! pip install --upgrade penaltyblog
010 1
Martin Eastwood @martineastwood.co.uk · 09/12/2025
📝 A couple of important notes: You'll need your own Opta subscription/credentials to use this (I provide the tools, not the data!) 🔑 As this is a v1 release of the integration, there's likely some rough edges. If you run into any, let me know - I'm happy to work with you to improve it. 🤝
000 0
Martin Eastwood @martineastwood.co.uk · 09/12/2025
⚽ penaltyblog v1.7.0 is now available: Direct integration with the Opta (Stats Perform) API. You can now stream matches & events lazily without downloading the JSON first. Includes helpers for human-readable filtering (no more memorising IDs). pip install --upgrade penaltyblog
Code example showing how the penaltyblog python package can now integrate directly with the StatsPerform Opta API to download data directly.
160 6
Martin Eastwood @martineastwood.co.uk · 04/12/2025
Have been doing Advent of Code in Nim and Kotlin this year and enjoying learning both. I can see Nim becoming one of my favourite languages!
010 1
Martin Eastwood @martineastwood.co.uk · 24/10/2025
Thanks Nils, it’s a good point and is on my todo list to dig further into how long it takes for something like FSAA to stabilise to something useful early on in a player’s career. Even with a fairly wide HDI at that stage, there’s still potentially benefits to its use
010 1
Martin Eastwood @martineastwood.co.uk · 20/10/2025
Not yet, but good idea!
010 1
Martin Eastwood @martineastwood.co.uk · 20/10/2025
New article: "Shrinkage, Uncertainty, and Son Heung-min: Using Bayesian Methods to Identify Finishing Ability" which discusses using a Bayesian hierarchical approach to quantifying player finishing ability, with credible intervals to express uncertainty. pena.lt/y/2025/10/01...
pena.lt
Shrinkage, Uncertainty, and Son Heung-min: Using Bayesian Methods to Identify Finishing Ability
Why most finishing metrics are flawed and how a Bayesian approach gives us a truer picture of a player's finishing ability...
3235 23
Martin Eastwood @martineastwood.co.uk · 17/10/2025
🎉 penaltyblog v1.6.1 is out! ✨ What's new: - Python 3.14 support - scipy 1.16+ compatibility - Better numerical stability for Negative Binomial model - New Colab notebook for implied probabilities example pip install --upgrade penaltyblog
043 4
Martin Eastwood @martineastwood.co.uk · 07/10/2025
Absolutely. Also, people started sharing big (for then anyway) pre-trained networks that made it much easier to get started. I built many models in my day job back then by fine tuning BERT and ImageNet that I would have struggled to train from scratch without investing massively in compute.
000 0
Martin Eastwood @martineastwood.co.uk · 07/10/2025
We can also split Massey Ratings into attack & defence: 🔴 LFC: best attack in the league paired with a mid-table defence ⚪️ ARS: Elite at both ends. They have the #1 defence and the #3 attack 🌳 Forest: A disaster at both ends of the pitch
0101 10
Martin Eastwood @martineastwood.co.uk · 07/10/2025
Here's how the Premier League table really looks according to Massey Ratings, which account for strength of schedule. 📈 Arsenal (+1.5) & Man City (+1.3) are clear strongest overall 😬 Man Utd (-0.2) rank in the bottom half 📉 West Ham & Forest (-1.2) are worst teams by far
Massey Ratings for the English Premier League
3144 14
Martin Eastwood @martineastwood.co.uk · 23/09/2025
Thanks to everyone who suggested features and reported issues. Your input shapes the package's development. Questions or feedback welcome at pena.lt/y/contact Install: pip install penaltyblog GitHub: github.com/martineastwo...
000 0
Martin Eastwood @martineastwood.co.uk · 23/09/2025
📚 Interactive Colab notebooks are available in the docs - experiment with real examples without any local setup. I'll be steadily expanding these over the coming weeks to cover all functionality in the package. Docs: penaltyblog.readthedocs.io
penaltyblog.readthedocs.io
penaltyblog: Football Data & Modelling Made Easy — penaltyblog documentation
100 1
Martin Eastwood @martineastwood.co.uk · 23/09/2025
🔧 Improved implied odds module: - New logarithmic overround removal method for better accuracy - Structured results instead of raw arrays - Better handling of edge cases Making it easier to work with bookmaker probabilities in your analyses.
100 1
Martin Eastwood @martineastwood.co.uk · 23/09/2025
💰 Expanded betting utilities: - Kelly Criterion for multiple outcomes - Arbitrage opportunity detection - Value bet identification - Hedge bet calculations - Odds format conversion (decimal/fractional/American) All functions now return structured outputs for easier integration.
100 1
Martin Eastwood @martineastwood.co.uk · 23/09/2025
⚽ penaltyblog v1.6.0 is now available! 📊 MatchFlow updates: - SQL-style joins for nested football data (left, right, outer, inner, anti) - Cloud storage support: read/write directly to AWS S3, Google Cloud Storage, and Azure Blob - Automatic type inference for join keys pip install penaltyblog
110 1
Martin Eastwood @martineastwood.co.uk · 18/08/2025
🚀 New article on my blog walking through the latest updates to the penaltyblog python package for football (soccer) analytics & betting ✅ New interactive pitch plots ✅ 5-10× faster goal models ✅ New Flow query DSL 👉 pena.lt/y/2025/08/14...
pena.lt
Penaltyblog v1.5.0: Faster Models, Smarter Queries, and a Sharper Edge
v1.5.0 delivers interactive charts, faster models, upgraded football probability grid, and a powerful Flow query language - all designed to make your analysis sharper and quicker...
050 5
Martin Eastwood @martineastwood.co.uk · 15/08/2025
📚 Docs: penaltyblog.readthedocs.io/en/latest/in... 💻 GitHub: github.com/martineastwo... 🐍 pip install penaltyblog Feedback welcome, let me know what you build!
penaltyblog.readthedocs.io
penaltyblog: Football Data & Modelling Made Easy — penaltyblog documentation
010 1
Martin Eastwood @martineastwood.co.uk · 15/08/2025
🔍 New: Flow Query DSL Filter datasets with safe, Pythonic expressions: - AST-parsed (no eval) - Variables, regex, dates - Access nested fields
Image of code showing examples of penaltyblog Flow's new DSL
100 1
Martin Eastwood @martineastwood.co.uk · 15/08/2025
📈 Goal models are now 5-10× faster - Cython-powered analytical gradients for speed + stability - Fine-tune with minimizer_options:
Image of code demonstrating the the features in penaltyblog's goals models
110 1
Martin Eastwood @martineastwood.co.uk · 15/08/2025
⚽ New: Pitch Plotting API Build interactive football visualisations with: - Multiple layouts & themes - Scatter, heatmaps, arrows, comets - Custom hover tooltips
GIF demonstrating the interactive tooltips in penaltyblog's new Pitch plotting API
100 1
Martin Eastwood @martineastwood.co.uk · 15/08/2025
🚀 penaltyblog v1.5.0 is here! ✅ Interactive pitch plots ✅ 5-10× faster goal models ✅ New Flow query DSL What’s new 👇
142 4
Martin Eastwood @martineastwood.co.uk · 16/07/2025
📊 New article on my blog: How Accurate Are Soccer Odds? A Data Dive into 250 Million Betting Lines 🔍 How sharp are different bookmakers? 📈 How accurate are bookmaker's odds? 🎯 Are the odds well-calibrated? ➡️ pena.lt/y/2025/07/16...
pena.lt
How Accurate Are Soccer Odds? A Data Dive into 250 Million Betting Lines
A data-driven deep dive into how accurately bookmakers price global soccer markets...
0164 16
Martin Eastwood @martineastwood.co.uk · 19/06/2025
There's also a new blog post here that explains more about the latest updates: pena.lt/y/2025/06/10...
pena.lt
MatchFlow 1.4.0: Optimizing, Visualizing, and Validating your Data Pipelines
MatchFlow just got smarter, friendlier, and more powerful for optimizing your pipelines, visualizing your data flow, and keeping your data clean...
030 3
Martin Eastwood @martineastwood.co.uk · 19/06/2025
🚀 penaltyblog v1.4.0 is out! Now includes a query plan optimiser for smarter Flow pipelines: • Optional FlowOptimizer for smart rewrites (optimize=True) • New .plot_plan() for pipeline viz • .with_schema() for field validation • Rolling- and time-based summaries github.com/martineastwo...
github.com
GitHub - martineastwood/penaltyblog: ⚽ High-performance football analytics toolkit: build data pipelines, scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀
⚽ High-performance football analytics toolkit: build data pipelines, scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀 - martineastwood/penaltyblog
140 4
Martin Eastwood @martineastwood.co.uk · 25/05/2025
If you're interested in finding out more: Why I built it 👉 pena.lt/y/2025/05/25... Docs 👉 penaltyblog.readthedocs.io/en/latest/in...
pena.lt
Introducing MatchFlow: a JSON-native query engine for football data.
MatchFlow is a JSON-native query engine for football data - no flattening, no fuss...
010 1
Martin Eastwood @martineastwood.co.uk · 25/05/2025
At the heart of matchflow is the Flow class - a lazy, composable way to work with nested football data. You can filter, group, and summarize JSON-like data without flattening or loading everything into memory. 👇 Example:
Python code showing how to use the Flow class from penaltyblog.matchflow: it loads a folder of JSON files, filters for shots, groups by player name, and summarizes shot counts.
110 1
Martin Eastwood @martineastwood.co.uk · 25/05/2025
🚨 I've updated penaltyblog to v1.3.0 It now ships with matchflow, a new submodule for building streaming data pipelines from nested football JSON (like Statsbomb events). Composable, lazy, and designed for the way football data actually looks. github.com/martineastwo...
github.com
GitHub - martineastwood/penaltyblog: ⚽ High-performance football analytics toolkit: build data pipelines, scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀
⚽ High-performance football analytics toolkit: build data pipelines, scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀 - martineastwood/penaltyblog
130 3
Martin Eastwood @martineastwood.co.uk · 02/05/2025
Thanks! Just to remove another variable - by simulating the result I definitely know which forecast is better as the simulated result is sampled from that particular forecast. When using the actual result you could argue that the true probabilities it's sampled from are unknown.
030 3
Martin Eastwood @martineastwood.co.uk · 01/05/2025
New article on my blog: why the Ranked Probability Score might be misleading you when evaluating football prediction models - and what to use instead pena.lt/y/2025/05/01... #FootballAnalytics #DataScience #RPS
pena.lt
Better Metrics for Football Forecasts: Moving Beyond the Ranked Probability Score
Why the Ranked Probability Score might be misleading your football model evaluations, and what to use instead....
160 6
Martin Eastwood @martineastwood.co.uk · 16/04/2025
Thanks Paul. Good question, in theory with enough cross league connectivity you have one global Pi system and it all converges. Ratings are then relative to average team in your global pool so can compare across leagues. Is on todo list to see how well this performs compared to other approaches.
100 1
Martin Eastwood @martineastwood.co.uk · 14/04/2025
New on my blog: Pi Ratings — a football-first alternative to Elo. ✅ Handles draws ✅ Uses score margins ✅ Beats Elo on predictions Includes code, benchmarks & more: 👉 pena.lt/y/2025/04/14...
pena.lt
Pi Ratings: The Smarter Way to Rank Football Teams
A smarter, football-focused alternative to Elo — using Pi Ratings to track team strength and predict matches...
1174 17
Martin Eastwood @martineastwood.co.uk · 10/04/2025
penaltyblog v1.2.0 is released! ✅ Elo Ratings now football-specific (home advantage + draw probabilities) ⚡️ Fast Cython implementations of Ignorance Score & Multiclass Brier Score 📝 Updated docs / examples for Elo, Pi Ratings, RPS & more github.com/martineastwo...
github.com
GitHub - martineastwood/penaltyblog: ⚽ High-performance football analytics toolkit: scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀
⚽ High-performance football analytics toolkit: scrape data, model matches, rank teams, and bet smarter | Powered by pena.lt/y/blog 🚀 - martineastwood/penaltyblog
0133 13
Reposted by Martin Eastwood
Nils Mackay @nilsmackay.bsky.social · 01/04/2025
[NEW] First blog in a long time! In which I show a pretty straightforward way to derive teams' attacking and defensive strengths from bookmaker odds. This method is not only easy to implement, but also very accurate compared to results-based models. mackayanalytics.nl/2025/04/01/g...
2347 34
Martin Eastwood @martineastwood.co.uk · 18/03/2025
Looking forward to the Field Of Play Conference today. If you’re there as well today then come over and say hi 👋
010 1
Martin Eastwood @martineastwood.co.uk · 16/03/2025
⚽ New blog post - which football prediction model is the best? Poisson, Weibull, or Negative Binomial — each has its strengths and weaknesses. Learn how to optimise them for accurate match predictions using my penaltyblog Python package. pena.lt/y/2025/03/10... #FootballAnalytics #DataScience
pena.lt
Football Prediction Models: Which Ones Work the Best?
Comparing football goals models — Poisson, Dixon-Coles, and more — to see which predicts best and how to optimize them...
0257 25
Martin Eastwood @martineastwood.co.uk · 16/03/2025
That wasn't the answer I'm looking for, stop encouraging me 😅
010 1
Martin Eastwood @martineastwood.co.uk · 16/03/2025
I may just create a separate package for them for people willing to fight with the dependencies. I'm also trying really hard to talk myself out of building my own lightweight Bayesian framework for them 😆
100 1
Martin Eastwood @martineastwood.co.uk · 16/03/2025
Main issue is that pymc and stan are such heavy dependencies that all the Bayesian stuff became too difficult to share as users struggled to install them. Plus, pymc and Stan's dependencies were then so strict that it was difficult to install other packages alongside them. Wasn't worth the hassle.
200 2
Martin Eastwood @martineastwood.co.uk · 15/03/2025
Also, v1.1.0 is the first Cythonized penaltyblog release using wheels across multiple platforms. This should now make installation smoother on Windows, macOS, and Linux. However, if you run into any issues installing, let me know so I can look into it. Thanks!
000 0
Martin Eastwood @martineastwood.co.uk · 15/03/2025
penaltyblog v1.1.0 is released! 🔥 250x faster models with Cython 📊 New models: Negative Binomial, Weibull, ZIP & Bivariate 🔢 Pi Ratings System for ranking teams 🔗 Full changelog: penaltyblog.readthedocs.io/en/master/changelog/index.html #Python #SportsAnalytics #MachineLearning
penaltyblog.readthedocs.io
Changelog — penaltyblog documentation
2222 22
Martin Eastwood @martineastwood.co.uk · 27/02/2025
@pysport.org Looks like you've got the wrong Martin on your website as the contributor for my penaltyblog python package - opensource.pysport.org/project/pena...
opensource.pysport.org
000 0