Expected Points: Explanation, Usage, and how to Program your own Model
Data analytics has begun taking over the world of association football. From the foundational work of Charles Reep in the 1960s to today, analytics in football has grown from meticulous notetaking to hyper-complex modeling. Throughout this time period, data has revealed a lot about football that might not have been intuitive to the naked eye, and teams that embrace the lessons that data teaches have often been notable overperformers, if not revolutionaries in their own right.
Reep’s early work played a pivotal role in shaping the identity of English football. His first paper, “Skill and Chance in Association Football” was published by the Royal Statistical Society in 1968, and was one of the most comprehensive examples of data collection at the time. Essentially, Reep found that — contrary to intuition — extended periods of possession do not lead to goal scoring. Reep began his paper by showing the theoretical explanation for this theory: the more a team passes the ball, the more chances they have to lose possession. In fact, Reep found that a majority of goals were scored from very short possessions with fewer passes.
These findings were used to inform the “route one” approach eventually employed by many English teams. This style of play implicated long, vertical passes that moved the ball up the field quickly towards the goal, wasting no time on methodical buildup and safe ground passing. Obviously, long passes into a team’s defense are more likely to be intercepted, and these direct attacks would fail more often than not, but this style of play would often be fruitful results-wise, if not a turn-off for fans who want to watch a more attractive style of play. Even today, teams like Burnley and (for many years) West Brom were able to remain in the Premier League despite notably less valuable squads with less talented players compared to other teams in the division by employing this style of play.
Reep’s findings have eventually proven to be somewhat outdated. His style of data collection, heavily constrained by the pen-and-paper approach he was limited to in his day, was incapable of capturing the nuances of where and how these short attacks came to be. Ultimately, his findings remain true to this day, but their interpretation has changed; teams trying to score from these short possession tend to employ aggressive counter-pressing (or gengenpressing, as the term was originally coined in Germany), and the long-ball approach entailed by route-one football is less common amongst top clubs.
Additionally, more complex data modeling has been able to quantify the relative values of certain positions on the pitch, which has been another key component in informing the growing popularity of counter-pressing styles. Expected threat modeling shows the value that different positions have in terms of how likely a goal is to be scored from that position in a given number of ensuing moves. This modeling is especially useful for assessing midfielders and ball-playing defenders, as it quantifies the threat of ball progression in a manner that surface-level statistics like goals and assists can not.
The recent Champions League match between Real Madrid and Paris Saint-Germain provided a great example of the relevance of this modeling; Lionel Messi’s performance in that match was heavily criticized, with few clear-cut chances and a penalty saved by Thibaut Courtois. However, expected threat modeling revealed that Messi’s dribbling and passing led to an added threat of over 1.0 goals, meaning that he was essentially responsible for one expected goal (more on what this means later). Even though he did not get a direct goal contribution in this match, Messi was a massively valuable threat for PSG and was largely responsible for their sustained attacking pressure on a strong Real Madrid defense.
Ultimately, Messi was not involved in Kylian Mbappe’s late winner. So, if his performance was worth a contribution to a goal, but a goal was not scored, why does this modeling matter? One of the fallacies of the discourse surrounding metrics like expected goals, expected threat, and expected points is the expectation that they will be a perfect explanation of the events in a single game. In fact, these metrics are more useful as a long-term predictor than they are for summarizing 90 minutes of a very random sport.
The newest popular metric in football is expected goals, a statistic that explains the likelihood of a given shot becoming a goal based on historical data of other shots taken in similar positions and situations. The metric has become a mainstay — and often a centerpiece — of contemporary football discourse, with pundits and fans alike looking towards the metric as an explanation for which team deserved to win in a given game. However, as stated previously, using these metrics to assess 90-minute periods can be shaky.
Let’s say you and your friend are competing to see who will land a “tails” the most in a series of coin-flipping. If you get 10 flips of your coin, and your friend only gets 5, you are much more likely to land “tails” more often. However, it is not out of the realm of possibility for your friend to land 4 “tails” out of 5 tosses, and for you to only land 3 in your 10. This is analogous to a game of football where one team has more or higher-quality chances than the other, but may still fail to win or even lose the match. When this happens, many fans rush to question the credibility and usefulness of expected goals. However, as any statistically inclined person would be quick to point out, small sample sizes such as a game’s worth of shots do not always reflect the reality — or relative performance/strength of teams in this case.
On the business and administration side of association football, expected goals on its surface is used mostly for new player recruitment. The methods behind this process are complicated and interesting, and merit their own article. However, expected goals can be used for long-term result predictions, through their use in a model that produces a metric called expected points. expected points is a way of using expected goals to generate how many points a team “deserves” for a given match. It is calculated by iterating a simulation of a game based on the quality of chances each team has. For example, if a given shot has an xG value of 0.5, it has a 50% chance of being registered as a goal in any given iteration. Sometimes it will, sometimes it will not — much like how chances of similar quality often have varying conversion success.
This approach is often employed by large-scale betting companies. In association football, betting usually takes the form of choosing the result of the game, as opposed to over/unders or spreads, which are often used for betting in gridiron football. The latter forms of betting are meant to more closely reflect a 50/50 choice and are produced by complicated models with a lot of investment going into getting them right. In association football betting, however, there is a simple way to “beat” the system: predicting game results better than the oddsmakers.
Note: This should not be taken as betting advice. Most of the entities that make money by betting on the basis of expected points data are large companies betting in unregulated markets. The randomness of any given game means that, even with the best tools available to someone, there is always a massive risk of losing money. Only with betting volumes that are illegal in most of the developed world can a steady return on investment be relied upon.
Expected points are accumulated over the course of a season, and form what is often known as a “justice table,” — league standings based on expected points instead of actual points. By using the league position in the justice table, bettors are able to more accurately predict the outcomes of matches than by using the actual league table. It can also be a long-term predictor of success, highlighting teams that are unsustainably overperforming or underperforming based on their long-term xG and xPoints accumulation.
xG data is pretty easy to come by, as it is shared in many post-match analyses and scores apps such as FotMob. However, expected points data is harder to come by, which is a shame given that it is a better indication of what fans care about: results. So, here is a free and simple tutorial on how to generate your own expected points data.
What you need:
- The xG of a team in a given game
- Some environment to program in python
- (ideally, but not necessary) the number of shots a team took in a game.
For the purpose of this tutorial, I will be programming in Jupyter Notebooks. Installation is easy, and it is an environment that is great for learning and sharing programs.
Let’s start by getting our data points for a specific game. For this tutorial, we’ll use the recent clash between Manchester City and Tottenham, where Spurs pulled off a last-gasp, upset victory. Understat — the best online platform for justice tables and team-level xG data, scores the game as MCI 2.31–2.00 TOT, with Manchester City having taken 23 shots, and Tottenham having taken just 6.
Now that we have the data points we need, let's start by importing the NumPy library and by assigning lists with the number of shots and expected goals to variables named for each team.
Note: if you cannot find the number of shots, or simply do not feel like trying to fetch it, that’s fine. This program will still work without the exact number of shots, but it will be less accurate. You can replace the shot values with any amount, although a good rule of thumb is to try to assign 1 shot for every 0.10 to 0.20 xG.
Recall that expected points are found through iterating simulations of games based on each team’s xG. So, in order to create a program that produces expected points, we first need to create a game simulator. While this may seem like a daunting task, it actually only takes 4 lines of code:
However, in order to make our simulator iterable and more useful generally, we should put it inside a function.
In order to make the function more flexible, I’ve renamed every instance of “mci” to “a” and every instance of “tot” to “b”.
Now that we have this, we need to decide what we want the function to return. We could have it return a simple list with the goals scored by each team, but we can save ourselves some time in the future by converting the goals scored by each team into the points that they would get out of the game. In order to do this, we’ll create a series of conditionals to check what the result would be.
Now, we want to be able to iterate these simulations, in order to overcome the randomness that can occur in a small number of simulations. We could simply iterate with a for loop, but putting the process into a function will be much more convenient.
If you have the computing power to run a lot more simulations or want to play around with the number of simulations, you can add it as an argument like this:
Now that we have what we need, let’s run our program and compare it to the xPoints value from the Understat website:
Understat does not show the expected points values for each game, but they can be found by going back in time on the Premier League justice table. When doing this, we can find that Undertsat scored this game 1.58xP to 1.17xP, very similar to the values of 1.56xP and 1.23xP, respectively from our simulation.
There are a couple of reasons why there is a small discrepancy, however. Understat likely uses a much more complicated model to find its expected points totals, simulating each shot, whereas we average each shot out to the mean xG value of each shot. This can lead to some deviation, as it has been found that a lower volume of higher quality chances, when compared to a higher volume of lower quality chances with the same cumulative xG, tends to yield more goals. Oddly, this worked in the opposite direction in this case, but that could be down to something as trivial as a routing error somewhere down the line. For reference, when manually changing the shot amounts to 10 each, the xPoints is a more accurate reflection of Understat’s findings, with a tabulation of 1.58xP to 1.19xP. Ultimatley, this model is very accurate for how simple it is, and can hopefully be of use to any curious enquirers about expected points!
There are a couple of caveats to note here:
Different data sources will have different xG values for a given game, so the xP produced may be very different. For example, using FotMob’s data for the City-Tottenham game makes the gap seem much larger: 1.85xP to 0.96xP in favor of Manchester City. This is due to the fact that FotMob sources their xG data from Opta, while Understat developed their own model. Generally speaking, Opta is the industry leader in in-depth data for association football, and likely have the most complex model of anyone, so that data should be better trusted. I used Understat’s xG data for this example to compare it to their expected points model, as Opta does not have a public justice table.
I’m not even sure if Opta ever extrapolated expected points from their xG modeling. The earliest large-scale use of xPoints and justice tables were from SmartOdds, who sourced their data from Opta, although these tables were never public. The earliest public source on xPoints that I could find was from the “The Short Fuse” blog — the Arsenal blog for SBNation — in this 2017 article linked here. The topic was also discussed on pages 134–135 of The Expected Goals Philosophy — essential reading for anyone interested in analytics in association football.
Currently, xPoints data is only public on Understat, which only covers 6 European leagues: The EPL, La Liga, Ligue Une, The Bundesliga, Serie A, and the Russian Premier League. FotMob provides free access to xG data from Opta for other leagues not included on Understat, such as MLS, Liga MX, the SPFL, the English Championship, and many more. Given the ease of accessing FotMob data, this algorithm could be used to create more justice tables for leagues not shown on Understat.