Skip to content

Instantly share code, notes, and snippets.

@jhw
Last active October 21, 2019 08:06
Show Gist options
  • Save jhw/dd7d3dc77bfdce9db48f1713a39417da to your computer and use it in GitHub Desktop.
Save jhw/dd7d3dc77bfdce9db48f1713a39417da to your computer and use it in GitHub Desktop.
Simple goals grid model
justin@justin-XPS-13-9360:~/work$ python3 goals_grid.py 
home_win	0.45395
away_win	0.24608
draw    	0.29997
over_05 	0.86466
under_05	0.13534
over_15 	0.59399
under_15	0.40601
over_25 	0.32332
under_25	0.67668
over_35 	0.14288
under_35	0.85712
over_45 	0.05265
under_45	0.94735
over_55 	0.01656
under_55	0.98344
import math
HomeWin, AwayWin, Draw = MatchOdds = ["home_win", "away_win", "draw"]
N=10
def poisson(l, x):
return (l**x)*math.exp(-l)/math.factorial(x)
def correct_score_grid(lx, ly, rho, n):
def DC_factor(i, j):
if i==0 and j==0:
return 1-lx*ly*rho
elif i==0 and j==1:
return 1+lx*rho
elif i==1 and j==0:
return 1+ly*rho
elif i==1 and j==1:
return 1-rho
else:
return 1
return [[poisson(lx, i)*poisson(ly, j)*DC_factor(i, j)
for j in range(n)]
for i in range(n)]
class CSGrid(list):
def __init__(self, data):
list.__init__(self, data)
def sum(self, filterfn):
return sum([self[i][j]
for i in range(len(self))
for j in range(len(self))
if filterfn(i, j)])
def match_odds(self, selection):
filterfns={HomeWin: lambda i, j: i > j,
AwayWin: lambda i, j: i < j,
Draw: lambda i, j: i==j}
return self.sum(filterfns[selection])
def over_goals(self, strike):
filterfn=lambda i, j: i+j > strike
return self.sum(filterfn)
def under_goals(self, strike):
filterfn=lambda i, j: i+j < strike
return self.sum(filterfn)
def run_model(lx, ly, rho, n=N):
# initialise
grid=CSGrid(correct_score_grid(lx, ly, rho, n))
table=[]
# match odds
for attr in MatchOdds:
value=grid.match_odds(attr)
row={"name": attr,
"value": value}
table.append(row)
# o/u goals
for i in range(6):
strike=i+0.5
for attr in ["over", "under"]:
name="%s_%s" % (attr, str(strike).replace(".", ""))
fn=getattr(grid, "%s_goals" % attr)
value=fn(strike)
row={"name": name,
"value": value}
table.append(row)
# return
return table
if __name__=="__main__":
def format_name(text, n=8):
if len(text) > n:
return text[:n]
else:
return text+" ".join(['' for i in range(1+n-len(text))])
for row in run_model(1.2, 0.8, 0):
print ("%s\t%.5f" % (format_name(row["name"]),
row["value"]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment