EPL 21-23 November 2015

EPL November 21st - 23rd 2015

Another brief look at some of the simple statistics underlying the weekend games in the English Premier League.

In [1]:
%matplotlib inline
import league_analysis
from IPython.display import display, HTML
epl = league_analysis.epl
weekend_matches = league_analysis.get_matches(epl, '21/11/2015', '23/11/2015')
league_analysis.display_given_matches(weekend_matches)
Home Away
Team Chelsea Norwich
Goals 1 0
Shots 21 4
SOT 7 2
Home Away
Team Everton Aston Villa
Goals 4 0
Shots 16 10
SOT 9 3
Home Away
Team Man City Liverpool
Goals 1 4
Shots 11 14
SOT 3 9
Home Away
Team Newcastle Leicester
Goals 0 3
Shots 9 18
SOT 1 7
Home Away
Team Southampton Stoke
Goals 0 1
Shots 16 16
SOT 1 4
Home Away
Team Swansea Bournemouth
Goals 2 2
Shots 11 16
SOT 4 4
Home Away
Team Watford Man United
Goals 1 2
Shots 10 13
SOT 5 6
Home Away
Team West Brom Arsenal
Goals 2 1
Shots 4 11
SOT 1 3
Home Away
Team Tottenham West Ham
Goals 4 1
Shots 22 10
SOT 12 4
Home Away
Team Crystal Palace Sunderland
Goals 0 1
Shots 19 12
SOT 7 4
In [2]:
league_analysis.display_match(epl, 'Chelsea', 'Norwich', '21/11/15')

Chelsea 1 - 0 Norwich

Home Away
Team Chelsea Norwich
Goals 1 0
Shots 21 4
SOT 7 2

Similar to their win against Aston Villa before a poor run of results, Chelsea really needed a win here. It looks as though their 1-0 victory was if anything a little unflattering. Such a performance will be encouraging, though it is still beating teams around the relegation battle rather than those they might hope to surpass into one of the four champions' league spots.

In [3]:
epl.compare_game_against_opponents('Chelsea', 'Norwich', '21/11/15')
Measure Average Per Game for This game for Average Per Game against opponents
Chelsea Shots 14.615384615384615 21 13.76923076923077
Norwich Shots 12.846153846153847 4 12.23076923076923
Chelsea SOT 4.3076923076923075 7 4.6923076923076925
Norwich SOT 4.153846153846154 2 5.230769230769231

So, Chelsea with 21 shots took 6 and a half shots more than usual and 7 more than the average team does against Norwich. They also only allowed 4 shots, whereas Norwich normally take nearly 13 and Chelsea normally allow over 12. Similar statistics for the shots on target. Overall then a pretty good display from the champions, even if the narrow scoreline probably had a few Chelsea fans worried about a late equaliser.

In [4]:
league_analysis.display_match(epl, 'Everton', 'Aston Villa', '21/11/15')

Everton 4 - 0 Aston Villa

Home Away
Team Everton Aston Villa
Goals 4 0
Shots 16 10
SOT 9 3

Probably the most predictable of the results this weekend (with Tottenham's win over West Ham a good second). The scoreline looks a little harsh on Aston Villa. Worrying signs for Aston Villa, now bottom in the league for goals scored and goal difference, and not doing great on the goals conceded front either.

In [20]:
pairs = [(stats.teamname, stats.goals_for - stats.goals_against)
         for stats in epl.team_stats.values()]
league_analysis.display_ranked_table(['Team', 'Goal Difference'], pairs)
pairs = [(stats.teamname, stats.goals_for)
         for stats in epl.team_stats.values()]
league_analysis.display_ranked_table(['Team', 'Goals For'], pairs)
pairs = [(stats.teamname, stats.goals_against)
         for stats in epl.team_stats.values()]
league_analysis.display_ranked_table(['Team', 'Goals Against'], pairs, reverse=False)
Position Team Goal Difference
1 Man City 14
2 Tottenham 13
3 Arsenal 12
4 Man United 10
5 Everton 8
- Leicester 8
7 Southampton 5
8 West Ham 4
9 Liverpool 2
10 Crystal Palace 1
11 Stoke -1
12 Watford -2
13 Swansea -4
14 West Brom -5
15 Chelsea -6
16 Norwich -8
17 Newcastle -12
- Sunderland -12
19 Bournemouth -13
20 Aston Villa -14
Position Team Goals For
1 Leicester 28
2 Man City 27
3 West Ham 24
- Tottenham 24
- Everton 24
6 Arsenal 23
7 Man United 19
- Southampton 19
9 Chelsea 17
- Liverpool 17
11 Norwich 16
12 Bournemouth 14
- Crystal Palace 14
- Sunderland 14
- Swansea 14
16 Newcastle 13
17 Watford 12
- West Brom 12
19 Stoke 11
20 Aston Villa 10
Position Team Goals Against
1 Man United 9
2 Tottenham 11
- Arsenal 11
4 Stoke 12
5 Man City 13
- Crystal Palace 13
7 Watford 14
- Southampton 14
9 Liverpool 15
10 Everton 16
11 West Brom 17
12 Swansea 18
13 West Ham 20
- Leicester 20
15 Chelsea 23
16 Aston Villa 24
- Norwich 24
18 Newcastle 25
19 Sunderland 26
20 Bournemouth 27
In [6]:
league_analysis.display_match(epl, 'Man City', 'Liverpool', '21/11/15')

Man City 1 - 4 Liverpool

Home Away
Team Man City Liverpool
Goals 1 4
Shots 11 14
SOT 3 9

Concerning the last table this game is the reason that Manchester City were not joint top with Manchester United for goals conceded. It's hard to argue with the score line as well, with 9 shots on target Liverpool were significantly better than most teams have managed against Manchester City:

In [7]:
epl.compare_game_against_opponents('Man City', 'Liverpool', '21/11/15')
Measure Average Per Game for This game for Average Per Game against opponents
Man City Shots 17.692307692307693 11 10.76923076923077
Liverpool Shots 15.23076923076923 14 8.153846153846153
Man City SOT 6.615384615384615 3 3.230769230769231
Liverpool SOT 5.076923076923077 9 2.8461538461538463

Restricting the home side to just 11 shots from an average of more than 17 is impressive, and done when taking 14 shots themselves. Basically Liverpool have managed to restrict Manchester City to looking like an average team that plays Liverpool (that average team usually manage 10.8 shots and 3.2 shots on target), but have done so whilst looking anything like an average team that takes on Manchester City. Even Tottenham, the other team to have beaten Man City 4-1, did not manage to out-shoot them, and were pretty fortunate to win 4-1:

In [8]:
league_analysis.display_given_matches(league_analysis.get_matches_between([epl], 'Man City', 'Tottenham'))
Home Away
Team Tottenham Man City
Goals 4 1
Shots 15 22
SOT 8 8
In [9]:
league_analysis.display_match(epl, 'Newcastle', 'Leicester', '21/11/15')

Newcastle 0 - 3 Leicester

Home Away
Team Newcastle Leicester
Goals 0 3
Shots 9 18
SOT 1 7

And so to the new league leaders. Say what you want you about Leicester and how they might not sustain this run, but they certainly deserved their victory here. In fact the interest around Leicester's rise to the top of the table should not distract us from the danger that Newcastle find themselves. This is pretty terrible stuff, losing at home so comprehsively.

In [10]:
league_analysis.display_match(epl, 'Southampton', 'Stoke', '21/11/15')

Southampton 0 - 1 Stoke

Home Away
Team Southampton Stoke
Goals 0 1
Shots 16 16
SOT 1 4

This was pretty surprising, Stoke have not had great numbers so far this season. Although with the influx of some talent it was a bit of a surprise that Stoke's numbers were quite as bad as they were and perhaps many expected an up-tick. Still, an excellent away victory at Southampton, all the more for having competed so well on the shot counts. This was not like the defeat of Chelsea in which they suffered something of a battering. This was a solid display (at least in terms of shot numbers).

In [11]:
league_analysis.display_match(epl, 'Swansea', 'Bournemouth', '21/11/15')

Swansea 2 - 2 Bournemouth

Home Away
Team Swansea Bournemouth
Goals 2 2
Shots 11 16
SOT 4 4

Bournemouth just cannot catch a break. Though to be fair Bournemouth had a two goal lead here and probably should have held on, but an away draw is not a disaster. Still, their PDO has not been their friend, I fully expect Bournemouth to remain in the division:

In [12]:
pairs = [(stats.teamname, stats.pdo)
         for stats in epl.team_stats.values()]
league_analysis.display_ranked_table(['Team', 'PDO'], pairs)
Position Team PDO
1 Man United 0.1680035650623886
2 Everton 0.15101838052657723
3 West Ham 0.134453781512605
4 Arsenal 0.07640344747262984
5 Leicester 0.06681405060181778
6 Stoke 0.06533776301218164
7 Tottenham 0.0314176245210728
8 Watford 0.026455026455026454
9 West Brom 0.017543859649122806
10 Crystal Palace 0.0014380212827150018
11 Sunderland -0.010932105868814712
12 Chelsea -0.03466386554621853
13 Man City -0.037397862979258345
14 Newcastle -0.059857057772483624
15 Southampton -0.061969439728353115
16 Swansea -0.06216931216931221
17 Aston Villa -0.06409130816505704
18 Norwich -0.09714632665452339
19 Liverpool -0.09956709956709958
20 Bournemouth -0.23153942428035046

Just look at that number. They are minus 0.23 more than double the negative of the next worse off team Liverpool. Also worth noting here is that Leicester aren't getting an incredible amount of luck.

In [13]:
league_analysis.display_match(epl, 'Watford', 'Man United', '21/11/15')

Watford 1 - 2 Man United

Home Away
Team Watford Man United
Goals 1 2
Shots 10 13
SOT 5 6

The above table showed the league leaders in PDO are Manchester United. However, we know that PDO is an imperfect measure of luck, and that Mancester United do seem to have some qualities that allow them to defy measure. A good article at statsbomb (by Marek Kwiatkowski otherwise known as statlurker), is a nice discussion of one way in which shot statistics might miss "near chances". So perhaps Manchester United create a lot of plays that do not result in shots but nearly a shot from a highly dangerous position. In other words a cross/pass which missed its target but had it done so would have resulted in a goal with high probability. Having watched Manchester United play this season I'm a little sceptical of that explanation (for this season).

Still, this was a game that Mancester United probably deserved to win, but it highlights a problem with playing in such a closed manner. You're susceptible to the vagries of chance. In other words, you're more likely to lose if you out-shoot your opponents 5-3 than you are if you out-shoot them 20-12. Since Man United should probably consider themselves favourites for most games against league opponents this season, their tactics are at least a bit questionable. But that is a topic that deserves much more than a brief look.

Of course I say all this despite the fact that actually Watford have managed quite a decent number of shots and shots on target against the generally miserly Man United. Watford are in danger of coming off as plucky-losers a lot, but the general signs points to a pretty decent team that should manage to remain in the league, they certainly seem better than Newcastle, Sunderland and Aston Villa.

In [14]:
league_analysis.display_match(epl, 'West Brom', 'Arsenal', '21/11/15')

West Brom 2 - 1 Arsenal

Home Away
Team West Brom Arsenal
Goals 2 1
Shots 4 11
SOT 1 3

Great win for West Brom. Another defeat for Arsenal despite dominating the game for large portions. Still, Arsenal are clearly title contenders this season.

In [15]:
league_analysis.display_match(epl, 'Tottenham', 'West Ham', '22/11/15')

Tottenham 4 - 1 West Ham

Home Away
Team Tottenham West Ham
Goals 4 1
Shots 22 10
SOT 12 4

This was pretty predictable. Tottenham are beginning to look better and better this season. With the very lacklustre start to the campaign for the champions, a top 4 spot has looked well within Tottenham's grasp. Having seen Arsenal and City lose this weekend I suspect Spurs fans are starting to dream of a title-bid if not exactly a title. Probably a little premature for that, but still, it's been a long time since Spurs lost a league match.

I don't wish to harp on at West Ham, but they are still over-performing. I still think they will not manage to remain in the top half of the table.

In [16]:
league_analysis.display_match(epl, 'Crystal Palace', 'Sunderland', '23/11/15')

Crystal Palace 0 - 1 Sunderland

Home Away
Team Crystal Palace Sunderland
Goals 0 1
Shots 19 12
SOT 7 4

File this one under, "Did not see that coming". However, once again the shots statistics show that Sunderland probably did not deserve this win. I say once again, because Sunderland have only won two games this season, and both have been seemingly undeserved:

In [17]:
def filter_fun(match):
    return ((match.HomeTeam == 'Sunderland' and match.FTR == 'H') or
            (match.AwayTeam == 'Sunderland' and match.FTR == 'A'))

relevant_matches = league_analysis.get_all_matches(years=[league_analysis.year_201516], filter_fun=filter_fun)
league_analysis.display_given_matches(relevant_matches)
Home Away
Team Sunderland Newcastle
Goals 3 0
Shots 9 21
SOT 3 8
Home Away
Team Crystal Palace Sunderland
Goals 0 1
Shots 19 12
SOT 7 4

Worrying times, unless you're a Newcastle fan, except that:

In [18]:
def filter_fun(match):
    return ((match.HomeTeam == 'Newcastle' and match.FTR == 'H') or
            (match.AwayTeam == 'Newcastle' and match.FTR == 'A'))

relevant_matches = league_analysis.get_all_matches(years=[league_analysis.year_201516], filter_fun=filter_fun)
league_analysis.display_given_matches(relevant_matches)
Home Away
Team Newcastle Norwich
Goals 6 2
Shots 11 18
SOT 6 6
Home Away
Team Bournemouth Newcastle
Goals 0 1
Shots 20 2
SOT 5 1

Still it could be worse, you could have only won one game, which you probably didn't deserve:

In [19]:
def filter_fun(match):
    return ((match.HomeTeam == 'Aston Villa' and match.FTR == 'H') or
            (match.AwayTeam == 'Aston Villa' and match.FTR == 'A'))

relevant_matches = league_analysis.get_all_matches(years=[league_analysis.year_201516], filter_fun=filter_fun)
league_analysis.display_given_matches(relevant_matches)
Home Away
Team Bournemouth Aston Villa
Goals 0 1
Shots 11 7
SOT 2 3

As I said, poor old Bournemouth.

Thanks for reading.

Comments

Comments powered by Disqus