"
],
"text/plain": [
" a_team h_a h_team lastAction player \\\n",
"count 226499 226499 226499 226499 226499 \n",
"unique 160 2 160 39 4846 \n",
"top Real Madrid h Real Madrid Pass Cristiano Ronaldo \n",
"freq 2391 125415 2437 80110 889 \n",
"\n",
" player_assisted result shotType situation \n",
"count 165662 226499 226499 226499 \n",
"unique 4839 6 4 5 \n",
"top Dimitri Payet MissedShots RightFoot OpenPlay \n",
"freq 535 89945 118641 166304 "
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.describe(include=['O'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The dataset has around 226,500 shots which aren't really a lot but enough to have a basic model running."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"Index(['X', 'Y', 'a_goals', 'a_team', 'date', 'h_a', 'h_goals', 'h_team', 'id',\n",
" 'lastAction', 'match_id', 'minute', 'player', 'player_assisted',\n",
" 'player_id', 'result', 'season', 'shotType', 'situation'],\n",
" dtype='object')"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.columns"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### PRE-PROCESSING"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The X & Y co-ordinates present in the data are scaled from 0 to 1 so I had to find a suitable multipliying factor. The field was considered to be of dimensions of 104*76 yards.\n",
"The co-ordinates were scaled acccordingly."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"df['X'] = df['X']*104\n",
"df['Y'] = df['Y']*76"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's try and plot the shot locations"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"from matplotlib.patches import Arc\n",
"\n",
"fig=plt.figure()\n",
"#fig,ax = plt.subplots(figsize=(10.4,7.6))\n",
"ax=fig.add_subplot(1,1,1)\n",
"ax.axis('off')\n",
"\n",
"plt.plot([0,104],[0,0],color=\"black\")\n",
"plt.plot([0,0],[76,0],color=\"black\")\n",
"plt.plot([0,104],[76,76],color=\"black\")\n",
"plt.plot([104,104],[76,0],color=\"black\")\n",
"plt.plot([52,52],[0,76],color=\"black\")\n",
"\n",
"plt.plot([104,86.32],[60,60],color=\"black\")\n",
"plt.plot([86.32,104],[16,16],color=\"black\")\n",
"plt.plot([86.32,86.32],[60,16],color=\"black\")\n",
"plt.plot([104,97.97],[48,48],color=\"black\")\n",
"plt.plot([104,97.97],[27.968,27.968],color=\"black\")\n",
"plt.plot([97.97,97.97],[48,27.968],color=\"black\")\n",
"\n",
"plt.plot([104,104],[34,42],color=\"red\")\n",
"\n",
"penaltySpot = plt.Circle((92.04,38),0.25,color=\"black\")\n",
"centreSpot = plt.Circle((52,38),0.5,color=\"black\")\n",
"centreCircle = plt.Circle((52,38),10,color=\"black\",fill=False)\n",
"\n",
"D = Arc((92.04,38),height=20,width=20,angle=0,theta1=125,theta2=235,color=\"black\")\n",
"\n",
"ax.add_patch(centreSpot)\n",
"ax.add_patch(centreCircle)\n",
"ax.add_patch(penaltySpot)\n",
"ax.add_patch(D)\n",
"\n",
"\n",
"plt.scatter(df['X'],df['Y'])\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All the shots are when the team is attacking from right to left. The shots on the left end of the pitch are perhaps own goals that will have to be removed."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We know that distance is a major factor for shots to be converted into goals and thus I added a distance feature. The distance will be measured from the shot location to the centre of the goal."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"df['distance'] = (((df['X']-104)**2 + (df['Y']-38)**2)**(1/2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another important factor to be taken into account is the angle of view the striker has. A smaller angle will obviously minimize the chance of a shot being converted into a goal."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We use trigonometry to find the angle extended by both the goal posts onto the shot location.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"cos c = (A^2+B^2-C^2)/2*A*B"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"import matplotlib.image as mpimg\n",
"image = mpimg.imread(\"angle.jpg\")\n",
"plt.imshow(image)\n",
"plt.axis('off')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pardon my paint skills, but the diagram above explains the angle c we are trying to find. The Red Dot is the shot location and the rectangle on the right is the goalmouth."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below, I find the distance between the goal posts and the shot location and use it to find the angle extended by the goal onto the shot location."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"temp = pd.DataFrame()\n",
"temp['a'] = ((df['X']-104)**2 + (df['Y']-42)**2)\n",
"temp['b'] = ((df['X']-104)**2 + (df['Y']-34)**2)\n",
"df['angle'] = (temp['a']+temp['b']-144)/(2*temp['a']*temp['b'])\n",
"df['angle'] = df['angle'].apply(math.acos)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Distance and Angle have been added as columns to the DataFrame."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"Index(['X', 'Y', 'a_goals', 'a_team', 'date', 'h_a', 'h_goals', 'h_team', 'id',\n",
" 'lastAction', 'match_id', 'minute', 'player', 'player_assisted',\n",
" 'player_id', 'result', 'season', 'shotType', 'situation', 'distance',\n",
" 'angle'],\n",
" dtype='object')"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.columns"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since the columns in the categs list are actually categories, we convert them into categories."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"categs = ['lastAction','result','shotType', 'situation']\n",
"for categ in categs:\n",
" df[categ] = df[categ].astype('category')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us have a look at the categories for each specific feature."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"lastAction\n",
"Index(['Aerial', 'BallRecovery', 'BallTouch', 'BlockedPass', 'Card',\n",
" 'Challenge', 'ChanceMissed', 'Chipped', 'Clearance', 'CornerAwarded',\n",
" 'Cross', 'CrossNotClaimed', 'Dispossessed', 'End', 'Error',\n",
" 'FormationChange', 'Foul', 'Goal', 'GoodSkill', 'HeadPass',\n",
" 'Interception', 'KeeperPickup', 'KeeperSweeper', 'LayOff', 'None',\n",
" 'OffsidePass', 'OffsideProvoked', 'Pass', 'PenaltyFaced', 'Punch',\n",
" 'Rebound', 'Save', 'ShieldBallOpp', 'Standard', 'Start',\n",
" 'SubstitutionOn', 'Tackle', 'TakeOn', 'Throughball'],\n",
" dtype='object')\n",
"result\n",
"Index(['BlockedShot', 'Goal', 'MissedShots', 'OwnGoal', 'SavedShot',\n",
" 'ShotOnPost'],\n",
" dtype='object')\n",
"shotType\n",
"Index(['Head', 'LeftFoot', 'OtherBodyPart', 'RightFoot'], dtype='object')\n",
"situation\n",
"Index(['DirectFreekick', 'FromCorner', 'OpenPlay', 'Penalty', 'SetPiece'], dtype='object')\n"
]
}
],
"source": [
"for categ in categs:\n",
" print(categ)\n",
" print(df[categ].cat.categories)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Before we can train the model, we need to remove any OwnGoals that might spoil the model and thus, we do so."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"df = df[df['result'] != 'OwnGoal']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Introducing a binary column by the name of Goal."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"df['goal'] = (df['result'] == 'Goal')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One Hot Encoding for the situation column is done in the DataFrame so that Logistic Regression might not misinterpret the situations as something of different weightages.\n",
"\n",
"LabelBinarizer from sklearn is used to carry out the one hot encoding."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"LabelBinarizer(neg_label=0, pos_label=1, sparse_output=False)"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.preprocessing import LabelBinarizer\n",
"le = LabelBinarizer()\n",
"le.fit(df['situation'])"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"temp = le.transform(df['situation'])"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(['DirectFreekick', 'FromCorner', 'OpenPlay', 'Penalty', 'SetPiece'],\n",
" dtype='\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
X
\n",
"
Y
\n",
"
a_goals
\n",
"
a_team
\n",
"
date
\n",
"
h_a
\n",
"
h_goals
\n",
"
h_team
\n",
"
id
\n",
"
lastAction
\n",
"
...
\n",
"
goal
\n",
"
isDirectFreekick
\n",
"
isFromCorner
\n",
"
isOpenPlay
\n",
"
isPenalty
\n",
"
isSetPiece
\n",
"
fromHead
\n",
"
fromLeftFoot
\n",
"
fromOtherBodyPart
\n",
"
fromRightFoot
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
73.527997
\n",
"
28.804001
\n",
"
0
\n",
"
Hoffenheim
\n",
"
2015-08-29 17:30:00
\n",
"
h
\n",
"
0
\n",
"
Darmstadt
\n",
"
76737
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
1
\n",
"
75.712003
\n",
"
28.347999
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-09-12 17:30:00
\n",
"
a
\n",
"
0
\n",
"
Bayer Leverkusen
\n",
"
76808
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
3
\n",
"
91.000000
\n",
"
39.595999
\n",
"
2
\n",
"
Darmstadt
\n",
"
2015-12-20 20:30:00
\n",
"
a
\n",
"
3
\n",
"
Borussia M.Gladbach
\n",
"
79876
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
96.407997
\n",
"
42.332001
\n",
"
2
\n",
"
Werder Bremen
\n",
"
2014-12-07 16:30:00
\n",
"
a
\n",
"
5
\n",
"
Eintracht Frankfurt
\n",
"
27374
\n",
"
Pass
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
93.496002
\n",
"
45.447999
\n",
"
2
\n",
"
Darmstadt
\n",
"
2015-09-27 19:30:00
\n",
"
a
\n",
"
2
\n",
"
Borussia Dortmund
\n",
"
77444
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
2
\n",
"
101.920000
\n",
"
35.872001
\n",
"
2
\n",
"
Darmstadt
\n",
"
2015-10-17 17:30:00
\n",
"
a
\n",
"
0
\n",
"
Augsburg
\n",
"
78030
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
102.336002
\n",
"
36.175999
\n",
"
2
\n",
"
Darmstadt
\n",
"
2015-10-17 17:30:00
\n",
"
a
\n",
"
0
\n",
"
Augsburg
\n",
"
78029
\n",
"
Rebound
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
4
\n",
"
92.040000
\n",
"
32.907999
\n",
"
0
\n",
"
Darmstadt
\n",
"
2015-11-01 18:30:00
\n",
"
a
\n",
"
2
\n",
"
VfB Stuttgart
\n",
"
78500
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
5
\n",
"
97.967997
\n",
"
48.260000
\n",
"
0
\n",
"
Darmstadt
\n",
"
2015-11-01 18:30:00
\n",
"
a
\n",
"
2
\n",
"
VfB Stuttgart
\n",
"
78501
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
6
\n",
"
99.527997
\n",
"
47.575999
\n",
"
1
\n",
"
Hamburger SV
\n",
"
2015-11-07 21:30:00
\n",
"
h
\n",
"
1
\n",
"
Darmstadt
\n",
"
78849
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
7
\n",
"
94.640000
\n",
"
46.284001
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-12-06 20:30:00
\n",
"
a
\n",
"
0
\n",
"
Eintracht Frankfurt
\n",
"
79502
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
8
\n",
"
95.367997
\n",
"
40.280000
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-12-06 20:30:00
\n",
"
a
\n",
"
0
\n",
"
Eintracht Frankfurt
\n",
"
79514
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
9
\n",
"
97.032003
\n",
"
42.787999
\n",
"
4
\n",
"
Hertha Berlin
\n",
"
2015-12-12 18:30:00
\n",
"
h
\n",
"
0
\n",
"
Darmstadt
\n",
"
79822
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
10
\n",
"
96.927997
\n",
"
36.404001
\n",
"
2
\n",
"
Darmstadt
\n",
"
2015-12-20 20:30:00
\n",
"
a
\n",
"
3
\n",
"
Borussia M.Gladbach
\n",
"
79863
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
11
\n",
"
94.847997
\n",
"
46.512001
\n",
"
2
\n",
"
Bayer Leverkusen
\n",
"
2016-02-13 18:30:00
\n",
"
h
\n",
"
1
\n",
"
Darmstadt
\n",
"
80950
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
12
\n",
"
90.376002
\n",
"
48.868002
\n",
"
0
\n",
"
Darmstadt
\n",
"
2016-03-06 18:30:00
\n",
"
a
\n",
"
0
\n",
"
Mainz 05
\n",
"
81919
\n",
"
Rebound
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
13
\n",
"
90.376002
\n",
"
48.868002
\n",
"
0
\n",
"
Darmstadt
\n",
"
2016-03-06 18:30:00
\n",
"
a
\n",
"
0
\n",
"
Mainz 05
\n",
"
81918
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
14
\n",
"
100.463998
\n",
"
32.527999
\n",
"
2
\n",
"
VfB Stuttgart
\n",
"
2016-04-02 17:30:00
\n",
"
h
\n",
"
2
\n",
"
Darmstadt
\n",
"
82623
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
15
\n",
"
91.416002
\n",
"
39.215999
\n",
"
1
\n",
"
Darmstadt
\n",
"
2016-04-23 17:30:00
\n",
"
a
\n",
"
4
\n",
"
FC Cologne
\n",
"
83244
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
16
\n",
"
77.480000
\n",
"
43.700000
\n",
"
0
\n",
"
Werder Bremen
\n",
"
2016-08-26 22:30:00
\n",
"
a
\n",
"
6
\n",
"
Bayern Munich
\n",
"
127431
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
17
\n",
"
103.063998
\n",
"
46.967999
\n",
"
0
\n",
"
Werder Bremen
\n",
"
2016-08-26 22:30:00
\n",
"
a
\n",
"
6
\n",
"
Bayern Munich
\n",
"
127447
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
98.383998
\n",
"
35.415999
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-08-22 17:30:00
\n",
"
a
\n",
"
1
\n",
"
Schalke 04
\n",
"
76326
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
2
\n",
"
97.032003
\n",
"
34.352001
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-08-22 17:30:00
\n",
"
a
\n",
"
1
\n",
"
Schalke 04
\n",
"
76330
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
99.007997
\n",
"
32.907999
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-09-12 17:30:00
\n",
"
a
\n",
"
0
\n",
"
Bayer Leverkusen
\n",
"
76809
\n",
"
Aerial
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
4
\n",
"
91.312003
\n",
"
37.467999
\n",
"
2
\n",
"
Darmstadt
\n",
"
2015-09-27 19:30:00
\n",
"
a
\n",
"
2
\n",
"
Borussia Dortmund
\n",
"
77459
\n",
"
None
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
5
\n",
"
95.056002
\n",
"
44.384001
\n",
"
0
\n",
"
Darmstadt
\n",
"
2015-11-01 18:30:00
\n",
"
a
\n",
"
2
\n",
"
VfB Stuttgart
\n",
"
78477
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
6
\n",
"
94.223998
\n",
"
43.547999
\n",
"
0
\n",
"
Darmstadt
\n",
"
2015-11-01 18:30:00
\n",
"
a
\n",
"
2
\n",
"
VfB Stuttgart
\n",
"
78498
\n",
"
Chipped
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
7
\n",
"
92.143998
\n",
"
41.495999
\n",
"
1
\n",
"
Hamburger SV
\n",
"
2015-11-07 21:30:00
\n",
"
h
\n",
"
1
\n",
"
Darmstadt
\n",
"
78845
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
8
\n",
"
99.320000
\n",
"
36.404001
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-11-22 20:40:00
\n",
"
a
\n",
"
3
\n",
"
Ingolstadt
\n",
"
79074
\n",
"
Cross
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
9
\n",
"
94.536002
\n",
"
37.315999
\n",
"
1
\n",
"
Darmstadt
\n",
"
2015-12-06 20:30:00
\n",
"
a
\n",
"
0
\n",
"
Eintracht Frankfurt
\n",
"
79498
\n",
"
Cross
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
9
\n",
"
83.096002
\n",
"
27.207999
\n",
"
2
\n",
"
Villarreal
\n",
"
2018-11-11 17:30:00
\n",
"
a
\n",
"
2
\n",
"
Rayo Vallecano
\n",
"
240027
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
10
\n",
"
76.543998
\n",
"
38.835999
\n",
"
1
\n",
"
Real Betis
\n",
"
2018-11-25 19:45:00
\n",
"
h
\n",
"
2
\n",
"
Villarreal
\n",
"
241740
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
11
\n",
"
93.287997
\n",
"
35.112001
\n",
"
1
\n",
"
Real Betis
\n",
"
2018-11-25 19:45:00
\n",
"
h
\n",
"
2
\n",
"
Villarreal
\n",
"
241746
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
12
\n",
"
92.767997
\n",
"
24.927999
\n",
"
1
\n",
"
Real Betis
\n",
"
2018-11-25 19:45:00
\n",
"
h
\n",
"
2
\n",
"
Villarreal
\n",
"
241754
\n",
"
Pass
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
13
\n",
"
88.712003
\n",
"
24.624001
\n",
"
1
\n",
"
Real Betis
\n",
"
2018-11-25 19:45:00
\n",
"
h
\n",
"
2
\n",
"
Villarreal
\n",
"
241757
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
14
\n",
"
95.887997
\n",
"
24.016000
\n",
"
0
\n",
"
Villarreal
\n",
"
2018-12-02 17:30:00
\n",
"
a
\n",
"
2
\n",
"
Barcelona
\n",
"
243092
\n",
"
Rebound
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
15
\n",
"
81.120000
\n",
"
29.944001
\n",
"
0
\n",
"
Villarreal
\n",
"
2018-12-02 17:30:00
\n",
"
a
\n",
"
2
\n",
"
Barcelona
\n",
"
243094
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
79.143998
\n",
"
40.127999
\n",
"
2
\n",
"
Fulham
\n",
"
2018-10-20 14:00:00
\n",
"
h
\n",
"
4
\n",
"
Cardiff
\n",
"
234806
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
0
\n",
"
96.303998
\n",
"
35.112001
\n",
"
2
\n",
"
Udinese
\n",
"
2018-10-28 13:00:00
\n",
"
h
\n",
"
2
\n",
"
Genoa
\n",
"
236059
\n",
"
Cross
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
95.887997
\n",
"
37.467999
\n",
"
0
\n",
"
Genoa
\n",
"
2018-11-03 14:00:00
\n",
"
a
\n",
"
5
\n",
"
Inter
\n",
"
236765
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
2
\n",
"
93.912003
\n",
"
42.484001
\n",
"
2
\n",
"
Napoli
\n",
"
2018-11-10 19:30:00
\n",
"
h
\n",
"
1
\n",
"
Genoa
\n",
"
239498
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
84.343998
\n",
"
35.415999
\n",
"
1
\n",
"
Sampdoria
\n",
"
2018-11-25 19:30:00
\n",
"
h
\n",
"
1
\n",
"
Genoa
\n",
"
241719
\n",
"
Rebound
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
4
\n",
"
96.927997
\n",
"
36.632001
\n",
"
1
\n",
"
Sampdoria
\n",
"
2018-11-25 19:30:00
\n",
"
h
\n",
"
1
\n",
"
Genoa
\n",
"
241725
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
5
\n",
"
92.456002
\n",
"
40.964001
\n",
"
1
\n",
"
Genoa
\n",
"
2018-12-02 14:00:00
\n",
"
a
\n",
"
2
\n",
"
Torino
\n",
"
242821
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
6
\n",
"
83.407997
\n",
"
36.555999
\n",
"
1
\n",
"
Genoa
\n",
"
2018-12-02 14:00:00
\n",
"
a
\n",
"
2
\n",
"
Torino
\n",
"
242824
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
85.383998
\n",
"
42.560000
\n",
"
0
\n",
"
Toulouse
\n",
"
2018-11-24 16:00:00
\n",
"
a
\n",
"
1
\n",
"
Paris Saint Germain
\n",
"
240889
\n",
"
BallRecovery
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
92.352003
\n",
"
43.320000
\n",
"
0
\n",
"
Monaco
\n",
"
2018-11-03 19:00:00
\n",
"
h
\n",
"
1
\n",
"
Reims
\n",
"
237309
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
84.967997
\n",
"
35.264001
\n",
"
1
\n",
"
Guingamp
\n",
"
2018-11-24 19:00:00
\n",
"
h
\n",
"
2
\n",
"
Reims
\n",
"
241121
\n",
"
Chipped
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
98.487997
\n",
"
33.440000
\n",
"
0
\n",
"
Real Valladolid
\n",
"
2018-11-25 15:15:00
\n",
"
a
\n",
"
1
\n",
"
Sevilla
\n",
"
241542
\n",
"
Aerial
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
87.880000
\n",
"
22.800000
\n",
"
1
\n",
"
Wolfsburg
\n",
"
2018-11-09 19:30:00
\n",
"
a
\n",
"
2
\n",
"
Hannover 96
\n",
"
238742
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
0
\n",
"
88.296002
\n",
"
38.075999
\n",
"
4
\n",
"
Paris Saint Germain
\n",
"
2018-11-11 20:00:00
\n",
"
h
\n",
"
0
\n",
"
Monaco
\n",
"
240130
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
0
\n",
"
98.487997
\n",
"
40.584001
\n",
"
1
\n",
"
Eintracht Frankfurt
\n",
"
2018-10-28 11:30:00
\n",
"
h
\n",
"
1
\n",
"
Nuernberg
\n",
"
235992
\n",
"
Chipped
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
91.103998
\n",
"
42.787999
\n",
"
2
\n",
"
Nuernberg
\n",
"
2018-11-03 14:30:00
\n",
"
a
\n",
"
2
\n",
"
Augsburg
\n",
"
236785
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
2
\n",
"
101.192003
\n",
"
24.395999
\n",
"
2
\n",
"
Nuernberg
\n",
"
2018-11-03 14:30:00
\n",
"
a
\n",
"
2
\n",
"
Augsburg
\n",
"
236802
\n",
"
Chipped
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
96.303998
\n",
"
37.620000
\n",
"
2
\n",
"
Nuernberg
\n",
"
2018-11-03 14:30:00
\n",
"
a
\n",
"
2
\n",
"
Augsburg
\n",
"
236807
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
4
\n",
"
100.152003
\n",
"
36.327999
\n",
"
2
\n",
"
Nuernberg
\n",
"
2018-11-24 17:30:00
\n",
"
a
\n",
"
5
\n",
"
Schalke 04
\n",
"
241048
\n",
"
Rebound
\n",
"
...
\n",
"
True
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
0
\n",
"
88.503998
\n",
"
57.075999
\n",
"
1
\n",
"
Atletico Madrid
\n",
"
2018-12-02 15:15:00
\n",
"
h
\n",
"
1
\n",
"
Girona
\n",
"
242927
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
0
\n",
"
96.303998
\n",
"
34.504001
\n",
"
3
\n",
"
Fortuna Duesseldorf
\n",
"
2018-11-24 14:30:00
\n",
"
a
\n",
"
3
\n",
"
Bayern Munich
\n",
"
240596
\n",
"
None
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
78.936002
\n",
"
38.987999
\n",
"
1
\n",
"
Mainz 05
\n",
"
2018-11-30 19:30:00
\n",
"
h
\n",
"
0
\n",
"
Fortuna Duesseldorf
\n",
"
241967
\n",
"
Pass
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
"
\n",
"
2
\n",
"
99.112003
\n",
"
49.020000
\n",
"
1
\n",
"
Mainz 05
\n",
"
2018-11-30 19:30:00
\n",
"
h
\n",
"
0
\n",
"
Fortuna Duesseldorf
\n",
"
241976
\n",
"
Cross
\n",
"
...
\n",
"
False
\n",
"
0
\n",
"
1
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
0
\n",
"
1
\n",
"
\n",
" \n",
"
\n",
"
225797 rows × 31 columns
\n",
""
],
"text/plain": [
" X Y a_goals a_team date \\\n",
"0 73.527997 28.804001 0 Hoffenheim 2015-08-29 17:30:00 \n",
"1 75.712003 28.347999 1 Darmstadt 2015-09-12 17:30:00 \n",
"3 91.000000 39.595999 2 Darmstadt 2015-12-20 20:30:00 \n",
"0 96.407997 42.332001 2 Werder Bremen 2014-12-07 16:30:00 \n",
"1 93.496002 45.447999 2 Darmstadt 2015-09-27 19:30:00 \n",
"2 101.920000 35.872001 2 Darmstadt 2015-10-17 17:30:00 \n",
"3 102.336002 36.175999 2 Darmstadt 2015-10-17 17:30:00 \n",
"4 92.040000 32.907999 0 Darmstadt 2015-11-01 18:30:00 \n",
"5 97.967997 48.260000 0 Darmstadt 2015-11-01 18:30:00 \n",
"6 99.527997 47.575999 1 Hamburger SV 2015-11-07 21:30:00 \n",
"7 94.640000 46.284001 1 Darmstadt 2015-12-06 20:30:00 \n",
"8 95.367997 40.280000 1 Darmstadt 2015-12-06 20:30:00 \n",
"9 97.032003 42.787999 4 Hertha Berlin 2015-12-12 18:30:00 \n",
"10 96.927997 36.404001 2 Darmstadt 2015-12-20 20:30:00 \n",
"11 94.847997 46.512001 2 Bayer Leverkusen 2016-02-13 18:30:00 \n",
"12 90.376002 48.868002 0 Darmstadt 2016-03-06 18:30:00 \n",
"13 90.376002 48.868002 0 Darmstadt 2016-03-06 18:30:00 \n",
"14 100.463998 32.527999 2 VfB Stuttgart 2016-04-02 17:30:00 \n",
"15 91.416002 39.215999 1 Darmstadt 2016-04-23 17:30:00 \n",
"16 77.480000 43.700000 0 Werder Bremen 2016-08-26 22:30:00 \n",
"17 103.063998 46.967999 0 Werder Bremen 2016-08-26 22:30:00 \n",
"1 98.383998 35.415999 1 Darmstadt 2015-08-22 17:30:00 \n",
"2 97.032003 34.352001 1 Darmstadt 2015-08-22 17:30:00 \n",
"3 99.007997 32.907999 1 Darmstadt 2015-09-12 17:30:00 \n",
"4 91.312003 37.467999 2 Darmstadt 2015-09-27 19:30:00 \n",
"5 95.056002 44.384001 0 Darmstadt 2015-11-01 18:30:00 \n",
"6 94.223998 43.547999 0 Darmstadt 2015-11-01 18:30:00 \n",
"7 92.143998 41.495999 1 Hamburger SV 2015-11-07 21:30:00 \n",
"8 99.320000 36.404001 1 Darmstadt 2015-11-22 20:40:00 \n",
"9 94.536002 37.315999 1 Darmstadt 2015-12-06 20:30:00 \n",
".. ... ... ... ... ... \n",
"9 83.096002 27.207999 2 Villarreal 2018-11-11 17:30:00 \n",
"10 76.543998 38.835999 1 Real Betis 2018-11-25 19:45:00 \n",
"11 93.287997 35.112001 1 Real Betis 2018-11-25 19:45:00 \n",
"12 92.767997 24.927999 1 Real Betis 2018-11-25 19:45:00 \n",
"13 88.712003 24.624001 1 Real Betis 2018-11-25 19:45:00 \n",
"14 95.887997 24.016000 0 Villarreal 2018-12-02 17:30:00 \n",
"15 81.120000 29.944001 0 Villarreal 2018-12-02 17:30:00 \n",
"0 79.143998 40.127999 2 Fulham 2018-10-20 14:00:00 \n",
"0 96.303998 35.112001 2 Udinese 2018-10-28 13:00:00 \n",
"1 95.887997 37.467999 0 Genoa 2018-11-03 14:00:00 \n",
"2 93.912003 42.484001 2 Napoli 2018-11-10 19:30:00 \n",
"3 84.343998 35.415999 1 Sampdoria 2018-11-25 19:30:00 \n",
"4 96.927997 36.632001 1 Sampdoria 2018-11-25 19:30:00 \n",
"5 92.456002 40.964001 1 Genoa 2018-12-02 14:00:00 \n",
"6 83.407997 36.555999 1 Genoa 2018-12-02 14:00:00 \n",
"0 85.383998 42.560000 0 Toulouse 2018-11-24 16:00:00 \n",
"0 92.352003 43.320000 0 Monaco 2018-11-03 19:00:00 \n",
"1 84.967997 35.264001 1 Guingamp 2018-11-24 19:00:00 \n",
"0 98.487997 33.440000 0 Real Valladolid 2018-11-25 15:15:00 \n",
"0 87.880000 22.800000 1 Wolfsburg 2018-11-09 19:30:00 \n",
"0 88.296002 38.075999 4 Paris Saint Germain 2018-11-11 20:00:00 \n",
"0 98.487997 40.584001 1 Eintracht Frankfurt 2018-10-28 11:30:00 \n",
"1 91.103998 42.787999 2 Nuernberg 2018-11-03 14:30:00 \n",
"2 101.192003 24.395999 2 Nuernberg 2018-11-03 14:30:00 \n",
"3 96.303998 37.620000 2 Nuernberg 2018-11-03 14:30:00 \n",
"4 100.152003 36.327999 2 Nuernberg 2018-11-24 17:30:00 \n",
"0 88.503998 57.075999 1 Atletico Madrid 2018-12-02 15:15:00 \n",
"0 96.303998 34.504001 3 Fortuna Duesseldorf 2018-11-24 14:30:00 \n",
"1 78.936002 38.987999 1 Mainz 05 2018-11-30 19:30:00 \n",
"2 99.112003 49.020000 1 Mainz 05 2018-11-30 19:30:00 \n",
"\n",
" h_a h_goals h_team id lastAction ... \\\n",
"0 h 0 Darmstadt 76737 Aerial ... \n",
"1 a 0 Bayer Leverkusen 76808 Pass ... \n",
"3 a 3 Borussia M.Gladbach 79876 Aerial ... \n",
"0 a 5 Eintracht Frankfurt 27374 Pass ... \n",
"1 a 2 Borussia Dortmund 77444 None ... \n",
"2 a 0 Augsburg 78030 None ... \n",
"3 a 0 Augsburg 78029 Rebound ... \n",
"4 a 2 VfB Stuttgart 78500 Cross ... \n",
"5 a 2 VfB Stuttgart 78501 Aerial ... \n",
"6 h 1 Darmstadt 78849 Aerial ... \n",
"7 a 0 Eintracht Frankfurt 79502 Cross ... \n",
"8 a 0 Eintracht Frankfurt 79514 Cross ... \n",
"9 h 0 Darmstadt 79822 Aerial ... \n",
"10 a 3 Borussia M.Gladbach 79863 Cross ... \n",
"11 h 1 Darmstadt 80950 Aerial ... \n",
"12 a 0 Mainz 05 81919 Rebound ... \n",
"13 a 0 Mainz 05 81918 Aerial ... \n",
"14 h 2 Darmstadt 82623 Cross ... \n",
"15 a 4 FC Cologne 83244 None ... \n",
"16 a 6 Bayern Munich 127431 None ... \n",
"17 a 6 Bayern Munich 127447 Cross ... \n",
"1 a 1 Schalke 04 76326 Aerial ... \n",
"2 a 1 Schalke 04 76330 Aerial ... \n",
"3 a 0 Bayer Leverkusen 76809 Aerial ... \n",
"4 a 2 Borussia Dortmund 77459 None ... \n",
"5 a 2 VfB Stuttgart 78477 Aerial ... \n",
"6 a 2 VfB Stuttgart 78498 Chipped ... \n",
"7 h 1 Darmstadt 78845 None ... \n",
"8 a 3 Ingolstadt 79074 Cross ... \n",
"9 a 0 Eintracht Frankfurt 79498 Cross ... \n",
".. .. ... ... ... ... ... \n",
"9 a 2 Rayo Vallecano 240027 Pass ... \n",
"10 h 2 Villarreal 241740 None ... \n",
"11 h 2 Villarreal 241746 Pass ... \n",
"12 h 2 Villarreal 241754 Pass ... \n",
"13 h 2 Villarreal 241757 Pass ... \n",
"14 a 2 Barcelona 243092 Rebound ... \n",
"15 a 2 Barcelona 243094 Pass ... \n",
"0 h 4 Cardiff 234806 Pass ... \n",
"0 h 2 Genoa 236059 Cross ... \n",
"1 a 5 Inter 236765 Aerial ... \n",
"2 h 1 Genoa 239498 Cross ... \n",
"3 h 1 Genoa 241719 Rebound ... \n",
"4 h 1 Genoa 241725 Aerial ... \n",
"5 a 2 Torino 242821 Cross ... \n",
"6 a 2 Torino 242824 Aerial ... \n",
"0 a 1 Paris Saint Germain 240889 BallRecovery ... \n",
"0 h 1 Reims 237309 Pass ... \n",
"1 h 2 Reims 241121 Chipped ... \n",
"0 a 1 Sevilla 241542 Aerial ... \n",
"0 a 2 Hannover 96 238742 Pass ... \n",
"0 h 0 Monaco 240130 None ... \n",
"0 h 1 Nuernberg 235992 Chipped ... \n",
"1 a 2 Augsburg 236785 Cross ... \n",
"2 a 2 Augsburg 236802 Chipped ... \n",
"3 a 2 Augsburg 236807 Pass ... \n",
"4 a 5 Schalke 04 241048 Rebound ... \n",
"0 h 1 Girona 242927 Pass ... \n",
"0 a 3 Bayern Munich 240596 None ... \n",
"1 h 0 Fortuna Duesseldorf 241967 Pass ... \n",
"2 h 0 Fortuna Duesseldorf 241976 Cross ... \n",
"\n",
" goal isDirectFreekick isFromCorner isOpenPlay isPenalty isSetPiece \\\n",
"0 False 0 1 0 0 0 \n",
"1 False 0 0 0 0 1 \n",
"3 False 0 1 0 0 0 \n",
"0 True 0 0 1 0 0 \n",
"1 False 0 0 0 0 1 \n",
"2 False 0 1 0 0 0 \n",
"3 False 0 1 0 0 0 \n",
"4 False 0 0 1 0 0 \n",
"5 False 0 1 0 0 0 \n",
"6 False 0 0 0 0 1 \n",
"7 False 0 1 0 0 0 \n",
"8 False 0 0 1 0 0 \n",
"9 False 0 1 0 0 0 \n",
"10 False 0 1 0 0 0 \n",
"11 False 0 0 1 0 0 \n",
"12 False 0 0 0 0 1 \n",
"13 False 0 0 0 0 1 \n",
"14 False 0 1 0 0 0 \n",
"15 False 0 1 0 0 0 \n",
"16 False 0 0 1 0 0 \n",
"17 False 0 1 0 0 0 \n",
"1 False 0 0 0 0 1 \n",
"2 False 0 1 0 0 0 \n",
"3 True 0 0 0 0 1 \n",
"4 True 0 0 0 0 1 \n",
"5 False 0 0 0 0 1 \n",
"6 False 0 0 0 0 1 \n",
"7 False 0 0 1 0 0 \n",
"8 True 0 1 0 0 0 \n",
"9 True 0 0 0 0 1 \n",
".. ... ... ... ... ... ... \n",
"9 False 0 0 1 0 0 \n",
"10 False 0 0 1 0 0 \n",
"11 False 0 0 1 0 0 \n",
"12 True 0 0 1 0 0 \n",
"13 False 0 0 1 0 0 \n",
"14 False 0 0 1 0 0 \n",
"15 False 0 0 1 0 0 \n",
"0 False 0 0 1 0 0 \n",
"0 True 0 1 0 0 0 \n",
"1 False 0 1 0 0 0 \n",
"2 False 0 0 1 0 0 \n",
"3 False 0 0 1 0 0 \n",
"4 False 0 1 0 0 0 \n",
"5 False 0 1 0 0 0 \n",
"6 False 0 0 0 0 1 \n",
"0 False 0 0 1 0 0 \n",
"0 False 0 0 1 0 0 \n",
"1 True 0 0 1 0 0 \n",
"0 False 0 1 0 0 0 \n",
"0 False 0 0 1 0 0 \n",
"0 False 0 1 0 0 0 \n",
"0 True 0 0 1 0 0 \n",
"1 False 0 0 1 0 0 \n",
"2 False 0 0 0 0 1 \n",
"3 False 0 0 1 0 0 \n",
"4 True 0 0 1 0 0 \n",
"0 False 0 0 1 0 0 \n",
"0 False 0 0 0 0 1 \n",
"1 False 0 0 1 0 0 \n",
"2 False 0 1 0 0 0 \n",
"\n",
" fromHead fromLeftFoot fromOtherBodyPart fromRightFoot \n",
"0 0 0 0 1 \n",
"1 0 0 0 1 \n",
"3 1 0 0 0 \n",
"0 0 1 0 0 \n",
"1 0 0 0 1 \n",
"2 0 1 0 0 \n",
"3 0 1 0 0 \n",
"4 0 1 0 0 \n",
"5 1 0 0 0 \n",
"6 1 0 0 0 \n",
"7 1 0 0 0 \n",
"8 1 0 0 0 \n",
"9 1 0 0 0 \n",
"10 1 0 0 0 \n",
"11 1 0 0 0 \n",
"12 0 1 0 0 \n",
"13 0 0 0 1 \n",
"14 1 0 0 0 \n",
"15 0 1 0 0 \n",
"16 0 1 0 0 \n",
"17 0 1 0 0 \n",
"1 1 0 0 0 \n",
"2 1 0 0 0 \n",
"3 1 0 0 0 \n",
"4 0 0 0 1 \n",
"5 1 0 0 0 \n",
"6 1 0 0 0 \n",
"7 0 0 0 1 \n",
"8 1 0 0 0 \n",
"9 1 0 0 0 \n",
".. ... ... ... ... \n",
"9 0 1 0 0 \n",
"10 0 1 0 0 \n",
"11 0 1 0 0 \n",
"12 0 1 0 0 \n",
"13 0 1 0 0 \n",
"14 0 1 0 0 \n",
"15 0 1 0 0 \n",
"0 0 0 0 1 \n",
"0 1 0 0 0 \n",
"1 1 0 0 0 \n",
"2 1 0 0 0 \n",
"3 0 0 0 1 \n",
"4 1 0 0 0 \n",
"5 1 0 0 0 \n",
"6 0 1 0 0 \n",
"0 0 1 0 0 \n",
"0 0 1 0 0 \n",
"1 0 1 0 0 \n",
"0 1 0 0 0 \n",
"0 0 1 0 0 \n",
"0 0 0 0 1 \n",
"0 1 0 0 0 \n",
"1 0 1 0 0 \n",
"2 1 0 0 0 \n",
"3 0 1 0 0 \n",
"4 0 0 0 1 \n",
"0 0 0 0 1 \n",
"0 1 0 0 0 \n",
"1 0 0 0 1 \n",
"2 0 0 0 1 \n",
"\n",
"[225797 rows x 31 columns]"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"Index(['X', 'Y', 'a_goals', 'a_team', 'date', 'h_a', 'h_goals', 'h_team', 'id',\n",
" 'lastAction', 'match_id', 'minute', 'player', 'player_assisted',\n",
" 'player_id', 'result', 'season', 'shotType', 'situation', 'distance',\n",
" 'angle', 'goal', 'isDirectFreekick', 'isFromCorner', 'isOpenPlay',\n",
" 'isPenalty', 'isSetPiece', 'fromHead', 'fromLeftFoot',\n",
" 'fromOtherBodyPart', 'fromRightFoot'],\n",
" dtype='object')"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.columns"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Oh Boi, that's a lot of columns. Not to worry though. We will not be using all of them. Only a subset, atleast for this model. This subset is stored in the cols list"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"cols = ['distance','angle','isDirectFreekick','isFromCorner','isOpenPlay','isPenalty','isSetPiece','fromHead','fromLeftFoot','fromOtherBodyPart','fromRightFoot','goal']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We create a new DataFrame by the name of shot to store the subset data from the selected columns."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"shot = df[cols]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The aim of this whole endeavour is to make a model which will output wether a shot is goal or not. Thus, the goal feature is taken as a series by the name of Y and the rest of the independent features are stored in the DataFrame X."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"X=shot.drop('goal',axis=1)\n",
"Y=shot['goal']"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['distance', 'angle', 'isDirectFreekick', 'isFromCorner', 'isOpenPlay',\n",
" 'isPenalty', 'isSetPiece', 'fromHead', 'fromLeftFoot',\n",
" 'fromOtherBodyPart', 'fromRightFoot'],\n",
" dtype='object')"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X.columns"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Y series currently consists of values in the form of True and False but we would like it to be a binary value i.e. 1 or 0. Thus, we use LabelEncoder available in the sklearn library."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.preprocessing import LabelEncoder\n",
"le = LabelEncoder()\n",
"Y=le.fit_transform(Y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will have to construct both a train data set and test data set to check the validity of our model.\n",
"Thus, we break up our dataset into two parts in 70:30 ratio. 70% of shots are present in the training set and the rest 30% are used as an hold-out test set."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### MODEL FITTING & TESTING"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lo and Behold, we are finally at the point to train the model. The first Model that I'm using here is Logistic Regression because it is realtively cheaper computationally."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\sklearn\\cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.\n",
" \"This module will be removed in 0.20.\", DeprecationWarning)\n"
]
},
{
"data": {
"text/plain": [
"LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
" intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,\n",
" penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
" verbose=0, warm_start=False)"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.cross_validation import train_test_split\n",
"\n",
"reg = LogisticRegression()\n",
"\n",
"X_train,X_test,Y_train,Y_test = train_test_split(X,Y,test_size=0.3,random_state=42)\n",
"\n",
"reg.fit(X_train,Y_train)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9048863300856215"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"reg.score(X_test,Y_test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We obtain an accuracy of 90.4% which is decent considering the size of data. Moreover, we did not take a lot of features into account."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"90% sounds good but it's classifying wheteher a shot is a goal or not and the dataset is skewed towards having a lot more shots as not a goal in comaprisons to ones which actually ended up being a goal."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Thus, judging the performance of a model based on just the accuracy is not a good practice. Let's look at the predictions themselves with the help of a confusion matrix."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[60210 442]\n",
" [ 6001 1087]]\n"
]
}
],
"source": [
"preds = reg.predict(X_test)\n",
"\n",
"from sklearn.metrics import confusion_matrix\n",
"confusion_matrix = confusion_matrix(Y_test,preds)\n",
"print(confusion_matrix)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Confusion Matrix shows us Exactly how the model performed in terms of raw output. The top left value indicates shots that were rightly predicted as not goals. The righta are shots that were predicted as goals but were not.\n",
"\n",
"The second row contains shots that were classified as not goal but were infact, goals. On the right of it, we have the shots that were correctly classified as goals."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another tool to look at the performance of the model is an ROC curve. The area under ROC curve for our model is 80% which is quite good."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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2aMYJ5olXKLIbFGUeNfTtm02w69MGejWDa69Fi67zOszOZeH1NRUqlatSt26dRH/X4k5VWXt2rWkpqZSr169Yntd73qKxvjx0KwZvPKK3b70Uivk5x985/KUlpZGzZo1PUmUEBGhZs2axd6CS7hEUaJdT3//DXfeCSecAJs2JXC5WufC40miZMVifyds11PME8WPP1oRv4UL4eab4YknoFq1GL+pc87Fn4RrUaSnQ9WqJVAQMD3d3uSHH6zLyZOEcwnrs88+Q0T4/fff/7lv9OjRnJ9tmcyuXbsyZMgQwAbi7733Xg4//HAaN25M8+bN+fLLL4scyxNPPEH9+vU58sgj+TpzDlY23333Hc2aNaNp06a0bt2aecHaCtu2baNjx47Ur1+fFi1asGjRoiLHE42ESxQZGTFsTQwdai0HsCJ+M2fCSSfF6M2ccyVl0KBBtG7dmsGDB0f9nP/7v/9jxYoVzJgxgxkzZjBixAg2bdpUpDhmzZrF4MGDmTlzJl999RU333wzGZn96RFuuukm3n//faZOncoVV1zBY489BsCAAQOoUaMG8+bN48477+See+4pUjzRSsiup2I/4+nPP+G22+Djj23QukcPq8/kRfycKzZ33GHTjopT06bw/PN5b7N582bGjRvHqFGjuPDCC+nVq1e+r7tlyxb69evHwoULqVChAgD7778/HTp0KFK8w4YNo1OnTlSoUIF69epRv359JkyYQKtWrXbZTkT466+/ANi4cSMHBafgDxs27J/4L730Um699VZUNebjQAn3TZieXowtClV47z37BG/eDI8/Dj17JthCF865vAwdOpS2bdtyxBFHsPfee/Prr7/SrFmzPJ8zb9486tSpQ7UoupzvvPNORo0atdv9nTp14t57793lvmXLltGyZct/bteuXZtly5bt9tz+/ftz7rnnsueee1KtWjXGjx//z/MPDlZsK1euHNWrV2ft2rXss88++cZZFKU7USxZYnMiUlJsdnWDBsX0ws657PI78o+VQYMGcccddwD25T1o0CCaNWuW61F4QY/O+/TpE/W2qhrV+/Xp04eRI0fSokULnn76ae666y769+8f9fOLW8IliiLXecos4nfOOVbEb9w4q/bq9ZmcSzpr167l+++/Z8aMGYgIGRkZiAi9e/emZs2arF+/fpft161bxz777EP9+vVZsmQJmzZtomrVqnm+R0FaFLVr12bp0qX/3E5NTf2nWynT6tWrmTZtGi1atACgY8eOtG3bdpfn165dm/T0dDZu3MjeJTFXQFUT6gLH6f33a+HMmaPapo0qqI4eXcgXcc5Fa9asWaG+/+uvv67du3ff5b6TTjpJx4wZo2lpaVq3bt1/Yly0aJHWqVNHN2zYoKqqPXv21K5du+q2bdtUVXX58uX67rvvFimeGTNm6DHHHKNpaWm6YMECrVevnqanp++yzY4dO7RmzZo6Z84cVVXt37+/XnLJJaqq+vLLL+sNN9ygqqqDBg3Syy67LMf3yWm/A5O0kN+7CdeigEJ0PaWnw7PPwkMPwZ57wptv+tlMzpUCgwYN2u2ovn379nzwwQe0adOG9957j2uuuYa0tDT22GMP+vfvT/Xq1QF47LHHeOCBB2jYsCEVK1akcuXKPPLII0WKp1GjRnTo0IGGDRtSrlw5XnnlFcoGvRnnnnsu/fv356CDDqJfv360b9+eMmXKUKNGDQYOHAjAddddx1VXXUX9+vXZe++9C3QWV1GI5tDnFc9EUvSttybRpUsBnnT22fDNN3DJJTYnIiEW3HYu8c2ePZujjjoq7DBKnZz2u4hMVtWUwrxe8rYo0tLs7KWyZaF7d7u0bx/z2JxzLtkk3IQ7iCJRjBtnJ1hnFvFr396ThHPOFVJCJopcz3ravBluv90WEUpLA2/yOhe6ROveTnSx2N8JmShybFH88AM0bgwvvwy33gozZsCZZ5Z4bM65LBUrVmTt2rWeLEqIButRVKxYsVhfN7nGKCpVsqqvJ55YovE453JWu3ZtUlNTWb16ddihlBqZK9wVp4Q766ls2RTNyJhkNz79FH7/Hf7zH7udkeET55xzLgdFOesppl1PItJWROaIyDwRuTeHxyuIyIfB47+ISN38XrNsWWDlSltlrn17+Owz2L494kHnnHPFKWaJQkTKAq8A5wANgctFpGG2za4D1qtqfaAP8FR+r7u3rrVB6s8/t5LgP/1klV6dc87FRCxbFM2Beaq6QFW3A4OBdtm2aQe8HVwfApwu+VS4qpW+2Aatp02De+/1Sq/OORdjsRzMrgUsjbidCrTIbRtVTReRjUBNYE3kRiLSHege3NwmY8fO8EqvAOxDtn1Vivm+yOL7IovviyxHFvaJsUwUObUMso+cR7MNqvoG8AaAiEwq7IBMsvF9kcX3RRbfF1l8X2QRkUmFfW4su55SgYMjbtcGlue2jYiUA6oD62IYk3POuQKKZaKYCBwuIvVEpDzQCRiebZvhQGZ5v0uB7zXRztd1zrkkF7Oup2DM4Vbga6AsMFBVZ4rII1hd9OHAAOBdEZmHtSQ6RfHSb8Qq5gTk+yKL74ssvi+y+L7IUuh9kXAT7pxzzpWshKz15JxzruR4onDOOZenuE0UsSj/kaii2Bd3icgsEZkuIt+JyCFhxFkS8tsXEdtdKiIqIkl7amQ0+0JEOgSfjZki8kFJx1hSovgfqSMio0RkSvB/cm4YccaaiAwUkVUiMiOXx0VEXgz203QRaRbVCxd2se1YXrDB7/nAoUB5YBrQMNs2NwOvB9c7AR+GHXeI++JUoFJw/abSvC+C7aoCY4DxQErYcYf4uTgcmALUCG7vF3bcIe6LN4CbgusNgUVhxx2jfXES0AyYkcvj5wJfYnPYWgK/RPO68dqiiEn5jwSV775Q1VGquiW4OR6bs5KMovlcADwK9AbSSjK4EhbNvrgeeEVV1wOo6qoSjrGkRLMvFKgWXK/O7nO6koKqjiHvuWjtgHfUjAf2EpED83vdeE0UOZX/qJXbNqqaDmSW/0g20eyLSNdhRwzJKN99ISLHAger6uclGVgIovlcHAEcISLjRGS8iLQtsehKVjT7ohdwpYikAiOB20omtLhT0O8TIH4XLiq28h9JIOrfU0SuBFKAk2MaUXjy3BciUgarQty1pAIKUTSfi3JY99MpWCvzRxFprKobYhxbSYtmX1wOvKWqz4pIK2z+VmNV3Rn78OJKob4347VF4eU/skSzLxCRM4D7gQtVdVsJxVbS8tsXVYHGwGgRWYT1wQ5P0gHtaP9HhqnqDlVdCMzBEkeyiWZfXAd8BKCqPwMVsYKBpU1U3yfZxWui8PIfWfLdF0F3S18sSSRrPzTksy9UdaOq7qOqdVW1LjZec6GqFroYWhyL5n9kKHaiAyKyD9YVtaBEoywZ0eyLJcDpACJyFJYoSuP6rMOBq4Ozn1oCG1V1RX5PisuuJ41d+Y+EE+W+eBqoAnwcjOcvUdULQws6RqLcF6VClPvia+AsEZkFZAA9VXVteFHHRpT7ogfQT0TuxLpauibjgaWIDMK6GvcJxmMeAvYAUNXXsfGZc4F5wBbgmqheNwn3lXPOuWIUr11Pzjnn4oQnCuecc3nyROGccy5Pniicc87lyROFc865PHmicHFHRDJEZGrEpW4e29bNrVJmAd9zdFB9dFpQ8uLIQrzGjSJydXC9q4gcFPFYfxFpWMxxThSRplE85w4RqVTU93allycKF4+2qmrTiMuiEnrfzqraBCs2+XRBn6yqr6vqO8HNrsBBEY91U9VZxRJlVpyvEl2cdwCeKFyheaJwCSFoOfwoIr8GlxNy2KaRiEwIWiHTReTw4P4rI+7vKyJl83m7MUD94LmnB2sY/BbU+q8Q3P+kZK0B8kxwXy8RuVtELsVqbr0fvOeeQUsgRURuEpHeETF3FZGXChnnz0QUdBOR10RkktjaEw8H992OJaxRIjIquO8sEfk52I8fi0iVfN7HlXKeKFw82jOi2+mz4L5VwJmq2gzoCLyYw/NuBF5Q1abYF3VqUK6hI3BicH8G0Dmf978A+E1EKgJvAR1V9WisksFNIrI3cDHQSFWPAR6LfLKqDgEmYUf+TVV1a8TDQ4BLIm53BD4sZJxtsTIdme5X1RTgGOBkETlGVV/EavmcqqqnBqU8HgDOCPblJOCufN7HlXJxWcLDlXpbgy/LSHsALwd98hlY3aLsfgbuF5HawKeqOldETgeOAyYG5U32xJJOTt4Xka3AIqwM9ZHAQlX9I3j8beAW4GVsrYv+IvIFEHVJc1VdLSILgjo7c4P3GBe8bkHirIyVq4hcoayDiHTH/q8PxBbomZ7tuS2D+8cF71Me22/O5coThUsUdwJ/Ak2wlvBuixKp6gci8gtwHvC1iHTDyiq/rar3RfEenSMLCIpIjuubBLWFmmNF5joBtwKnFeB3+RDoAPwOfKaqKvatHXWc2CpuTwKvAJeISD3gbuB4VV0vIm9hhe+yE+B/qnp5AeJ1pZx3PblEUR1YEawfcBV2NL0LETkUWBB0twzHumC+Ay4Vkf2CbfaW6NcU/x2oKyL1g9tXAT8EffrVVXUkNlCc05lHm7Cy5zn5FLgIWyPhw+C+AsWpqjuwLqSWQbdVNeBvYKOI7A+ck0ss44ETM38nEakkIjm1zpz7hycKlyheBbqIyHis2+nvHLbpCMwQkalAA2zJx1nYF+o3IjId+B/WLZMvVU3Dqmt+LCK/ATuB17Ev3c+D1/sBa+1k9xbweuZgdrbXXQ/MAg5R1QnBfQWOMxj7eBa4W1WnYetjzwQGYt1Zmd4AvhSRUaq6Gjsja1DwPuOxfeVcrrx6rHPOuTx5i8I551yePFE455zLkycK55xzefJE4ZxzLk+eKJxzzuXJE4Vzzrk8eaJwzjmXp/8HTs/+UZ06GZAAAAAASUVORK5CYII=\n",
"text/plain": [
"