{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-02T01:37:53.854907Z","iopub.execute_input":"2023-06-02T01:37:53.855209Z","iopub.status.idle":"2023-06-02T01:37:53.886091Z","shell.execute_reply.started":"2023-06-02T01:37:53.855187Z","shell.execute_reply":"2023-06-02T01:37:53.885130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pathlib import Path\nimport datetime as dt\nimport os\nimport random\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pylab as plt\nfrom sklearn import metrics\nfrom sklearn import impute\nfrom sklearn import preprocessing\nfrom sklearn.utils import class_weight","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:37:57.900164Z","iopub.execute_input":"2023-06-02T01:37:57.900477Z","iopub.status.idle":"2023-06-02T01:37:58.589526Z","shell.execute_reply.started":"2023-06-02T01:37:57.900455Z","shell.execute_reply":"2023-06-02T01:37:58.588864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH = Path('../input/football-match-probability-prediction')\n!ls {PATH}","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:38:15.809585Z","iopub.execute_input":"2023-06-02T01:38:15.809927Z","iopub.status.idle":"2023-06-02T01:38:16.081880Z","shell.execute_reply.started":"2023-06-02T01:38:15.809903Z","shell.execute_reply":"2023-06-02T01:38:16.081033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#In summary, below code snippet iterates over the columns in the train and test DataFrames that contain the substring 'date'. It converts the values in those columns to datetime objects using pd.to_datetime() and updates the DataFrame with the converted values. This is useful when working with date or timestamp data, as it allows for convenient manipulation and analysis of the dates\n\ntrain = pd.read_csv(PATH / 'train.csv')\ntest = pd.read_csv(PATH / 'test.csv')\ntrain_target_and_scores = pd.read_csv(PATH / 'train_target_and_scores.csv')\nsample_submission = pd.read_csv(PATH / 'sample_submission.csv')\n\nfor col in train.filter(regex='date', axis=1).columns:\n    train[col] = pd.to_datetime(train[col])\n    test[col] = pd.to_datetime(test[col])\n    \ntrain ","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:38:33.040435Z","iopub.execute_input":"2023-06-02T01:38:33.040800Z","iopub.status.idle":"2023-06-02T01:38:41.466860Z","shell.execute_reply.started":"2023-06-02T01:38:33.040770Z","shell.execute_reply":"2023-06-02T01:38:41.466007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import seaborn as sns\n\ntrain['target'].value_counts()\nsns.countplot(x='target', data=train).set(xlabel='Target', ylabel='Density')\ntrain['league_name'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:40:11.594995Z","iopub.execute_input":"2023-06-02T01:40:11.595311Z","iopub.status.idle":"2023-06-02T01:40:12.122017Z","shell.execute_reply.started":"2023-06-02T01:40:11.595289Z","shell.execute_reply":"2023-06-02T01:40:12.121238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get the number of rows and columns in the DataFrame\nprint(\"Number of rows:\", train.shape[0])\nprint(\"Number of columns:\", train.shape[1])\n\n# Describe a specific column in the train DataFrame\ncolumn_stats = train['target'].describe()\nprint(column_stats)","metadata":{"execution":{"iopub.status.busy":"2023-06-01T23:08:02.540547Z","iopub.execute_input":"2023-06-01T23:08:02.541007Z","iopub.status.idle":"2023-06-01T23:08:02.585256Z","shell.execute_reply.started":"2023-06-01T23:08:02.540974Z","shell.execute_reply":"2023-06-01T23:08:02.584274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#By running the code below, you will be able to view the descriptive statistics for the history rating columns of the home and away teams, presented in a nicely formatted output.\n\n\n# Set the max_rows option to None to display all rows\npd.set_option('display.max_rows', None)\n\n# Specify the columns to describe\nhome_columns_to_describe = [f'home_team_history_rating_{i}' for i in range(1, 11)]\naway_columns_to_describe = [f'away_team_history_rating_{i}' for i in range(1, 11)]\n\n# Describe the specified columns in the train DataFrame\nhome_column_stats = train[home_columns_to_describe].describe()\naway_column_stats = train[away_columns_to_describe].describe()\n\n# Concatenate home and away column statistics side by side\ncolumn_stats = pd.concat([home_column_stats, away_column_stats], axis=1)\n\n# Print the column statistics\nprint(column_stats)\n\n# Reset the max_rows option to its default value\npd.reset_option('display.max_rows')\n\n","metadata":{"execution":{"iopub.status.busy":"2023-06-01T23:08:46.384290Z","iopub.execute_input":"2023-06-01T23:08:46.384741Z","iopub.status.idle":"2023-06-01T23:08:46.591898Z","shell.execute_reply.started":"2023-06-01T23:08:46.384704Z","shell.execute_reply":"2023-06-01T23:08:46.590744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport matplotlib.pyplot as plt\n\n# Set the max_rows option to None to display all rows\npd.set_option('display.max_rows', None)\n\n# Specify the columns to describe\nhome_columns_to_describe = [f'home_team_history_rating_{i}' for i in range(1, 11)]\naway_columns_to_describe = [f'away_team_history_rating_{i}' for i in range(1, 11)]\n\n# Describe the specified columns in the train DataFrame\nhome_column_stats = train[home_columns_to_describe].describe()\naway_column_stats = train[away_columns_to_describe].describe()\n\n# Remove 'count' statistic from the column statistics\nhome_column_stats.drop(['count','max','min','std','25%','50%','75%'], inplace=True)\naway_column_stats.drop(['count', 'max','min','std','25%','50%','75%'], inplace=True)\n#home_column_stats.drop('max', inplace=True)\n#away_column_stats.drop('max', inplace=True)\n# Concatenate home and away column statistics side by side\ncolumn_stats = pd.concat([home_column_stats, away_column_stats], axis=1)\n\n# Reset the max_rows option to its default value\npd.reset_option('display.max_rows')\n\n# Plotting the column statistics\ncolumn_stats.plot(kind='bar', figsize=(10, 6))\nplt.xlabel('Statistics')\nplt.ylabel('Values')\nplt.title('Comparison of Column Statistics for Home and Away Teams')\nplt.legend(['Home Team', 'Away Team'])\nplt.xticks(rotation=45)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-01T23:09:05.568990Z","iopub.execute_input":"2023-06-01T23:09:05.569374Z","iopub.status.idle":"2023-06-01T23:09:06.187838Z","shell.execute_reply.started":"2023-06-01T23:09:05.569346Z","shell.execute_reply":"2023-06-01T23:09:06.186735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The purpose of this code below is to extract and aggregate the historical home team's goal information from the given DataFrame, providing a consolidated view of the home team's goal scoring performance.\n\ndef home_team_home_goals(df):\n    for i in range(1, 11):\n        home_goals = df.loc[df[f'home_team_history_is_play_home_{i}'] == 1.0, f'home_team_history_goal_{i}']\n        home_goals_series = pd.Series(0, index=df.index)\n        home_goals_series[df[f'home_team_history_is_play_home_{i}'] == 1.0] = home_goals\n        df[f'HT_home_goals_{i}'] = home_goals_series\n        \n    df['HT_home_goals_total'] = df.loc[:, 'HT_home_goals_1':'HT_home_goals_10'].sum(axis=1)\n\n    return df\n\ndef home_team_away_goals(df):\n    for i in range(1, 11):\n        home_goals = df.loc[df[f'home_team_history_is_play_home_{i}'] == 0.0, f'home_team_history_goal_{i}']\n        home_goals_series = pd.Series(0, index=df.index)\n        home_goals_series[df[f'home_team_history_is_play_home_{i}'] == 0.0] = home_goals\n        df[f'HT_away_goals_{i}'] = home_goals_series\n\n    df['HT_away_goals_total'] = df.loc[:, 'HT_away_goals_1':'HT_away_goals_10'].sum(axis=1)\n    \n    return df\n\ndef away_team_home_goals(df):\n    for i in range(1, 11):\n        away_goals = df.loc[df[f'away_team_history_is_play_home_{i}'] == 1.0, f'away_team_history_goal_{i}']\n        away_goals_series = pd.Series(0, index=df.index)\n        away_goals_series[df[f'away_team_history_is_play_home_{i}'] == 1.0] = away_goals\n        df[f'AT_home_goals_{i}'] = away_goals_series\n\n    df['AT_home_goals_total'] = df.loc[:, 'AT_home_goals_1':'AT_home_goals_10'].sum(axis=1)\n    \n    return df\n\ndef away_team_away_goals(df):\n    for i in range(1, 11):\n        away_goals = df.loc[df[f'away_team_history_is_play_home_{i}'] == 0.0, f'away_team_history_goal_{i}']\n        away_goals_series = pd.Series(0, index=df.index)\n        away_goals_series[df[f'away_team_history_is_play_home_{i}'] == 0.0] = away_goals\n        df[f'AT_away_goals_{i}'] = away_goals_series\n\n    df['AT_away_goals_total'] = df.loc[:, 'AT_away_goals_1':'AT_away_goals_10'].sum(axis=1)\n    \n    return df\n\ntrain = home_team_home_goals(train)\ntest  = home_team_home_goals(test)\n\ntrain = home_team_away_goals(train)\ntest  = home_team_away_goals(test)\n\ntrain = away_team_home_goals(train)\ntest  = away_team_home_goals(test)\n\ntrain = away_team_away_goals(train)\ntest  = away_team_away_goals(test)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:44:08.747793Z","iopub.execute_input":"2023-06-02T01:44:08.748150Z","iopub.status.idle":"2023-06-02T01:44:09.215902Z","shell.execute_reply.started":"2023-06-02T01:44:08.748125Z","shell.execute_reply":"2023-06-02T01:44:09.215024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The purpose of this code is to extract and aggregate the historical home team's conceded goal information from the given DataFrame, providing a consolidated view of the home team's defensive performance at home.\n\n\ndef home_team_home_goals_conceded(df):\n    for i in range(1, 11):\n        home_goals_conceded = df.loc[df[f'home_team_history_is_play_home_{i}'] == 1.0, f'home_team_history_opponent_goal_{i}']\n        home_goals_conceded_series = pd.Series(0, index=df.index)\n        home_goals_conceded_series[df[f'home_team_history_is_play_home_{i}'] == 1.0] = home_goals_conceded\n        df[f'HT_home_goals_conceded_{i}'] = home_goals_conceded_series\n        \n    df['HT_home_goals_conceded_total'] = df.loc[:, 'HT_home_goals_conceded_1':'HT_home_goals_conceded_10'].sum(axis=1)\n\n    return df\n\ndef home_team_away_goals_conceded(df):\n    for i in range(1, 11):\n        home_goals_conceded = df.loc[df[f'home_team_history_is_play_home_{i}'] == 0.0, f'home_team_history_opponent_goal_{i}']\n        home_goals_conceded_series = pd.Series(0, index=df.index)\n        home_goals_conceded_series[df[f'home_team_history_is_play_home_{i}'] == 0.0] = home_goals_conceded\n        df[f'HT_away_goals_conceded_{i}'] = home_goals_conceded_series\n\n    df['HT_away_goals_conceded_total'] = df.loc[:, 'HT_away_goals_conceded_1':'HT_away_goals_conceded_10'].sum(axis=1)\n    \n    return df\n\ndef away_team_home_goals_conceded(df):\n    for i in range(1, 11):\n        away_goals_conceded = df.loc[df[f'away_team_history_is_play_home_{i}'] == 1.0, f'away_team_history_opponent_goal_{i}']\n        away_goals_conceded_series = pd.Series(0, index=df.index)\n        away_goals_conceded_series[df[f'away_team_history_is_play_home_{i}'] == 1.0] = away_goals_conceded\n        df[f'AT_home_goals_conceded_{i}'] = away_goals_conceded_series\n\n    df['AT_home_goals_conceded_total'] = df.loc[:, 'AT_home_goals_conceded_1':'AT_home_goals_conceded_10'].sum(axis=1)\n    \n    return df\n\ndef away_team_away_goals_conceded(df):\n    for i in range(1, 11):\n        away_goals_conceded = df.loc[df[f'away_team_history_is_play_home_{i}'] == 0.0, f'away_team_history_opponent_goal_{i}']\n        away_goals_conceded_series = pd.Series(0, index=df.index)\n        away_goals_conceded_series[df[f'away_team_history_is_play_home_{i}'] == 0.0] = away_goals_conceded\n        df[f'AT_away_goals_conceded_{i}'] = away_goals_conceded_series\n\n    df['AT_away_goals_conceded_total'] = df.loc[:, 'AT_away_goals_conceded_1':'AT_away_goals_conceded_10'].sum(axis=1)\n    \n    return df\n\ntrain = home_team_home_goals_conceded(train)\ntest = home_team_home_goals_conceded(test)\n\ntrain = away_team_home_goals_conceded(train)\ntest = away_team_home_goals_conceded(test)\n\ntrain = home_team_away_goals_conceded(train)\ntest = home_team_away_goals_conceded(test)\n\ntrain = away_team_away_goals_conceded(train)\ntest = away_team_away_goals_conceded(test)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:44:17.946241Z","iopub.execute_input":"2023-06-02T01:44:17.946543Z","iopub.status.idle":"2023-06-02T01:44:18.378048Z","shell.execute_reply.started":"2023-06-02T01:44:17.946519Z","shell.execute_reply":"2023-06-02T01:44:18.377227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calculate_elo_rating(rating, opponent_rating, result, k_factor = 3):\n    expected_result = 1 / (1 + 10 ** ((opponent_rating - rating) / 400)) \n    new_rating = rating + k_factor * (result - expected_result)\n    return new_rating#.where(~result.isin(['no game']), rating.ffill())","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:44:40.264787Z","iopub.execute_input":"2023-06-02T01:44:40.265095Z","iopub.status.idle":"2023-06-02T01:44:40.270117Z","shell.execute_reply.started":"2023-06-02T01:44:40.265073Z","shell.execute_reply":"2023-06-02T01:44:40.268877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef home_team_home_result(df):\n    for i in range(1, 11):\n        is_home_game = df[f'home_team_history_is_play_home_{i}'] == 1.0\n        home_goals = df.loc[is_home_game, f'home_team_history_goal_{i}']\n        opponent_goals = df.loc[is_home_game, f'home_team_history_opponent_goal_{i}']\n        result = pd.Series('no game', index=df.index)\n        if sum(is_home_game) != 0:  # if no home games, assign 0\n            temp_result = pd.Series(index=df.index)\n        \n      \n            temp_result[is_home_game & (home_goals > opponent_goals)] = 1  # winning home 1 point\n            temp_result[is_home_game & (home_goals == opponent_goals)] = -1\n            temp_result[is_home_game & (home_goals < opponent_goals)] = -3  # losing at home higher punishment\n            result.update(temp_result)\n        df[f'HT_home_result_{i}'] = result\n        non_no_game = result != 'no game'\n        HT_home_elo_rating = calculate_elo_rating(df[f'home_team_history_rating_{i}'][non_no_game], df[f'home_team_history_opponent_rating_{i}'][non_no_game], result[non_no_game])\n        df[f'HT_home_games_ELO_rating_{i}'] = HT_home_elo_rating\n    \n    return df\n\ndef home_team_away_result(df):\n    for i in range(1, 11):\n        is_away_game = df[f'home_team_history_is_play_home_{i}'] == 0.0\n        away_goals = df.loc[is_away_game, f'home_team_history_goal_{i}']\n        opponent_goals = df.loc[is_away_game, f'home_team_history_opponent_goal_{i}']\n        result = pd.Series('no game', index=df.index)\n        if sum(is_away_game) != 0:  # if no away games, assign 0\n            temp_result = pd.Series(index=df.index)\n    \n            temp_result[is_away_game & (away_goals > opponent_goals)] = 2 # winning away higher reward\n            temp_result[is_away_game & (away_goals == opponent_goals)] = 1\n            temp_result[is_away_game & (away_goals < opponent_goals)] = -2\n            result.update(temp_result)\n        df[f'HT_away_result_{i}'] = result\n        non_no_game = result != 'no game'\n        HT_away_elo_rating = calculate_elo_rating(df[f'home_team_history_rating_{i}'][non_no_game], df[f'home_team_history_opponent_rating_{i}'][non_no_game], result[non_no_game])\n        df[f'HT_away_games_ELO_rating_{i}'] = HT_away_elo_rating\n\n    return df\n\ndef away_team_home_result(df):\n    for i in range(1, 11):\n        is_home_game = df[f'away_team_history_is_play_home_{i}'] == 1.0\n        home_goals = df.loc[is_home_game, f'away_team_history_goal_{i}']\n        opponent_goals = df.loc[is_home_game, f'away_team_history_opponent_goal_{i}']\n        result = pd.Series('no game', index=df.index)\n        if sum(is_home_game) != 0:  # if no away games, assign 0\n            temp_result = pd.Series(index=df.index)\n     \n            temp_result[is_home_game & (home_goals > opponent_goals)] = 1 # win\n            temp_result[is_home_game & (home_goals == opponent_goals)] = -1 #draw \n            temp_result[is_home_game & (home_goals < opponent_goals)] = -3 #loss\n            result.update(temp_result)\n        df[f'AT_home_result_{i}'] = result\n        non_no_game = result != 'no game'\n        AT_home_elo_rating = calculate_elo_rating(df[f'away_team_history_rating_{i}'][non_no_game], df[f'away_team_history_opponent_rating_{i}'][non_no_game], result[non_no_game])\n        df[f'AT_home_games_ELO_rating_{i}'] = AT_home_elo_rating\n\n    return df\n\ndef away_team_away_result(df):\n    for i in range(1, 11):\n        is_away_game = df[f'away_team_history_is_play_home_{i}'] == 0.0\n        away_goals = df.loc[is_away_game, f'away_team_history_goal_{i}']\n        opponent_goals = df.loc[is_away_game, f'away_team_history_opponent_goal_{i}']\n        result = pd.Series('no game', index=df.index)\n        if sum(is_away_game) != 0:  # if no away games, assign 0\n            temp_result = pd.Series(index=df.index)\n      \n            temp_result[is_away_game & (away_goals > opponent_goals)] = 2 # win\n            temp_result[is_away_game & (away_goals == opponent_goals)] = 1 #draw \n            temp_result[is_away_game & (away_goals < opponent_goals)] = -2 #loss\n            result.update(temp_result)\n        df[f'AT_away_result_{i}'] = result\n        non_no_game = result != 'no game'\n        AT_away_elo_rating = calculate_elo_rating(df[f'away_team_history_rating_{i}'][non_no_game], df[f'away_team_history_opponent_rating_{i}'][non_no_game], result[non_no_game])\n        df[f'AT_away_games_ELO_rating_{i}'] = AT_away_elo_rating\n    return df\n\ntrain = home_team_home_result(train)\ntest  = home_team_home_result(test)\n\ntrain = home_team_away_result(train)\ntest  = home_team_away_result(test)\n\ntrain = away_team_home_result(train)\ntest  = away_team_home_result(test)\n\ntrain = away_team_away_result(train)\ntest  = away_team_away_result(test)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:44:48.194259Z","iopub.execute_input":"2023-06-02T01:44:48.194573Z","iopub.status.idle":"2023-06-02T01:44:55.125167Z","shell.execute_reply.started":"2023-06-02T01:44:48.194552Z","shell.execute_reply":"2023-06-02T01:44:55.124085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef calculate_elo_sum_mean(df, column_names):\n    for column_name in column_names:\n        elo_sum = df[[f'{column_name}_{i}' for i in range(1, 11)]].sum(axis=1, skipna=True)\n        elo_mean = df[[f'{column_name}_{i}' for i in range(1, 11)]].mean(axis=1, skipna=True)\n\n        df[f'{column_name}_sum'] = elo_sum\n        df[f'{column_name}_mean'] = elo_mean\n\n    return df\n\ncolumn_names = ['HT_home_games_ELO_rating','HT_away_games_ELO_rating','AT_home_games_ELO_rating','AT_away_games_ELO_rating']\n# eventhough i dont need to list 'HT_away_games_ELO_rating','AT_home_games_ELO_rating' cause not going to use it \n\ndef upcoming_game_expected_result_ELO_sum_home_win(df):\n    for i in range(1, 11):\n        result = 0 #dummy result because below code i dont use it\n        home_away_elo_rating = calculate_elo_rating(df['AT_away_games_ELO_rating_sum'],df['HT_home_games_ELO_rating_sum'],result)\n        expected_result = 1 / (1 + 10 ** ((df['HT_home_games_ELO_rating_sum'] - df['AT_away_games_ELO_rating_sum']) / 400))\n        expected_transform = (10 ** ((df['HT_home_games_ELO_rating_sum']) / 400))\n        df['home_team_transformed_ELO_sum'] = expected_transform\n        df['home_team_expected_ELO_rating_sum_win'] = expected_result\n    return df\n\n\ndef upcoming_game_expected_result_ELO_sum_away_win(df):\n    for i in range(1, 11):\n        result = 0\n        home_away_elo_rating = calculate_elo_rating(df['AT_away_games_ELO_rating_sum'],df['HT_home_games_ELO_rating_sum'],result)\n        expected_result = 1 / (1 + 10 ** ((df['AT_away_games_ELO_rating_sum'] - df['HT_home_games_ELO_rating_sum']) / 400))\n        expected_transform = (10 ** ((df['AT_away_games_ELO_rating_sum']) / 400))\n        df['away_team_transformed_ELO_sum'] = expected_transform\n        df['home_team_expected_ELO_rating_sum_loss'] = expected_result\n    return df\n\ndef upcoming_game_expected_result_ELO_mean_home_win(df):\n    for i in range(1, 11):\n        result = 0\n        home_away_elo_rating = calculate_elo_rating(df['AT_away_games_ELO_rating_mean'],df['HT_home_games_ELO_rating_mean'],result)\n        expected_result = 1 / (1 + 10 ** ((df['HT_home_games_ELO_rating_mean'] - df['AT_away_games_ELO_rating_mean']) / 400))\n        expected_transform = (10 ** ((df['HT_home_games_ELO_rating_mean']) / 400))\n        df['home_team_transformed_ELO_mean'] = expected_transform\n        df['home_team_expected_ELO_rating_mean_win'] = expected_result\n    return df\n\ndef upcoming_game_expected_result_ELO_mean_away_win(df):\n    for i in range(1, 11):\n        result = 0\n        home_away_elo_rating = calculate_elo_rating(df['AT_away_games_ELO_rating_mean'],df['HT_home_games_ELO_rating_mean'],result)\n        expected_result = 1 / (1 + 10 ** ((df['AT_away_games_ELO_rating_mean']-df['HT_home_games_ELO_rating_mean']) / 400))\n        expected_transform = (10 ** ((df['AT_away_games_ELO_rating_mean']) / 400))\n        df['away_team_transformed_ELO_mean'] = expected_transform\n        df['home_team_expected_ELO_rating_mean_loss'] = expected_result\n    return df\n\ntrain = calculate_elo_sum_mean(train, column_names)\ntest = calculate_elo_sum_mean(test, column_names)\n\ntrain=upcoming_game_expected_result_ELO_sum_home_win(train)\ntest=upcoming_game_expected_result_ELO_sum_home_win(test)\n\ntrain=upcoming_game_expected_result_ELO_sum_away_win(train)\ntest=upcoming_game_expected_result_ELO_sum_away_win(test)\n\ntrain=upcoming_game_expected_result_ELO_mean_home_win(train)\ntest=upcoming_game_expected_result_ELO_mean_home_win(test)\n\ntrain=upcoming_game_expected_result_ELO_mean_away_win(train)\ntest=upcoming_game_expected_result_ELO_mean_away_win(test)\n\ndef calculate_draw_chance(df):\n    home_cont = (df['home_team_expected_ELO_rating_sum_win'] * 0.15)\n    away_cont = (df['home_team_expected_ELO_rating_sum_loss'] * 0.33)\n    updated_home_win_chance = df['home_team_expected_ELO_rating_sum_win'] - (df['home_team_expected_ELO_rating_sum_win'] * 0.15)\n    updated_away_win_chance = df['home_team_expected_ELO_rating_sum_loss'] - (df['home_team_expected_ELO_rating_sum_loss'] * 0.33)\n    updated_draw_chance = home_cont + away_cont\n    df['updated_home_win_chance'] = updated_home_win_chance\n    df['updated_away_win_chance'] = updated_away_win_chance\n    df['updated_draw_chance'] = updated_draw_chance\n    return df\n\ntrain = calculate_draw_chance(train)\ntest = calculate_draw_chance(test)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:45:23.362545Z","iopub.execute_input":"2023-06-02T01:45:23.362881Z","iopub.status.idle":"2023-06-02T01:45:27.347832Z","shell.execute_reply.started":"2023-06-02T01:45:23.362860Z","shell.execute_reply":"2023-06-02T01:45:27.346972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def HT_expected_win_percentage_sum(df):\n    expected_win = (df['home_team_transformed_ELO_sum'] / (df['home_team_transformed_ELO_sum'] + df['away_team_transformed_ELO_sum']))\n    df['home_win_chance_sum'] = expected_win\n    return df\n\ndef AT_expected_win_percentage_sum(df):\n    expected_win = (df['away_team_transformed_ELO_sum'] / (df['home_team_transformed_ELO_sum'] + df['away_team_transformed_ELO_sum']))\n    df['away_win_chance_sum'] = expected_win   \n    return df\n\n\ndef HT_expected_win_percentage_mean(df):\n    expected_win = (df['home_team_transformed_ELO_mean'] / (df['home_team_transformed_ELO_mean'] + df['away_team_transformed_ELO_mean']))\n    df['home_win_chance_mean'] = expected_win\n    return df\n\ndef AT_expected_win_percentage_mean(df):\n    expected_win = (df['away_team_transformed_ELO_mean'] / (df['home_team_transformed_ELO_mean'] + df['away_team_transformed_ELO_mean']))\n    df['away_win_chance_mean'] = expected_win   \n    return df\n\ntrain=HT_expected_win_percentage_sum(train)\ntest=HT_expected_win_percentage_sum(test)\n\ntrain=AT_expected_win_percentage_sum(train)\ntest=AT_expected_win_percentage_sum(test)\n\ntrain=HT_expected_win_percentage_mean(train)\ntest=HT_expected_win_percentage_mean(test)\n\ntrain=AT_expected_win_percentage_mean(train)\ntest=AT_expected_win_percentage_mean(test)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:45:30.586784Z","iopub.execute_input":"2023-06-02T01:45:30.587101Z","iopub.status.idle":"2023-06-02T01:45:30.600575Z","shell.execute_reply.started":"2023-06-02T01:45:30.587079Z","shell.execute_reply":"2023-06-02T01:45:30.599984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Replace 'no game' values with NaN\ntrain = train.replace('no game', np.nan)\n\n# Select columns that are not of string type\nnumerical_columns = train.select_dtypes(exclude=['object','datetime64']).columns\n\n# Convert selected numerical columns to float\ntrain[numerical_columns] = train[numerical_columns].astype(float)\n\n# Fill missing values with zero for numerical columns\ntrain[numerical_columns] = train[numerical_columns].fillna(0)\n\n# Now, train contains the processed data with string columns excluded and missing values handled for numerical columns","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:45:44.319960Z","iopub.execute_input":"2023-06-02T01:45:44.320277Z","iopub.status.idle":"2023-06-02T01:45:56.672088Z","shell.execute_reply.started":"2023-06-02T01:45:44.320254Z","shell.execute_reply":"2023-06-02T01:45:56.671234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# maps\ntarget2int = {'away': 2, 'draw': 0, 'home': 1}\nint2target = {x[1]: x[0] for x in target2int.items()}\n\nimport re\n\n# encode target\ntrain['target_int'] = train['target'].map(target2int)\n\n\nX_test = test.copy()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:46:29.092073Z","iopub.execute_input":"2023-06-02T01:46:29.092368Z","iopub.status.idle":"2023-06-02T01:46:29.190950Z","shell.execute_reply.started":"2023-06-02T01:46:29.092347Z","shell.execute_reply":"2023-06-02T01:46:29.190159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get the column names\ncolumn_names = list(train.columns)\n\n# Print the column names one line at a time\nfor column_name in column_names:\n    print(f'\"{column_name.strip()}\",')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Columns to exclude\ncolumns_to_exclude = [\n    \"id\", \"target\", \"home_team_name\", \"away_team_name\", \"match_date\", \"league_name\", \"league_id\", \"is_cup\",\n    \"home_team_coach_id\", \"away_team_coach_id\",\"target_int\"\n]\n\n# Generate the column names using a loop\nhome_team_history_match_dates = [f\"home_team_history_match_date_{i}\" for i in range(1, 11)]\nhome_team_history_coaches = [f\"home_team_history_coach_{i}\" for i in range(1, 11)]\naway_team_history_match_dates = [f\"away_team_history_match_date_{i}\" for i in range(1, 11)]\naway_team_history_coaches = [f\"away_team_history_coach_{i}\" for i in range(1, 11)]\ncolumns_to_exclude.extend(home_team_history_match_dates + home_team_history_coaches\n                          +away_team_history_match_dates+away_team_history_coaches )\n\n\n# Describe all columns except the excluded ones in the train DataFrame\ncolumns_to_use_in_ML = [col for col in train.columns if col not in columns_to_exclude]","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:47:22.079127Z","iopub.execute_input":"2023-06-02T01:47:22.079423Z","iopub.status.idle":"2023-06-02T01:47:22.085936Z","shell.execute_reply.started":"2023-06-02T01:47:22.079401Z","shell.execute_reply":"2023-06-02T01:47:22.085107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nfeatures = columns_to_use_in_ML\nlabel = 'target_int'\n   \n    \n    # Split data 70%-30% into training set and test set\nx_train, x_test, y_train, y_test = train_test_split(train[features].values,\n                                                    train[label].values,\n                                                    test_size=0.13,\n                                                    random_state=0)\n\nprint('Training Set: %d, Test Set: %d \\n' % (len(x_train), len(x_test)))","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:47:25.844192Z","iopub.execute_input":"2023-06-02T01:47:25.844517Z","iopub.status.idle":"2023-06-02T01:47:26.199238Z","shell.execute_reply.started":"2023-06-02T01:47:25.844493Z","shell.execute_reply":"2023-06-02T01:47:26.198108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.utils.data as td\n\n# Set random seed for reproducability\ntorch.manual_seed(0)\n\nprint(\"Libraries imported - ready to use PyTorch\", torch.__version__)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T01:47:29.540666Z","iopub.execute_input":"2023-06-02T01:47:29.541776Z","iopub.status.idle":"2023-06-02T01:47:31.833400Z","shell.execute_reply.started":"2023-06-02T01:47:29.541731Z","shell.execute_reply":"2023-06-02T01:47:31.832366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a dataset and loader for the training data and labels\ntrain_x = torch.from_numpy(x_train.astype(np.float32))\ntrain_y = torch.from_numpy(y_train.astype(np.int64))\ntrain_ds = td.TensorDataset(train_x, train_y)\ntrain_loader = td.DataLoader(train_ds, batch_size=33, shuffle=True, num_workers=20)\n\n# Create a dataset and loader for the test data and labels\ntest_x = torch.from_numpy(x_test.astype(np.float32))\ntest_y = torch.from_numpy(y_test.astype(np.int64))\ntest_ds = td.TensorDataset(test_x, test_y)\ntest_loader = td.DataLoader(test_ds, batch_size=33, shuffle=True, num_workers=20)\n\nprint('Ready to load data')","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:22:30.762378Z","iopub.execute_input":"2023-06-02T02:22:30.762728Z","iopub.status.idle":"2023-06-02T02:22:30.797822Z","shell.execute_reply.started":"2023-06-02T02:22:30.762692Z","shell.execute_reply":"2023-06-02T02:22:30.796791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of hidden layer nodes\nhl = 20\n\n# Define the neural network\nclass football(nn.Module):\n    def __init__(self):\n        super(football, self).__init__()\n        self.fc1 = nn.Linear(len(features), hl)\n        self.fc2 = nn.Linear(hl, hl)\n        \n    def forward(self, x):\n        x = torch.relu(self.fc1(x))\n        x = torch.relu(self.fc2(x))\n        \n        return x\n\n# Create a model instance from the network\nmodel = football()\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:22:39.378663Z","iopub.execute_input":"2023-06-02T02:22:39.379028Z","iopub.status.idle":"2023-06-02T02:22:39.387210Z","shell.execute_reply.started":"2023-06-02T02:22:39.379001Z","shell.execute_reply":"2023-06-02T02:22:39.386275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn.functional as F\n\n\ndef train(model, data_loader, optimizer, entropy_weight, discount_factor):\n    # Set the model to training mode\n    model.train()\n    train_loss = 0\n    \n    for batch, tensor in enumerate(data_loader):\n        data, target = tensor\n        # Feedforward\n        optimizer.zero_grad()\n        out = model(data)\n        loss = loss_criteria(out, target)\n        \n        # Calculate the entropy loss\n        entropy = torch.mean(torch.sum(-F.softmax(out, dim=1) * F.log_softmax(out, dim=1), dim=1))\n        loss += entropy_weight * entropy\n        \n        # Apply discount factor to the loss\n        loss *= discount_factor\n        \n        train_loss += loss.item()\n\n        # Backpropagate\n        loss.backward()\n        optimizer.step()\n\n    # Return average loss\n    avg_loss = train_loss / (batch+1)\n    print('Training set: Average loss: {:.6f}'.format(avg_loss))\n    return avg_loss\n           \n            \ndef test(model, data_loader):\n    # Switch the model to evaluation mode (so we don't backpropagate)\n    model.eval()\n    test_loss = 0\n    correct = 0\n\n    with torch.no_grad():\n        batch_count = 0\n        for batch, tensor in enumerate(data_loader):\n            batch_count += 1\n            data, target = tensor\n            # Get the predictions\n            out = model(data)\n\n            # Calculate the loss\n            test_loss += loss_criteria(out, target).item()\n\n            # Calculate the accuracy\n            _, predicted = torch.max(out.data, 1)\n            correct += torch.sum(target == predicted).item()\n            \n    # Calculate the average loss and total accuracy for this epoch\n    avg_loss = test_loss / batch_count\n    print('Validation set: Average loss: {:.6f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n        avg_loss, correct, len(data_loader.dataset),\n        100. * correct / len(data_loader.dataset)))\n    \n    # Return average loss for the epoch\n    return avg_loss\n\n# Specify the loss criteria (CrossEntropyLoss for multi-class classification)\nloss_criteria = nn.CrossEntropyLoss()\n\n# Use an \"Adam\" optimizer to adjust weights\n# (see https://pytorch.org/docs/stable/optim.html#algorithms for details of supported algorithms)\nlearning_rate = 0.0003\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\noptimizer.zero_grad()\n\n# Set the hyperparameters\nentropy_weight = 0.49  # Weight for the entropy loss\ndiscount_factor = 0.99  # Discount factor to apply to the loss\n\n# We'll track metrics for each epoch in these arrays\nepoch_nums = []\ntraining_loss = []\nvalidation_loss = []\n\n# Train over # epochs\nepochs = 25\nfor epoch in range(1, epochs + 1):\n    # Print the epoch number\n    print('Epoch: {}'.format(epoch))\n    \n    # Feed training data into the model to optimize the weights\n    train_loss = train(model, train_loader, optimizer, entropy_weight, discount_factor)\n    \n    # Feed the test data into the model to check its performance\n    test_loss = test(model, test_loader)\n    \n    # Log the metrics for this epoch\n    epoch_nums.append(epoch)\n    training_loss.append(train_loss)\n    validation_loss.append(test_loss)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:22:54.077825Z","iopub.execute_input":"2023-06-02T02:22:54.078184Z","iopub.status.idle":"2023-06-02T02:30:35.327335Z","shell.execute_reply.started":"2023-06-02T02:22:54.078159Z","shell.execute_reply":"2023-06-02T02:30:35.326292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%matplotlib inline\nfrom matplotlib import pyplot as plt\n\nplt.plot(epoch_nums, training_loss)\nplt.plot(epoch_nums, validation_loss)\nplt.xlabel('epoch')\nplt.ylabel('loss')\nplt.legend(['training', 'validation'], loc='upper right')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:30:44.047601Z","iopub.execute_input":"2023-06-02T02:30:44.048006Z","iopub.status.idle":"2023-06-02T02:30:44.255045Z","shell.execute_reply.started":"2023-06-02T02:30:44.047974Z","shell.execute_reply":"2023-06-02T02:30:44.253783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pytorch doesn't have a built-in confusion matrix metric, so we'll use SciKit-Learn\nfrom sklearn.metrics import confusion_matrix\nimport numpy as np\n\n# Set the model to evaluate mode\nmodel.eval()\n\n# Get predictions for the test data\nx = torch.Tensor(x_test).float()\n_, predicted = torch.max(model(x).data, 1)\n\n# Plot the confusion matrix\ncm = confusion_matrix(y_test, predicted.numpy())\n\n# Get unique classes\nunique_classes = np.unique(np.concatenate((y_test, predicted)))\n\n# Set the tick marks\ntick_marks = np.arange(len(unique_classes))\n\nplt.imshow(cm, interpolation=\"nearest\", cmap=plt.cm.Blues)\nplt.colorbar()\nplt.xticks(tick_marks, unique_classes, rotation=45)\nplt.yticks(tick_marks, unique_classes)\nplt.xlabel(\"Actual Result\")\nplt.ylabel(\"Predicted Result\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:10:50.190213Z","iopub.execute_input":"2023-06-02T02:10:50.190583Z","iopub.status.idle":"2023-06-02T02:10:50.407917Z","shell.execute_reply.started":"2023-06-02T02:10:50.190552Z","shell.execute_reply":"2023-06-02T02:10:50.406638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"xxxxxxxxxxxxxxxxxxx################################xxxxxxxxxxxxxxxx","metadata":{}},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\n\n# Train a random forest model on the training set\nmodel_RF = RandomForestClassifier().fit(x_train, y_train)\nprint(model_RF)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:15:29.837685Z","iopub.execute_input":"2023-06-02T02:15:29.838509Z","iopub.status.idle":"2023-06-02T02:17:30.471524Z","shell.execute_reply.started":"2023-06-02T02:15:29.838480Z","shell.execute_reply":"2023-06-02T02:17:30.470908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions_RF = model_RF.predict(x_test)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:18:14.778112Z","iopub.execute_input":"2023-06-02T02:18:14.778458Z","iopub.status.idle":"2023-06-02T02:18:15.362774Z","shell.execute_reply.started":"2023-06-02T02:18:14.778432Z","shell.execute_reply":"2023-06-02T02:18:15.361849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score\n\nprint('Accuracy: ', accuracy_score(y_test, predictions_RF))","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:18:59.028981Z","iopub.execute_input":"2023-06-02T02:18:59.029322Z","iopub.status.idle":"2023-06-02T02:18:59.036543Z","shell.execute_reply.started":"2023-06-02T02:18:59.029299Z","shell.execute_reply":"2023-06-02T02:18:59.035531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score, f1_score\n\n# Calculate the accuracy\naccuracy = accuracy_score(y_test, predictions_RF)\n\n# Calculate the F1 score using the macro average\nf1 = f1_score(y_test, predictions_RF, average='macro')\n\n# Print the accuracy and F1 score\nprint('Accuracy:', accuracy)\nprint('F1 Score (macro):', f1)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:20:00.147154Z","iopub.execute_input":"2023-06-02T02:20:00.147473Z","iopub.status.idle":"2023-06-02T02:20:00.158259Z","shell.execute_reply.started":"2023-06-02T02:20:00.147451Z","shell.execute_reply":"2023-06-02T02:20:00.157457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import mean_squared_error, r2_score\n\nmse = mean_squared_error(y_test, predictions_RF)\nprint(\"MSE:\", mse)\n\nrmse = np.sqrt(mse)\nprint(\"RMSE:\", rmse)\n\nr2 = r2_score(y_test, predictions_RF)\nprint(\"R2:\", r2)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T02:20:47.197674Z","iopub.execute_input":"2023-06-02T02:20:47.198051Z","iopub.status.idle":"2023-06-02T02:20:47.206600Z","shell.execute_reply.started":"2023-06-02T02:20:47.198018Z","shell.execute_reply":"2023-06-02T02:20:47.205097Z"},"trusted":true},"execution_count":null,"outputs":[]}]}