Dixon and Coles
[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 the model
[3]:
clf = pb.models.DixonColesGoalModel(
df["goals_home"], df["goals_away"], df["team_home"], df["team_away"]
)
clf.fit()
The model’s parameters
[4]:
clf
[4]:
Module: Penaltyblog
Model: Dixon and Coles
Number of parameters: 42
Log Likelihood: -1057.16
AIC: 2198.319
Team Attack Defence
------------------------------------------------------------
Arsenal 1.134 -0.939
Aston Villa 0.843 -0.619
Bournemouth 0.812 -0.652
Brighton 0.781 -0.832
Burnley 0.874 -0.917
Chelsea 1.341 -0.81
Crystal Palace 0.54 -0.928
Everton 0.904 -0.798
Leicester 1.306 -1.077
Liverpool 1.539 -1.288
Man City 1.72 -1.213
Man United 1.283 -1.217
Newcastle 0.756 -0.773
Norwich 0.386 -0.524
Sheffield United 0.757 -1.171
Southampton 1.046 -0.729
Tottenham 1.216 -0.951
Watford 0.712 -0.664
West Ham 1.012 -0.693
Wolves 1.037 -1.12
------------------------------------------------------------
Home Advantage: 0.231
Rho: -0.079
[5]:
clf.get_params()
[5]:
{'attack_Arsenal': 1.1341865177762285,
'attack_Aston Villa': 0.8428530080228543,
'attack_Bournemouth': 0.8120403901309736,
'attack_Brighton': 0.7808625592284577,
'attack_Burnley': 0.8735990924845769,
'attack_Chelsea': 1.340685364571421,
'attack_Crystal Palace': 0.540289929985007,
'attack_Everton': 0.9040391275578089,
'attack_Leicester': 1.3057973747311051,
'attack_Liverpool': 1.5388075144975972,
'attack_Man City': 1.7197213689727928,
'attack_Man United': 1.2833539229945745,
'attack_Newcastle': 0.7560462391368982,
'attack_Norwich': 0.38635937830680633,
'attack_Sheffield United': 0.7571523352515713,
'attack_Southampton': 1.0462746462988073,
'attack_Tottenham': 1.216439560492832,
'attack_Watford': 0.7122177934411291,
'attack_West Ham': 1.0118517568580763,
'attack_Wolves': 1.0374221192548183,
'defence_Arsenal': -0.9388906422952455,
'defence_Aston Villa': -0.6190197176844375,
'defence_Bournemouth': -0.6519855379159416,
'defence_Brighton': -0.8319679353511403,
'defence_Burnley': -0.9169866533049907,
'defence_Chelsea': -0.8096432828942898,
'defence_Crystal Palace': -0.9276726140616492,
'defence_Everton': -0.7977905220617109,
'defence_Leicester': -1.0774381274274807,
'defence_Liverpool': -1.2882869615601673,
'defence_Man City': -1.2127279738256183,
'defence_Man United': -1.2167286266767237,
'defence_Newcastle': -0.7732671939429236,
'defence_Norwich': -0.5236073026183325,
'defence_Sheffield United': -1.1712568842023234,
'defence_Southampton': -0.7286812539890076,
'defence_Tottenham': -0.9506798704672896,
'defence_Watford': -0.6644785296965087,
'defence_West Ham': -0.6929137366167742,
'defence_Wolves': -1.1199735644750717,
'home_advantage': 0.2311245551328041,
'rho': -0.07853233375103048}
Predict Match Outcomes
[6]:
probs = clf.predict("Liverpool", "Wolves")
probs
[6]:
Module: Penaltyblog
Class: FootballProbabilityGrid
Home Goal Expectation: 1.9154613455938239
Away Goal Expectation: 0.7781275343757059
Home Win: 0.6343570672571542
Draw: 0.22868509470199844
Away Win: 0.13695783584981738
1x2 Probabilities
[7]:
probs.home_draw_away
[7]:
[0.6343570672571542, 0.22868509470199844, 0.13695783584981738]
[8]:
probs.home_win
[8]:
0.6343570672571542
[9]:
probs.draw
[9]:
0.22868509470199844
[10]:
probs.away_win
[10]:
0.13695783584981738
Probablity of Total Goals >1.5
[11]:
probs.total_goals("over", 1.5)
[11]:
0.7580909443325337
Probability of Asian Handicap 1.5
[12]:
probs.asian_handicap("home", 1.5)
[12]:
0.38896867360115095
Probability of both teams scoring
[13]:
probs.both_teams_to_score
[13]:
0.46901574333181895