<jupyter_start><jupyter_text>Football Predictor Model In this notebook we develop a football match result predictor from scratch with sklearn library, testing differents models and compare performance of each one. The idea is then use this model for a more complex system, create a API Rest  Load, clean and Transform data<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import pandas as pd
import numpy as np
import matplotlib.ticker as ticker
from sklearn import preprocessing
from sklearn import metrics
df = pd.read_csv('dataset.csv')
df.head()
df['result'] = df.apply(lambda x : 'wins' if x.home_score > x.away_score else 'loses' if x.home_score < x.away_score else 'draws', axis=1)
df.head()
# dic = eval(df['home_team'].values)
teams = list(dict.fromkeys(df['home_team'].values.tolist() + df['away_team'].values.tolist()))
dic = { teams[i] : (i+1) for i in range(len(teams)) } 
df['home_team_id']= df['home_team'].map(dic) 
df['away_team_id']= df['away_team'].map(dic) 
df.head()
X = df[ ['home_team_id', 'away_team_id'] ].values
X[0:5]
y = df['result'].values
y[0:5]
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=4)
print ('Train set:', X_train.shape,  y_train.shape)
print ('Test set:', X_test.shape,  y_test.shape)

classifier = []
accuracy = []<jupyter_output>Train set: (33268, 2) (33268,)
Test set: (8318, 2) (8318,)<jupyter_text>Compare classifiers<jupyter_code>from sklearn.neighbors import KNeighborsClassifier

MAX_K = 50
mean_acc = np.zeros((MAX_K-1))
std_acc = np.zeros((MAX_K-1))
ConfustionMx = [];
for n in range(1,MAX_K):
    
    #Train Model
    model = KNeighborsClassifier(n_neighbors = n).fit(X_train,y_train)
    # Predict
    yhat = model.predict(X_test)
    
    # Measure accuracy from model with K = n
    mean_acc[n-1] = metrics.accuracy_score(y_test, yhat)    
    std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])

# Now I plot results and choose the best K
plt.plot(range(1,MAX_K),mean_acc,'g')
plt.fill_between(range(1,MAX_K),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)
plt.legend(('Accuracy ', '+/- 3xstd'))
plt.ylabel('Accuracy ')
plt.xlabel('Number of Nabors (K)')
plt.tight_layout()
plt.show()

print( "The best accuracy was with", mean_acc.max(), "with k=", mean_acc.argmax()+1)
KNN_K = mean_acc.argmax()+1
KNN = KNeighborsClassifier(n_neighbors = KNN_K).fit(X_train,y_train)
classifier.append("KNeighborsClassifier")
accuracy.append(mean_acc.max())
from sklearn.tree import DecisionTreeClassifier

MAX_DEPTH = 50
mean_acc = np.zeros((MAX_K-1))
std_acc = np.zeros((MAX_K-1))
ConfustionMx = [];
for n in range(1,MAX_DEPTH):
    
    #Train Model
    model = DecisionTreeClassifier(criterion="entropy", max_depth = n).fit(X_train,y_train)
    # Predict
    yhat = model.predict(X_test)
    
    # Measure accuracy from model with depth = n
    mean_acc[n-1] = metrics.accuracy_score(y_test, yhat)    
    std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])

# Now I plot results and choose the best K
plt.plot(range(1,MAX_DEPTH),mean_acc,'g')
plt.fill_between(range(1,MAX_DEPTH),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)
plt.legend(('Accuracy ', '+/- 3xstd'))
plt.ylabel('Accuracy ')
plt.xlabel('Max depth (K)')
plt.tight_layout()
plt.show()

print( "The best accuracy was with", mean_acc.max(), "with depth=", mean_acc.argmax()+1)
DT_DEPTH = mean_acc.argmax()+1
DT = DecisionTreeClassifier(criterion="entropy", max_depth = DT_DEPTH).fit(X_train,y_train)
classifier.append("DecisionTreeClassifier")
accuracy.append(mean_acc.max())
from sklearn.linear_model import LogisticRegression

MAX_C = 50
logloss_liblinear = np.zeros((MAX_C-1))
mean_acc_liblinear = np.zeros((MAX_C-1))
for n in range(1,MAX_C):
    
    #Train Model
    lr = LogisticRegression(C=(n/100), solver='liblinear').fit(X_train,y_train)
    # Predict
    yhat = lr.predict(X_test)
    
    # Measure accuracy from model with C = n
#     logloss_liblinear[n-1] = log_loss(y_test, yhat)
    mean_acc_liblinear[n-1] = metrics.accuracy_score(y_test, yhat)
    
logloss_sag = np.zeros((MAX_C-1))
mean_acc_sag = np.zeros((MAX_C-1))
std_acc_sag = np.zeros((MAX_C-1))
for n in range(1,MAX_C):
    
    #Train Model
    lr = LogisticRegression(C=(n/100), solver='sag').fit(X_train,y_train)
    # Predict
    yhat = lr.predict(X_test)
    
    # Measure accuracy from model with C = n
#     logloss_sag[n-1] = log_loss(y_test, yhat)
    mean_acc_sag[n-1] = metrics.accuracy_score(y_test, yhat)    
    std_acc_sag[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])

# Now I plot results and choose the best model
plt.plot(range(1,MAX_C),mean_acc_liblinear,'g')
plt.plot(range(1,MAX_C),mean_acc_sag,'b')
plt.legend(('liblinear ', 'sag'))
plt.ylabel('Accuracy ')
plt.xlabel('Regularization (C)')
plt.tight_layout()
plt.show()

print( "The best accuracy liblinear was with", mean_acc_liblinear.max(), "with C=", (mean_acc_liblinear.argmax()+1)/100)
print( "The best accuracy sag was with", mean_acc_sag.max(), "with C=", (mean_acc_sag.argmax()+1)/100)
classifier.append("LogisticRegression")
accuracy.append(mean_acc_liblinear.max())
from sklearn.ensemble  import RandomForestClassifier
RF = RandomForestClassifier(n_estimators = 200, random_state = 1, class_weight = 'balanced')
RF.fit(X_train,y_train)

yhat = RF.predict(X_test)
mean_acc = metrics.accuracy_score(y_test, yhat)
print( "Accuracy RandomForest was", mean_acc)
classifier.append("RandomForestClassifier")
accuracy.append(mean_acc)
from sklearn.ensemble  import AdaBoostClassifier
AB = AdaBoostClassifier(n_estimators = 200, random_state = 2)
AB.fit(X_train,y_train)

yhat = AB.predict(X_test)
mean_acc = metrics.accuracy_score(y_test, yhat)
print( "Accuracy AdaBoost was", mean_acc)
classifier.append("AdaBoostClassifier")
accuracy.append(mean_acc)
from sklearn.naive_bayes  import GaussianNB
GNB = GaussianNB()
GNB.fit(X_train,y_train)

yhat = GNB.predict(X_test)
mean_acc = metrics.accuracy_score(y_test, yhat)
print( "Accuracy GaussianNB was", mean_acc)
classifier.append("GaussianNB")
accuracy.append(mean_acc)
import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt

y_pos = np.arange(len(classifier))
plt.barh(y_pos, accuracy, align='center', alpha=0.5)
plt.yticks(y_pos, classifier)
plt.xlabel('Accuracy')
plt.title('Classifier type')<jupyter_output><empty_output><jupyter_text>Based on resultds we adapt the following classifier for our footbal predictor model:<jupyter_code>model  = AdaBoostClassifier(n_estimators = 200, random_state = 2).fit(X_train,y_train)<jupyter_output><empty_output><jupyter_text>Test our model Is time to test our model, we first test it in an scenario that never occurs, football match between Argentina and Galicia. We expect to Argentina wins this match :)<jupyter_code>index = df.index[((df['home_team'] == 'Argentina') & (df['away_team'] == 'Galicia')) | 
                (df['home_team'] == 'Galicia') & (df['away_team'] == 'Argentina')
                ].tolist()
index<jupyter_output><empty_output><jupyter_text>We just verify that in our model this match never occurs. It is time to play our virtual match!<jupyter_code>home_team = dic['Argentina']
away_team = dic['Galicia']
print("Argentina team idx", home_team)
print("Galicia team idx", away_team)
x1 = [[home_team,away_team]]
yhat = model.predict(x1)
yhat<jupyter_output><empty_output><jupyter_text>Argentina wins! Now we could try with another example more realistic<jupyter_code>home_team = dic['Paraguay']
away_team = dic['Argentina']
x1 = [[home_team,away_team]]
yhat = model.predict(x1)
yhat<jupyter_output><empty_output><jupyter_text>Save model and schema In this part we are goint to save our model for future use and save the schema dictionary that we have use to test our model<jupyter_code>from sklearn.externals import joblib
import sqlite3
# Save model
joblib.dump(model, 'football_predictor_model.pkl')<jupyter_output><empty_output><jupyter_text>Create schema<jupyter_code>conn = sqlite3.connect('football.db')
# The database will be saved in the location where your 'py' file is saved
c = conn.cursor() 
c.execute('''
            DROP TABLE IF EXISTS results;
         ''')
c.execute('''
            DROP TABLE IF EXISTS teams;
         ''')
c.execute('''CREATE TABLE teams(
             [id] INTEGER PRIMARY KEY NOT NULL,
             [country] TEXT NOT NULL
             )
         ''')
c.execute('''CREATE TABLE results(
             [home_team_id] INTEGER REFERENCES teams(id) NOT NULL,
             [away_team_id] INTEGER REFERENCES teams(id) NOT NULL,
             [home_score] INTEGER NOT NULL,
             [away_score] INTEGER NOT NULL,
             [result] TEXT NOT NULL
             )
         ''')<jupyter_output><empty_output><jupyter_text>Save dictionary<jupyter_code>teams = pd.DataFrame(dic.items(), columns=['country', 'id']) 
teams.head()
teams.to_sql('teams', conn, if_exists='replace', index = False)<jupyter_output><empty_output><jupyter_text>Save results<jupyter_code>results = df[ ['home_team_id', 'away_team_id', 'home_score', 'away_score', 'result'] ]
results.head()
results.to_sql('results', conn, if_exists='replace', index = False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1345305946876008, 'fraction_numerical': 0.012474459619313904, 'mean_word_length': 5.254203093476799, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '62360', 'license': 'Unlicense', 'n_tokens_mistral': 3564, 'n_tokens_neox': 3391, 'n_words': 752, 'path': 'football_predictor.ipynb', 'repo_name': 'hernancontigiani/football-result-predictor', 'size': '9299'}