Map play prediction


In [2]:
import pandas as pd
import numpy as np
import pymc3 as pm
import seaborn as sns
import datetime as dt
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
%matplotlib inline

In [3]:
h_bp = pd.read_csv('hltv_csv/picksAndBans.csv').set_index('Match ID')
h_matches = pd.read_csv('hltv_csv/matchResults.csv').set_index('Match ID')[['Date', 'Team 1 ID', 'Team 2 ID', 'Map']]
h_matches.columns = ['Date', 'Team 1 ID', 'Team 2 ID', 'Map Played']
h_bp = h_bp.join(h_matches, how='left')
h_bp['Date'] = pd.to_datetime(h_bp['Date'])
h_matches['Date'] = pd.to_datetime(h_matches['Date'])
h_teams = pd.read_csv('hltv_csv/teams.csv').set_index('ID')

Training/Validation Set


In [4]:
train = h_bp[(h_bp.Date < dt.datetime(2017,6,1)) & (h_bp.Date >= dt.datetime(2017,1,1))]
train_matches = h_matches[(h_matches.Date < dt.datetime(2017,6,1)) & (h_matches.Date >= dt.datetime(2017,1,1))]
valid = h_bp[h_bp.Date >= dt.datetime(2017,6,1)]
valid_matches = h_matches[(h_matches.Date >= dt.datetime(2017,6,1))]

Models

  1. Avg Most Picked
  2. Avg Least Banned
  3. Avg Most picked+Most banned^-1
  4. Avg Most Played
  5. Logistic Regression

In [5]:
filt = np.load('saved_model/eslpl/filter_teams.npy')
team_ids = np.load('saved_model/eslpl/teams.npy')
ht_filt = h_teams.loc[team_ids]
ht_filt = ht_filt[ht_filt.Name.isin(filt)]

In [59]:
def model_mp(train, t1, t2):
    tab = train[train['Team'].isin([t1, t2])].groupby(['Team', ' Pick Type', 'Map'])['Date'].count().unstack([' Pick Type', 'Team']).fillna(0)
    tab = (tab['picked']/tab['picked'].sum(axis=0)).mean(axis=1)# get average
    return (tab/tab.sum(axis=0)) # normalize

def model_mb(train, t1, t2):
    tab = train[train['Team'].isin([t1, t2])].groupby(['Team', ' Pick Type', 'Map'])['Date'].count().unstack([' Pick Type', 'Team']).fillna(0)
    tab = (tab['removed']/tab['removed'].sum(axis=0)).mean(axis=1)# get average
    return (tab/tab.sum(axis=0)) # normalize

def model_mix(train, t1, t2):
    tab = train[train['Team'].isin([t1, t2])].groupby(['Team', ' Pick Type', 'Map'])['Date'].count().unstack([' Pick Type', 'Team']).fillna(0)
    tab = (tab/tab.sum(axis=0)).mean(level=0,axis=1)
    tab['removed'] = (tab['removed']**-1)/(tab['removed']**-1).sum(axis=0)
    return tab.mean(axis=1)

def model_played(train, t1, t2):
    a = train[train['Team 1 ID'].isin([t1,t2])].groupby(['Team 1 ID', 'Map Played'])['Date'].count()
    b = train[train['Team 2 ID'].isin([t1,t2])].groupby(['Team 2 ID', 'Map Played'])['Date'].count()
    c = pd.DataFrame([a,b], index=['a','b']).T.fillna(0)
    c = (c['a']+c['b']).unstack(level=0).fillna(0)
    return (c/c.sum()).mean(axis=1)

In [62]:
err = []
for i in range(len(filt)):
    for j in range(i+1,len(filt)):
        t1 = ht_filt[ht_filt.Name == filt[i]].index[0]; t2 = ht_filt[ht_filt.Name == filt[j]].index[0]
        hup_m = valid_matches[(((valid_matches['Team 1 ID'] == t1)&(valid_matches['Team 2 ID'] == t2)) | 
                  ((valid_matches['Team 2 ID'] == t1)&(valid_matches['Team 1 ID'] == t2)))]
        if(len(hup_m) >= 8):
            predicted = model_played(train_matches, t1, t2)
            actual = hup_m.groupby('Map Played')['Date'].count()/hup_m.groupby('Map Played')['Date'].count().sum()
            df = pd.DataFrame([predicted, actual], index=['pred', 'y']).fillna(0).T.sort_values('pred', ascending=False)
            print('%s vs %s' % (filt[i], filt[j]))
            print(df)
            err.append(((df['pred']-df['y'])**2).sum())


OpTic vs Misfits
                 pred    y
Cobblestone  0.219058  0.0
Train        0.199367  0.2
Mirage       0.191062  0.3
Cache        0.126285  0.3
Inferno      0.096957  0.1
Nuke         0.086653  0.0
Overpass     0.064444  0.1
Dust2        0.016173  0.0
OpTic vs NRG
                 pred         y
Cobblestone  0.231364  0.090909
Train        0.189721  0.090909
Inferno      0.165539  0.181818
Mirage       0.149638  0.181818
Cache        0.103207  0.090909
Overpass     0.090204  0.181818
Nuke         0.063958  0.181818
Dust2        0.006369  0.000000
SK vs Cloud9
                 pred      y
Cache        0.200027  0.000
Cobblestone  0.184834  0.375
Mirage       0.171990  0.125
Train        0.166364  0.375
Inferno      0.157195  0.125
Overpass     0.069940  0.000
Nuke         0.037603  0.000
Default      0.006024  0.000
Dust2        0.006024  0.000
SK vs Liquid
                 pred    y
Cobblestone  0.240216  0.3
Mirage       0.160252  0.1
Cache        0.159907  0.0
Inferno      0.145538  0.3
Train        0.119715  0.1
Overpass     0.092433  0.2
Nuke         0.063522  0.0
Dust2        0.012394  0.0
Default      0.006024  0.0
Cloud9 vs Luminosity
                 pred      y
Cobblestone  0.194543  0.000
Train        0.176286  0.250
Cache        0.156511  0.375
Mirage       0.149205  0.250
Inferno      0.137847  0.125
Overpass     0.103959  0.000
Nuke         0.069885  0.000
Dust2        0.011765  0.000
Cloud9 vs Immortals
                 pred         y
Cobblestone  0.268216  0.000000
Inferno      0.185515  0.222222
Cache        0.164653  0.333333
Mirage       0.139592  0.111111
Train        0.127684  0.333333
Overpass     0.073650  0.000000
Nuke         0.034591  0.000000
Dust2        0.006098  0.000000
Liquid vs Luminosity
                 pred         y
Cobblestone  0.249925  0.272727
Mirage       0.137467  0.181818
Train        0.129637  0.181818
Overpass     0.126452  0.000000
Inferno      0.126190  0.363636
Cache        0.116392  0.000000
Nuke         0.095804  0.000000
Dust2        0.018134  0.000000
Liquid vs Astralis
                 pred         y
Inferno      0.175897  0.333333
Nuke         0.169781  0.000000
Cobblestone  0.166111  0.000000
Train        0.153984  0.111111
Mirage       0.123170  0.222222
Cache        0.103556  0.111111
Overpass     0.094508  0.222222
Dust2        0.012992  0.000000
Luminosity vs Misfits
                 pred         y
Cobblestone  0.195098  0.000000
Mirage       0.194771  0.222222
Train        0.163399  0.222222
Cache        0.137582  0.444444
Overpass     0.117647  0.000000
Inferno      0.108497  0.000000
Nuke         0.061438  0.111111
Dust2        0.021569  0.000000
Luminosity vs Ghost
                 pred      y
Cobblestone  0.214246  0.125
Mirage       0.203401  0.250
Train        0.197610  0.375
Inferno      0.146691  0.000
Overpass     0.103860  0.000
Cache        0.087132  0.125
Nuke         0.035294  0.125
Dust2        0.011765  0.000
Luminosity vs NRG
                 pred         y
Cobblestone  0.207404  0.272727
Inferno      0.177079  0.090909
Train        0.153753  0.181818
Mirage       0.153347  0.181818
Overpass     0.143408  0.000000
Cache        0.114503  0.272727
Nuke         0.038742  0.000000
Dust2        0.011765  0.000000
Renegades vs CLG
                 pred      y
Cobblestone  0.237827  0.375
Mirage       0.229003  0.125
Cache        0.173979  0.125
Train        0.168096  0.250
Overpass     0.082598  0.000
Inferno      0.047059  0.125
Nuke         0.041667  0.000
Dust2        0.019771  0.000
Renegades vs NRG
                 pred         y
Cobblestone  0.242289  0.333333
Mirage       0.214703  0.111111
Train        0.145378  0.222222
Cache        0.138482  0.222222
Inferno      0.124138  0.000000
Overpass     0.076006  0.111111
Nuke         0.045115  0.000000
Dust2        0.013889  0.000000
Immortals vs CLG
                 pred         y
Cobblestone  0.276614  0.111111
Cache        0.158142  0.111111
Mirage       0.158034  0.000000
Inferno      0.147669  0.222222
Train        0.127869  0.444444
Overpass     0.119692  0.111111
Dust2        0.011980  0.000000
Immortals vs fnatic
                 pred      y
Cobblestone  0.236091  0.125
Inferno      0.201917  0.250
Train        0.157281  0.250
Mirage       0.139407  0.125
Cache        0.132652  0.125
Overpass     0.103678  0.125
Dust2        0.015901  0.000
Nuke         0.013072  0.000
Splyce vs compLexity
                 pred         y
Cache        0.197593  0.000000
Cobblestone  0.194557  0.222222
Train        0.190396  0.333333
Mirage       0.152946  0.000000
Overpass     0.104139  0.111111
Inferno      0.086820  0.333333
Nuke         0.056118  0.000000
Dust2        0.017431  0.000000
mousesports vs fnatic
                 pred         y
Cobblestone  0.186453  0.222222
Mirage       0.179994  0.222222
Train        0.148897  0.444444
Cache        0.135034  0.111111
Inferno      0.128651  0.000000
Nuke         0.110728  0.000000
Overpass     0.084814  0.000000
Dust2        0.025429  0.000000
EnVyUs vs Heroic
                 pred         y
Train        0.216766  0.166667
Nuke         0.210014  0.083333
Cobblestone  0.131318  0.083333
Mirage       0.126141  0.000000
Inferno      0.120871  0.416667
Overpass     0.076642  0.250000
Cache        0.075525  0.000000
Dust2        0.042724  0.000000
EnVyUs vs Heroic
                 pred         y
Train        0.216766  0.166667
Nuke         0.210014  0.083333
Cobblestone  0.131318  0.083333
Mirage       0.126141  0.000000
Inferno      0.120871  0.416667
Overpass     0.076642  0.250000
Cache        0.075525  0.000000
Dust2        0.042724  0.000000

In [65]:
print(np.mean(err))


0.106895165315

In [118]:
err = []
for i,r in valid_matches[valid_matches['Team 1 ID'].isin(ht_filt.index) & valid_matches['Team 2 ID'].isin(ht_filt.index)].iterrows():
    t1 = r['Team 1 ID']; t2 = r['Team 2 ID']
    t1_name = ht_filt.loc[t1].Name; t2_name = ht_filt.loc[t2].Name;
    predicted = model_played(train_matches, t1, t2).sort_values().tail(1).index[0]
    #predicted = model_mp(train, t1_name, t2_name).sort_values().tail(1).index[0]
    err.append([predicted, r['Map Played']])
err = np.array(err)

In [119]:
from sklearn.metrics import accuracy_score
accuracy_score(err[:,1], err[:,0])


Out[119]:
0.16307692307692306

In [117]:
accuracy_score(err[:,1], err[:,0])


Out[117]:
0.21230769230769231

In [111]:
accuracy_score(err[:,1], err[:,0])


Out[111]:
0.13230769230769232

In [115]:
accuracy_score(err[:,1], err[:,0])


Out[115]:
0.067692307692307691

In [ ]: