<jupyter_start><jupyter_text>hyper_parameters from here https://machinelearningmastery.com/hyperparameters-for-classification-machine-learning-algorithms/for xgboost from here https://machinelearningmastery.com/extreme-gradient-boosting-ensemble-in-python/xgbtrees = [10, 50, 100, 500, 1000, 5000]  100  num of treesmax_depth = range(1,11)  3-5rates = [0.0001, 0.001, 0.01, 0.1, 1.0]  0.1subsample in arange(0.1, 1.1, 0.1):  0.4, 0.5  this is 0.1, 0.2 ... 1.0  % of features to samplesvc kernels in [‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’] if you use poly, then adjust degreeC in [100, 10, 1.0, 0.1, 0.001]gblearning_rate in [0.001, 0.01, 0.1]n_estimators [10, 100, 1000]subsample in [0.5, 0.7, 1.0]max_depth in [3, 7, 9]rfcmax_features [1 to 20]  keymax_features in [‘sqrt’, ‘log2’]n_estimators in [10, 100, 1000]bcn_estimators in [10, 100, 1000]svm_dic = {'kernels':[‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’]}lrc_dic = {'alpha': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]}lgr_hp_dic = {'solver': [‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’], 'penalty' : [‘none’, ‘l1’, ‘l2’, ‘elasticnet’],'C' :[100, 10, 1.0, 0.1, 0.01]}<jupyter_code>#Leung's features  WHYYYY is CSh% Csv% FSh% and Fsv% imporant?? that is so weird.
##are these features the same as Cernak's?? Nope, same as Morrison! even calles it PENDiff 
#too .. maybe Morrison got it from somewhere too ... 

Leung_features = ['ID', 
               'Date', 
               'HomeTeam', 
               'AwayTeam', 
               'CF%', 
               'CSh%',
               'CSv%',
               'FF%',
               'FSh%',
               'FSv%',
               'GDiff',
               'GF%',
               'PDO',
               'PENDiff',
               'SF%',
               'SDiff',
               'Sh%',
               'Sv',
               'FOW%',
               'W%',
               'FavoritesW%',
               'Result']
import pandas as pd
import numpy as np

from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score, confusion_matrix
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, f1_score


import matplotlib.pyplot as plt
import seaborn as sns


##couple evaluation functions 
def evaluate_binary_classification(model_name, y_test, y_pred, y_proba=None, graph = False):
    accuracy = accuracy_score(y_test, y_pred)
    precision = precision_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    f1 = f1_score(y_test, y_pred)
    #try:
    if y_proba != None:
        rocauc_score = roc_auc_score(y_test, y_proba)
    else:
        rocauc_score = "no roc"
    #except: 
    #    pass     
    cm = confusion_matrix(y_test, y_pred)
    if graph == True:
        sns.heatmap(cm, annot=True)
        plt.tight_layout()
        plt.title(f'{model_name}', y=1.1)
        plt.ylabel('Actual label')
        plt.xlabel('Predicted label')
        plt.show()
    print("accuracy: ", accuracy)
    print("precision: ", precision)
    print("recall: ", recall)
    print("f1 score: ", f1)
    print("rocauc: ", rocauc_score)
    print(cm)
    #return accuracy, precision, recall, f1, rocauc_score

def evaluate_regression(y_test, y_pred):
    mae = mean_absolute_error(y_test, y_pred)
    mse = mean_squared_error(y_test, y_pred)
    r2 = r2_score(y_test, y_pred)
    print("mae", mae)
    print("mse", mse)
    print('r2', r2)
    
##display null values


def perc_null(X):
    
    total = X.isnull().sum().sort_values(ascending=False)
    data_types = X.dtypes
    percent = (X.isnull().sum()/X.isnull().count()).sort_values(ascending=False)

    missing_data = pd.concat([total, data_types, percent], axis=1, keys=['Total','Type' ,'Percent'])
    return missing_data


data = pd.read_csv("/Users/joejohns/data_bootcamp/GitHub/final_project_nhl_prediction/Data/Shaped_Data/data_bet_stats_mp.csv")
data.drop(columns=[ 'Unnamed: 0'], inplace=True)
data['won'] = data['won'].apply(int)
data_playoffs = data.loc[data['playoffGame'] == 1, :].copy()  #set aside playoff games ... probably won't use them.
data=  data.loc[data['playoffGame'] == 0, :].copy() 

#sorted(data.columns)
def get_dates(X, season):  #season 20162017 int; returns the list of all dates in chronological order from that season 20161004, 20161005, ...
    X = X.loc[X['season'] == season, :].copy()
    dates_1 = list(set(X.loc[(X['date'] >= 900) & (X['date'] <= 1231) , :]['full_date']))  #2016 part
    dates_2 = list(set(X.loc[(X['date'] >= 100) & (X['date'] <= 800) , :]['full_date']))  #2017 part
    dates = dates_1 + dates_2 #all dates in order
    return dates

#sorted(data.columns)


def make_HA_data(X, season, list_var_names = None ):
    X = X.loc[X['season'] == season, :].copy()
    X_H = X.loc[X['HoA'] == 'home',:].copy()
    X_A = X.loc[X['HoA'] == 'away',:].copy()
    X_H['goal_difference'] = X_H['goalsFor'] - X_H['goalsAgainst']  ##note every thing is based in home data
    X_H.reset_index(drop = True, inplace = True)
    X_A.reset_index(drop = True, inplace = True)
    df_visitor = pd.get_dummies(X_H['nhl_name'], dtype=np.int64)
    df_home = pd.get_dummies(X_A['nhl_name'], dtype=np.int64)
    df_model = df_home.sub(df_visitor) 
    df_model['date'] = X_H['date']
    df_model['full_date'] = X_H['full_date']
    
    df_model['game_id'] = X_H['game_id']
    df_model['home_id'] = X_H['team_id']
    df_model['away_id'] = X_A['team_id'] 
    y = X_H.loc[:,['date', 'full_date','game_id', 'Open','goal_difference', 'won']].copy()   ##these are from home team perspective; 'Open' is for betting 
    return (df_model, y)

##have not written yet

def top3_max_val_params(model, X, dates, drop_firs=False):
    pass
    

#this is for  regressors predicting wins - losses, can use this to turn output into win prediction 

def make_win(x):
    if x <= 0:
        return 0
    if x >0:
        return 1

v_make_win = np.vectorize(make_win)

#useage: v_make_win(y_pred)
def regr_model_results(model, model_name, X, dates, step, window_size, prediction_size, drop_first_k_days = 0): #X = data 
    results_dic['model_name'] = []
    results_dic['date'] = []
    results_dic['mae'] = []
    results_dic['mse'] = []
    results_dic['r2'] = []   
    
    
    #drop first k days from dates and X
    dates = dates[drop_first_k_days :]
    X = X.loc[X['full_date'].isin(dates), :].copy()  

    for i in range(step, len(dates), step): ##eg step =10, so 17 rounds
        
        model.fit(X.loc[X['full_date'].isin(dates[max(i-window_size ,0):i]), :],y.loc[y['full_date'].isin(dates[max(i-window_size,0):i]),'goal_difference' ])
        y_pred = model.predict(X.loc[X['full_date'].isin(dates[i:i+prediction_size]), :])
        y_test = y.loc[y['full_date'].isin(dates[i:i+prediction_size]),'goal_difference' ]
        
        mae = mean_absolute_error(y_test, y_pred)
        mse = mean_squared_error(y_test, y_pred)
        r2 = r2_score(y_test, y_pred)
        
        results_dic['model_name'].append(model_name)
        results_dic['date'].append(dates[i])
    
        results_dic['mae'].append(mae)
        results_dic['mse'].append(mse)
        results_dic['r2'].append(r2)
        
    return results_dic #!
        
        
def class_model_results(model, model_name, X, dates, step, window_size, prediction_size, drop_first_k_days = 0): #X = data 
    results_dic ={}
    results_dic['model_name'] = []
    results_dic['date'] = []
    results_dic['accuracy'] = []
    results_dic['f1_score'] = []

    #results_dic['precision'] = []
  #  results_dic['recall'] = []
    
    #drop first k days from dates and X
    dates = dates[drop_first_k_days :]
    X = X.loc[X['full_date'].isin(dates), :].copy()  

    for i in range(step, len(dates), step): ##eg step =10, so 17 rounds
        model.fit(X.loc[X['full_date'].isin(dates[max(i-window_size ,0):i]), :],y.loc[y['full_date'].isin(dates[max(i-window_size,0):i]),'won' ])
        y_pred = model.predict(X.loc[X['full_date'].isin(dates[i:i+prediction_size]), :])
        y_test = y.loc[y['full_date'].isin(dates[i:i+prediction_size]),'won' ]
    
        accuracy = accuracy_score(y_test, y_pred)
        #recision = precision_score(y_test, y_pred, zero_division = 0)
        #recall = recall_score(y_test, y_pred)
        f1 = f1_score(y_test, y_pred) #, average = None)
            
        results_dic['model_name'].append(model_name)  #append same model name every iter so same length as others
        results_dic['date'].append(dates[i])
                          
        results_dic['accuracy'].append(accuracy)
        results_dic['f1_score'].append(f1)
        #results_dic['precision'].append(precision)
        #results_dic['recall'].append(recall)
    results_dic['model_name'].append('model_name'+'_avg')  #append same model name every iter so same length as others
    results_dic['date'].append('average')
    results_dic['accuracy'].append(round(np.mean(np.array(results_dic['accuracy'])), 2) ) 
    results_dic['f1_score'].append(round(np.mean(np.array(results_dic['f1_score'])), 2) ) 
    return results_dic #!
        
        
###ok let's check the results of model lr = ridge(0.001) again
all_seasons = set(data['season'])
X_dic = {}
y_dic = {}
for sea in all_seasons:
    X_dic[sea] = make_HA_data(data, sea)[0]
    y_dic[sea] = make_HA_data(data, sea)[1]

y_dic[20162017].loc[:, 'goal_difference']
X_dic[20172018].iloc[:, :-5].shape
##naive method: train on first half of season, 600 games, test on second half of season
##with no further training

def naive_test_train(cut_off = 600):
    for sea in all_seasons:
        #select season, remove date, etc. select target y
        y = y_dic[sea].loc[:, 'goal_difference'].copy()
        X = X_dic[sea].iloc[:, :-5].copy()
        
        #carry out naive train-test split
        y_train = y[0: cut_off].copy()
        y_test = y[cut_off :].copy()
        X_train = X[0: cut_off].copy()
        X_test = X[cut_off :].copy()
        
        #train model, find predictions
        lr.fit(X_train, y_train)
        y_pred = lr.predict(X_test) #this is regression pred on Hg - Ag
        
        y_pred_win = v_make_win(y_pred) #this is the pred of who wins HW =1, AW =0
        y_test_win = v_make_win(y_test)  #this gives the correct win, loss
        
        print("seaoson: ", sea)
        evaluate_regression(y_test, y_pred)
        evaluate_binary_classification(y_test_win, y_pred_win)
        print(" ")
        
        
        
naive_test_train(cut_off = 600)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15706506162224132, 'fraction_numerical': 0.028374892519346516, 'mean_word_length': 3.153968253968254, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '131375', 'license': 'MIT', 'n_tokens_mistral': 4127, 'n_tokens_neox': 3863, 'n_words': 804, 'path': 'Note_books/Explore_Models/.ipynb_checkpoints/model1_v5_Check_ridge_HA-checkpoint.ipynb', 'repo_name': 'joeyamosjohns/final_project_nhl_prediction_first_draft', 'size': '10467'}