<jupyter_start><jupyter_text>Normalize Team Data<jupyter_code>from sklearn.preprocessing import StandardScaler
def normalize(prev_season):
    scaler = StandardScaler()
    season = []
    for i in team_ids["id"]:
        teams_df = get_season_team(prev_season, i, team_names_test)
        teams_list = teams_df.drop(teams_df.columns[list(range(0, 9))], axis = 1).values.tolist()
        season += teams_list
    
    scaler.fit(season)
    return scaler<jupyter_output><empty_output><jupyter_text>Calculations<jupyter_code>""" gets the season games given the seasonID and abbreviation of the team """
""" Season is based on the year that the season STARTED in. I.E 2016-2017 has seasonID 2016"""
""" Reg season starts with 2, playoffs 4, pre 1 """
""" 
For some reason summer league and preseason games are sometimes included in reg season IDs.
The function accounts for this by only looking at Game IDs that start with 0021 for reg reason,
0041 for playoffs, 0011 for preseason
"""

def get_season_team(seasonID, team_id, team_names):
    seasonID = str(seasonID)
    gameID_prefix = seasonID[0]
    return team_names[team_id].loc[(team_names[team_id]["SEASON_ID"].str.contains(seasonID)) & \
                                    (team_names[team_id]['GAME_ID'].str.startswith('00{0}'.format(gameID_prefix)))]


""" gets the number of rows in the passed df"""
def num_rows(df):
    return len(df.index)

""" returns the number of features of the df"""
def num_features(df):
    return len(df.columns)

""" returns a list of the features from the start index moving forward. Using 9 for now """
def get_features(df, start_idx=9):
    return [feature for feature in df.columns.tolist()[start_idx:]]

""" 
util func: gets last n games given the curr game
in the df with the correct season, year
"""
def last_n_games(df, n, curr_game):
    n_rows = num_rows(df)
    # the first row is the latest game. I.E for reg season it's 82nd game
    
"""
returns avg team stats vector over the last n games given
the current game. Assumes games 0 indexed
"""
def get_team_avgs(season_games, curr_game, n):
    total_games = num_rows(season_games)
    assert curr_game > n, "curr game ({0}) > n ({1})".format(curr_game, n)
    assert total_games > n, "n ({0}) is more than the total number of games ({1})".format(n, total_games)
    # the real index of the current game
    game_idx = total_games - curr_game - 1
    # start at 9th index to get meaningful stats
    start_idx = 9
    team_avgs = np.zeros(num_features(season_games) - start_idx)
    for i in range(game_idx - n, game_idx):
        game_stats = np.array(season_games.iloc[i].tolist()[start_idx:])
        team_avgs += game_stats
    return team_avgs / n

def print_team_avgs(season_games, team_avgs):
    features = get_features(season_games)
    for stat, feature in zip(team_avgs, features):
        print("{0}:{1}".format(feature, stat))
# TEST: get the 2018 season games for the Atlanta Hawks. 

# atl_reg_season = get_season_team(22018, 1610612737, team_names_test)

# print the avgs of the 10 games before the 16th game that the Hawks played in the 2017-2018 season

atl_team_avgs = get_team_avgs(atl_reg_season, 16, 10)
#print_team_avgs(atl_reg_season, atl_team_avgs)
def find_opponent_id(opp_abr, season_id):
    
    return all_abrs[opp_abr].loc[all_abrs[opp_abr]["SEASON_ID"].str.contains(str(season_id))]["TEAM_ID"].iloc[0]
def find_opponent(n, curr_team, season_id):
    full_df = get_season_team(season_id, curr_team, team_names_test).reset_index()
    
    df_of_game = full_df.iloc[[-(n + 1)]]
    opp_abr = df_of_game["MATCHUP"].values[0][-3::]
    return find_opponent_id(opp_abr, season_id)
# TEST: get the opponent of the Atlanta Hawks's 2nd game of the the 2018 season

find_opponent(1, 1610612737, 22019)
def convert_to_01s(letter):
    return 1 if letter == "W" else 0
def check_home_team(team_df, curr_game):
    matchup = team_df["MATCHUP"].iloc[num_rows(team_df) - curr_game - 1]
    #print('matchup: ', matchup)
    return False if "@" in matchup else True
""" return the difference vector betweeen the current team and its opponent """
def find_diff_vector(curr_game, n, curr_team, season_id):
    
    #curr_team_season is a df
    curr_team_season = get_season_team(season_id, curr_team, team_names_test)
    curr_team_avgs = get_team_avgs(curr_team_season, curr_game, n)
    
    #check for home game
    if check_home_team(curr_team_season, curr_game):
    
        # find point differentials
        outcome = curr_team_season["PLUS_MINUS"].iloc[num_rows(curr_team_season) - curr_game - 1]

        opponent = find_opponent(curr_game, curr_team, season_id)
        opponent_team_season = get_season_team(season_id, opponent, team_names_test)
        opponent_team_avgs = get_team_avgs(opponent_team_season, curr_game, n)

        # normalize 
        scaler = normalize(season_id - 1)
        curr_team_avgs_normalized = scaler.transform([curr_team_avgs])
        opp_team_avgs_normalized = scaler.transform([opponent_team_avgs])

        diff = np.subtract(curr_team_avgs_normalized, opp_team_avgs_normalized)

        return diff, outcome
    return None, None
# TEST: diff vector between Atlanta Hawks' stats and its opponents' stats on the Hawks' 16th
# game based on the averages of the last 15 games before the nth game"""
find_diff_vector(15, 14, 1610612737, 22018)
""" gets diff vectors for all the games 2-82 for given team and season""" 
def get_season_diff_vectors(curr_team, season_id):
    diff_vector = []
    win_losses = []
    df_len = num_rows(get_season_team(season_id, curr_team, team_names_test))
    for i in range(2, df_len):
        diff, outcome = find_diff_vector(i, min(8, i-1), curr_team, season_id)
        if outcome != None:
            diff_vector.append(diff)
            win_losses.append(outcome)
    return diff_vector, win_losses
# TEST: get_season_diff_vectors function
diffs, outcomes = get_season_diff_vectors(1610612737, 22012)
len(outcomes)
""" get difference vectors for all teams for one season """

def diff_vectors_per_season(season_id):
    team_per_season_dict = {}
    outcomes_per_season_dict = {}
    
    for team in team_ids["id"]:
        print(team)
        diff, outcomes = get_season_diff_vectors(team, season_id)
        team_per_season_dict[team] = diff
        outcomes_per_season_dict[team] = outcomes
    
    return team_per_season_dict, outcomes_per_season_dict
""" get diff vectors for all seasons for all teams """

def ultimate_diff_vectors():
    ultimate_dict = {}
    ultimate_dict_outcomes = {}
    seasons = list(range(22009, 22019))

    for s in seasons:
        print(s)
        diff, outcomes = diff_vectors_per_season(s)
        ultimate_dict[s] = diff
        ultimate_dict_outcomes[s] = outcomes
        
    return ultimate_dict, ultimate_dict_outcomes
"""
key = season
value = dictionary with key as team id, values as difference numpy arrays
"""
ultimate_dict_points, ultimate_dict_points_outcomes = ultimate_diff_vectors()

""" pickle here!"""

#save_obj(ultimate_dict_points, 'ultimate_dict_points')
ultimate_dict_points_pickled = load_obj('ultimate_dict_points')

#save_obj(ultimate_dict_points_outcomes, 'ultimate_dict_points_outcome')
ultimate_dict_points_outcomes_pickled = load_obj('ultimate_dict_points_outcome')<jupyter_output><empty_output><jupyter_text>MODELS<jupyter_code>from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.model_selection import train_test_split
from pipeline import Model

from sklearn.tree import DecisionTreeRegressor
from sklearn.tree import plot_tree
from sklearn.ensemble import RandomForestRegressor
def massive_flatten(ultimate_lists):
    flattened_values = []
    for team in ultimate_lists.values():
        for games in team.values():
            flattened_values.extend(games)
    return flattened_values
def flatten_further(ult):
    for idx, vector in enumerate(ult):
        ult[idx] = vector.flatten()
X = massive_flatten(ultimate_dict_points_pickled)
y = massive_flatten(ultimate_dict_points_outcomes_pickled)
# X = massive_flatten(ultimate_dict_homeOnly_pickled)
# y = massive_flatten(ultimate_dict_homeOnly_outcomes_pickled)
flatten_further(X)
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.25)
m = Model(LinearRegression())
m.train(Xtr, ytr)
lin_preds = m.predict(Xte)
accuracy = lin_preds/yte
np.mean(accuracy)<jupyter_output><empty_output><jupyter_text>Using point spread predictions (lin reg) to predict win/loss. About the same accuracy as directly predicting win/loss.<jupyter_code>yte = np.array(yte)
both_win = (lin_preds > 0) & (yte > 0)
both_loss = (lin_preds < 0) & (yte < 0)
win_loss_acc = len(np.where(both_win | both_loss)[0]) / len(yte)
win_loss_acc
decision_tree = DecisionTreeRegressor()
decision_tree.fit(Xtr, ytr)
decision_tree.score(Xte, yte)
random_tree = RandomForestRegressor()
random_tree.fit(Xtr, ytr)
random_tree.score(Xte, yte)
from sklearn.neural_network import MLPRegressor
clf = MLPRegressor(solver='adam', activation='relu', alpha=5e-3,hidden_layer_sizes=(32,16),max_iter=3000, random_state=1)
clf.fit(Xtr, ytr)
#nn_preds = clf.predict(Xte)
clf.score(Xte, yte)<jupyter_output><empty_output><jupyter_text>Using the Logistic Regression model to predict 2019 game outcomes<jupyter_code># """get the opponent of the Atlanta Hawks's 2nd game of the the 2018 season"""

# find_opponent(2, 1610612737, 22018)

#diff, L = find_diff_vector(5, 4, 1610612737, 22019)  
#all_abrs['GSW']
for i in range(2, 7):
    print('i:', i)
    diff, outcome = find_diff_vector(i, i-1, 1610612737 + 7, 22019)  
    if (diff is None):
        opponent = find_opponent(i, 1610612737 + 7, 22019)
        print('opponent:', opponent)
        
        diff, outcome = find_diff_vector(i, i-1, opponent, 22019)
    print('predicted:', m.predict(diff)[0], 'actual:', outcome)
features = get_features(all_abrs['ATL'])
features[9]
season = get_season_team(22018, 1610612737 + 7, team_names_test)
get_team_avgs(season, 6, 4)
features = get_features(all_abrs['ATL'])
features[9]
season = get_season_team(22018, 1610612737 + 29, team_names_test)
get_team_avgs(season, 6, 4)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10106382978723404, 'fraction_numerical': 0.030634357762017336, 'mean_word_length': 4.665736607142857, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 26, 'https://': 0, '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': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '191592', 'license': 'MIT', 'n_tokens_mistral': 3743, 'n_tokens_neox': 3476, 'n_words': 867, 'path': 'Game_by_Game/Game_by_Game_2.ipynb', 'repo_name': 'callaunchpad/BalliNN', 'size': '10152'}