Poisson
[1]:
import sys
sys.path.append("../../")
import penaltyblog as pb
Get data from football-data.co.uk
[2]:
fb = pb.scrapers.FootballData("ENG Premier League", "2019-2020")
df = fb.get_fixtures()
df.head()
[2]:
competition | season | datetime | div | date | time | team_home | team_away | fthg | ftag | ... | b365_cahh | b365_caha | pcahh | pcaha | max_cahh | max_caha | avg_cahh | avg_caha | goals_home | goals_away | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | |||||||||||||||||||||
1565308800---liverpool---norwich | ENG Premier League | 2019-2020 | 2019-08-09 20:00:00 | E0 | 2019-08-09 | 20:00 | Liverpool | Norwich | 4 | 1 | ... | 1.91 | 1.99 | 1.94 | 1.98 | 1.99 | 2.07 | 1.90 | 1.99 | 4 | 1 |
1565395200---bournemouth---sheffield_united | ENG Premier League | 2019-2020 | 2019-08-10 15:00:00 | E0 | 2019-08-10 | 15:00 | Bournemouth | Sheffield United | 1 | 1 | ... | 1.95 | 1.95 | 1.98 | 1.95 | 2.00 | 1.96 | 1.96 | 1.92 | 1 | 1 |
1565395200---burnley---southampton | ENG Premier League | 2019-2020 | 2019-08-10 15:00:00 | E0 | 2019-08-10 | 15:00 | Burnley | Southampton | 3 | 0 | ... | 1.87 | 2.03 | 1.89 | 2.03 | 1.90 | 2.07 | 1.86 | 2.02 | 3 | 0 |
1565395200---crystal_palace---everton | ENG Premier League | 2019-2020 | 2019-08-10 15:00:00 | E0 | 2019-08-10 | 15:00 | Crystal Palace | Everton | 0 | 0 | ... | 1.82 | 2.08 | 1.97 | 1.96 | 2.03 | 2.08 | 1.96 | 1.93 | 0 | 0 |
1565395200---tottenham---aston_villa | ENG Premier League | 2019-2020 | 2019-08-10 17:30:00 | E0 | 2019-08-10 | 17:30 | Tottenham | Aston Villa | 3 | 1 | ... | 2.10 | 1.70 | 2.18 | 1.77 | 2.21 | 1.87 | 2.08 | 1.80 | 3 | 1 |
5 rows × 111 columns
Train a basic poisson model
[3]:
clf = pb.models.PoissonGoalsModel(
df["goals_home"], df["goals_away"], df["team_home"], df["team_away"]
)
clf.fit()
The model’s parameters
[4]:
clf
[4]:
Module: Penaltyblog
Model: Poisson
Number of parameters: 41
Log Likelihood: -1057.712
AIC: 2197.424
Team Attack Defence
------------------------------------------------------------
Arsenal 1.133 -0.937
Aston Villa 0.84 -0.618
Bournemouth 0.813 -0.65
Brighton 0.777 -0.837
Burnley 0.87 -0.91
Chelsea 1.349 -0.806
Crystal Palace 0.543 -0.922
Everton 0.899 -0.795
Leicester 1.306 -1.084
Liverpool 1.536 -1.283
Man City 1.721 -1.206
Man United 1.286 -1.216
Newcastle 0.755 -0.766
Norwich 0.391 -0.521
Sheffield United 0.761 -1.163
Southampton 1.052 -0.719
Tottenham 1.218 -0.953
Watford 0.706 -0.669
West Ham 1.014 -0.688
Wolves 1.031 -1.125
------------------------------------------------------------
Home Advantage: 0.229
[5]:
clf.get_params()
[5]:
{'attack_Arsenal': 1.1331236899973345,
'attack_Aston Villa': 0.8398888104788944,
'attack_Bournemouth': 0.8130897663316354,
'attack_Brighton': 0.7765248253257214,
'attack_Burnley': 0.8703023371771994,
'attack_Chelsea': 1.3487338919001544,
'attack_Crystal Palace': 0.5425422408745968,
'attack_Everton': 0.8994386622804366,
'attack_Leicester': 1.305683340822444,
'attack_Liverpool': 1.536142023201564,
'attack_Man City': 1.721273889006884,
'attack_Man United': 1.2855301627562425,
'attack_Newcastle': 0.754538349388783,
'attack_Norwich': 0.3911250522596789,
'attack_Sheffield United': 0.7614768317608919,
'attack_Southampton': 1.0516111981282654,
'attack_Tottenham': 1.2177895314312077,
'attack_Watford': 0.7064633632379288,
'attack_West Ham': 1.0135085594841655,
'attack_Wolves': 1.0312134741439425,
'defence_Arsenal': -0.9373593152185443,
'defence_Aston Villa': -0.6183887167614771,
'defence_Bournemouth': -0.6497780016893445,
'defence_Brighton': -0.8366644455845825,
'defence_Burnley': -0.9096445581199665,
'defence_Chelsea': -0.8056794617596451,
'defence_Crystal Palace': -0.9217234584764492,
'defence_Everton': -0.7950830265711245,
'defence_Leicester': -1.0841115587982018,
'defence_Liverpool': -1.283371292184721,
'defence_Man City': -1.2063235545625164,
'defence_Man United': -1.2156312104034752,
'defence_Newcastle': -0.766019714032436,
'defence_Norwich': -0.520671121600944,
'defence_Sheffield United': -1.1626929246095525,
'defence_Southampton': -0.7187488659558111,
'defence_Tottenham': -0.953348247236947,
'defence_Watford': -0.6693854533833772,
'defence_West Ham': -0.6878737389877748,
'defence_Wolves': -1.1252407856242987,
'home_advantage': 0.2292519839991387}
Predict Match Outcomes
[6]:
probs = clf.predict("Liverpool", "Wolves")
probs
[6]:
Module: Penaltyblog
Class: FootballProbabilityGrid
Home Goal Expectation: 1.8967714833577352
Away Goal Expectation: 0.7771220845059058
Home Win: 0.6385321493320355
Draw: 0.21487353680172425
Away Win: 0.1465943119417152
1x2 Probabilities
[7]:
probs.home_draw_away
[7]:
[0.6385321493320355, 0.21487353680172425, 0.1465943119417152]
[8]:
probs.home_win
[8]:
0.6385321493320355
[9]:
probs.draw
[9]:
0.21487353680172425
[10]:
probs.away_win
[10]:
0.1465943119417152
Probablity of Total Goals >1.5
[11]:
probs.total_goals("over", 1.5)
[11]:
0.746563389116105
Probability of Asian Handicap 1.5
[12]:
probs.asian_handicap("home", 1.5)
[12]:
0.38442594605181685
Probability of both teams scoring
[13]:
probs.both_teams_to_score
[13]:
0.45920366069754437