A tale of goals, passes, web scraping, and being the only German who is not into Soccer.
Usually, I’m a proud member of the small club of Germans who don’t care too much for soccer and make up for this by at least following the national selection on big competitions, like this year’s Euro. After Germany has been kicked out by the host France in the semi-finals, it’s time for some soul searching and many a discussion was had about whether the German style of playing (focusing on ball control and short, safe passing) is as good as it seemed in the aftermath of the last world cup, won by Germany.
Not being the biggest Soccer enthusiast, I don’t feel to qualified to enter this discussion, but maybe we can find interesting data we can crunch to give us some insights.
It’s about time I talked about web scraping. Writing a spider that follows links and extracts useful information is an important way for any data scientist worth his or her salt to gather interesting data. Now there are very nice frameworks around for this task. If you like Python, you should look into scrapy. Scala/Java users have with JSoup a powerful tool at their hands to extract entities from HTML pages (similar to beautifulsoup for Python).
An important thing to keep in mind is that you should have a look at the
page of the URL you want to extract information from to make sure they are okay with your spider grabbing data from their servers. Luckily, the UEFA does allow crawling their statistics on the Euro 2016 at the time of writing.
Do Passes Matter?
After spending some time extracting the data, let’s look at some numbers and graphs. And models, of course. UEFA provides us with lots of interesting information on players and teams, but in this post I’ll focus on two main indicators: Passes and attempts to score. Now just comparing the total number of passes and attempts per team should take the number of games into account as well as if or not the game was decided in overtime (which is in turn only applicable after the group stage). As for passes, UEFA has good numbers on all teams that made it past the group stages. So let’s look at those.
The bar chart above shows the passes per minute (PPM) per team, averaged over the players’ individual PPM. The color indicates which is the highest stage that the team reached. Now this is an interesting plot, as it shows that there is virtually no correlation between if a team passes the ball around a lot and when it was kicked out.
But what about goals? You can pass the ball around all you want, but you won’t win unless you score some goals. So let’s repeat the last plot, but with the attempts to score per minute (APM) instead of the PPM.
Due to some inconsistencies in the data, we now also have some teams that were kicked out in the group stage in our plot, most notably at first and next to last position. The teams of Austria and Turkey, both kicked out at the group stage, have the highest and next to lowest number (only Italy had less attempts per minute) of APMs.
I guess this is what makes soccer exciting. You can play very successful with a number of strategies, passing a lot or very little, making many or few attempts to score. To some degree it’s randomness that keeps us at the edge of our seats.
Nerd Zone: Ordinal Logistic Regression
Sometimes it’s just not enough to look at bar charts, but you have to quantify what you see. And since Germans take their soccer serious, I have all intention to back my ramblings with some numbers.
Let’s make sure that there is really not connection between APM, PPM, and at what stage you get kicked out. In order to do so, we use Ordinal Logistic Regression, using the MASS R package (check the tutorial here). The model we build using gives as expected a really bad AIC score.
So what does the null model say?
We see that the features basically don’t change the AIC score, as we expected. So we can conclude that our PPM and APM values don’t influence a team’s success and all that is left is to wish both France and Portugal the best of luck for tonight’s final. May the best team win!