{"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":"2022-05-04T18:07:36.373294Z","iopub.execute_input":"2022-05-04T18:07:36.373794Z","iopub.status.idle":"2022-05-04T18:07:36.391713Z","shell.execute_reply.started":"2022-05-04T18:07:36.373687Z","shell.execute_reply":"2022-05-04T18:07:36.390716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport pickle\npd.set_option('display.max_columns', None)\nfrom sklearn.preprocessing import OneHotEncoder\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Activation, Flatten\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn import metrics\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom sklearn.feature_selection import SelectKBest\nfrom sklearn.feature_selection import f_classif","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:36.393437Z","iopub.execute_input":"2022-05-04T18:07:36.394654Z","iopub.status.idle":"2022-05-04T18:07:38.948389Z","shell.execute_reply.started":"2022-05-04T18:07:36.394610Z","shell.execute_reply":"2022-05-04T18:07:38.947432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# read the training and testing dataset\ntrain_df_raw = pd.read_csv('/kaggle/input/football-match-probability-prediction/train.csv')\ntest_df_raw = pd.read_csv('/kaggle/input/football-match-probability-prediction/test.csv')","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:38.949611Z","iopub.execute_input":"2022-05-04T18:07:38.949861Z","iopub.status.idle":"2022-05-04T18:07:45.387252Z","shell.execute_reply.started":"2022-05-04T18:07:38.949830Z","shell.execute_reply":"2022-05-04T18:07:45.386101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# function to process the training and testing dataset\ndef pre_process_data(df, type = 'train'):\n    train_df_1 = df.drop(labels=['home_team_name', 'away_team_name'], axis=1)\n    train_df_1['is_cup'] = train_df_1['is_cup'].astype(str)\n    \n    def NormalizeData(data):\n        return (data - np.min(data)) / (np.max(data) - np.min(data))\n\n#     for col in train_df_1.columns:\n#         if col != 'target':\n#             train_df_1[col] = NormalizeData(train_df_1[col])\n            \n    # gap between its last match and matchday\n    train_df_1['away_team_history_match_date_1'] = train_df_1['away_team_history_match_date_1'].fillna(train_df_1['match_date'])\n    train_df_1['home_team_history_match_date_1'] = train_df_1['home_team_history_match_date_1'].fillna(train_df_1['match_date'])\n    train_df_1['home_team_rest'] = (pd.to_datetime(train_df_1['match_date']) - pd.to_datetime(train_df_1['home_team_history_match_date_1'])).dt.days\n    train_df_1['away_team_rest'] = (pd.to_datetime(train_df_1['match_date']) - pd.to_datetime(train_df_1['away_team_history_match_date_1'])).dt.days\n    \n    # convert all matchdates to pandas datetime\n    match_date_col_names = [col for col in train_df_1.columns\n                            if 'date' in col]\n    train_df_1 = train_df_1.drop(labels=match_date_col_names, axis=1)\n    \n    coach_columns = [col for col in train_df_1.columns\n                            if 'coach' in col]\n    train_df_1 = train_df_1.drop(labels=coach_columns, axis=1)\n    \n    league_columns = [col for col in train_df_1.columns\n                            if 'league' in col]\n    train_df_1 = train_df_1.drop(labels=league_columns, axis=1)\n    \n#     results_df_3 = train_df_1.copy()\n    # carry out onehot-encoding to the categorical columns\n    catCols = [col for col in train_df_1.columns \n               if train_df_1[col].dtype==\"O\" and col != 'target']\n    print(catCols)\n    if type != 'test':\n        onehot_encoder = OneHotEncoder(sparse=False,handle_unknown='ignore')\n        object_train_onehot = onehot_encoder.fit_transform(train_df_1[catCols])\n        object_train_onehot = pd.DataFrame(object_train_onehot, columns=onehot_encoder.get_feature_names())\n        object_train_onehot.set_index(train_df_1.index, inplace=True)\n        data_other_cols = train_df_1.drop(columns=catCols)\n\n        results_df_3 = pd.concat([data_other_cols, object_train_onehot], axis=1)\n\n        #exporting the departure encoder\n        output = open('onehotencoder_1.pkl', 'wb')\n        pickle.dump(onehot_encoder, output)\n        output.close()\n    else:\n        print('testing going on')\n        pkl_file = open('onehotencoder_1.pkl', 'rb')\n        onehot_encoder = pickle.load(pkl_file) \n        pkl_file.close()\n        object_train_onehot = onehot_encoder.transform(train_df_1[catCols])\n        object_train_onehot = pd.DataFrame(object_train_onehot, columns=onehot_encoder.get_feature_names())\n        object_train_onehot.set_index(train_df_1.index, inplace=True)\n        data_other_cols = train_df_1.drop(columns=catCols)\n\n        results_df_3 = pd.concat([data_other_cols, object_train_onehot], axis=1)\n\n    #fill up null values\n    check_list = list(range(1,11,1))\n    for check in check_list:\n        results_df_3[f'home_team_history_is_play_home_{check}'] = results_df_3[f'home_team_history_is_play_home_{check}'].fillna(0)\n        results_df_3[f'home_team_history_is_cup_{check}'] = results_df_3[f'home_team_history_is_cup_{check}'].fillna(0)\n        results_df_3[f'home_team_history_goal_{check}'] = results_df_3[f'home_team_history_goal_{check}'].fillna(results_df_3[f'home_team_history_goal_{check}'].mean())\n        results_df_3[f'home_team_history_opponent_goal_{check}'] = results_df_3[f'home_team_history_opponent_goal_{check}'].fillna(results_df_3[f'home_team_history_opponent_goal_{check}'].mean())\n        results_df_3[f'home_team_history_rating_{check}'] = results_df_3[f'home_team_history_rating_{check}'].fillna(results_df_3[f'home_team_history_rating_{check}'].mean())\n        results_df_3[f'home_team_history_opponent_rating_{check}'] = results_df_3[f'home_team_history_opponent_rating_{check}'].fillna(results_df_3[f'home_team_history_opponent_rating_{check}'].mean())\n        results_df_3[f'away_team_history_is_play_home_{check}'] = results_df_3[f'away_team_history_is_play_home_{check}'].fillna(0)\n        results_df_3[f'away_team_history_is_cup_{check}'] = results_df_3[f'away_team_history_is_cup_{check}'].fillna(0)\n        results_df_3[f'away_team_history_goal_{check}'] = results_df_3[f'away_team_history_goal_{check}'].fillna(results_df_3[f'away_team_history_goal_{check}'].mean())\n        results_df_3[f'away_team_history_opponent_goal_{check}'] = results_df_3[f'away_team_history_opponent_goal_{check}'].fillna(results_df_3[f'away_team_history_opponent_goal_{check}'].mean())\n        results_df_3[f'away_team_history_rating_{check}'] = results_df_3[f'away_team_history_rating_{check}'].fillna(results_df_3[f'away_team_history_rating_{check}'].mean())\n        results_df_3[f'away_team_history_opponent_rating_{check}'] = results_df_3[f'away_team_history_opponent_rating_{check}'].fillna(results_df_3[f'away_team_history_opponent_rating_{check}'].mean())\n\n    \n    def NormalizeData(data):\n        return (data - np.min(data)) / (np.max(data) - np.min(data))\n\n    for col in results_df_3.columns:\n        if col != 'target':\n            results_df_3[col] = NormalizeData(results_df_3[col])\n            \n    \n    return results_df_3","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:45.389741Z","iopub.execute_input":"2022-05-04T18:07:45.390056Z","iopub.status.idle":"2022-05-04T18:07:45.412421Z","shell.execute_reply.started":"2022-05-04T18:07:45.390015Z","shell.execute_reply":"2022-05-04T18:07:45.411507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results_df_3 = pre_process_data(train_df_raw, type = 'train')","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:45.413628Z","iopub.execute_input":"2022-05-04T18:07:45.414764Z","iopub.status.idle":"2022-05-04T18:07:46.279717Z","shell.execute_reply.started":"2022-05-04T18:07:45.414723Z","shell.execute_reply":"2022-05-04T18:07:46.278850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df_1 = results_df_3.copy()","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:46.281135Z","iopub.execute_input":"2022-05-04T18:07:46.281386Z","iopub.status.idle":"2022-05-04T18:07:46.410693Z","shell.execute_reply.started":"2022-05-04T18:07:46.281358Z","shell.execute_reply":"2022-05-04T18:07:46.410028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# normalizing the features\ndef NormalizeData(data):\n    return (data - np.min(data)) / (np.max(data) - np.min(data))\n\nfor col in train_df_1.columns:\n    if col != 'target':\n        train_df_1[col] = NormalizeData(train_df_1[col])\n","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:46.411935Z","iopub.execute_input":"2022-05-04T18:07:46.412673Z","iopub.status.idle":"2022-05-04T18:07:46.648237Z","shell.execute_reply.started":"2022-05-04T18:07:46.412639Z","shell.execute_reply":"2022-05-04T18:07:46.647274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df_1","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:46.650152Z","iopub.execute_input":"2022-05-04T18:07:46.650573Z","iopub.status.idle":"2022-05-04T18:07:46.787081Z","shell.execute_reply.started":"2022-05-04T18:07:46.650538Z","shell.execute_reply":"2022-05-04T18:07:46.786392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get the independent variables from the dataframe\nX = np.array(train_df_1.drop(labels=['id', 'target'], axis=1))\nX = np.asarray(X).astype(np.float32)\n# extract the dependent variables\ny_1 = np.array(list(train_df_1['target']))\n\n# create the dummies for the dependent variables\npred_dummy_col_names = pd.get_dummies(y_1).columns\ny = np.array(pd.get_dummies(y_1))\n\n# train_test split\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:48.071514Z","iopub.execute_input":"2022-05-04T18:07:48.072630Z","iopub.status.idle":"2022-05-04T18:07:49.060051Z","shell.execute_reply.started":"2022-05-04T18:07:48.072559Z","shell.execute_reply":"2022-05-04T18:07:49.059267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# number of y variables\nnum_labels = y.shape[1]\nnum_labels","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:07:49.718494Z","iopub.execute_input":"2022-05-04T18:07:49.718995Z","iopub.status.idle":"2022-05-04T18:07:49.725340Z","shell.execute_reply.started":"2022-05-04T18:07:49.718933Z","shell.execute_reply":"2022-05-04T18:07:49.724746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# build sequential model for neural network\nmodel = Sequential()\n# first layer\nmodel.add(Dense(300, input_shape = (X_train.shape[1],)))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.3))\n# second layer\nmodel.add(Dense(200))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.3))\n# third layer\nmodel.add(Dense(100))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.3))\n\n# final layer\nmodel.add(Dense(num_labels))\nmodel.add(Activation('softmax'))","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:29:59.453713Z","iopub.execute_input":"2022-05-04T18:29:59.455067Z","iopub.status.idle":"2022-05-04T18:29:59.527594Z","shell.execute_reply.started":"2022-05-04T18:29:59.454998Z","shell.execute_reply":"2022-05-04T18:29:59.526482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# we are using accuracy as a metric, since the data is more or less balanced\nmodel.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='Adam')\n\nnum_epochs = 100\nbatch_size = 1028\n\ncheckpoint = ModelCheckpoint(filepath='saved_models/match_prediction.h5',\n                             verbose=1, save_best_only=True)\n\nes = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10)\n\nhistory = model.fit(X_train, y_train,validation_data=(X_test, y_test), batch_size=batch_size, \n                    callbacks=[es,checkpoint], epochs=num_epochs)","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:30:00.281358Z","iopub.execute_input":"2022-05-04T18:30:00.281705Z","iopub.status.idle":"2022-05-04T18:30:34.504404Z","shell.execute_reply.started":"2022-05-04T18:30:00.281671Z","shell.execute_reply":"2022-05-04T18:30:34.503475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# evaluate the model\n_, train_acc = model.evaluate(X_train, y_train, verbose=0)\n_, test_acc = model.evaluate(X_test, y_test, verbose=0)\nprint('Train: %.3f, Test: %.3f' % (train_acc, test_acc))\n# plot training history\nplt.plot(history.history['loss'], label='train')\nplt.plot(history.history['val_loss'], label='test')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-04T18:30:39.938899Z","iopub.execute_input":"2022-05-04T18:30:39.939877Z","iopub.status.idle":"2022-05-04T18:30:45.650453Z","shell.execute_reply.started":"2022-05-04T18:30:39.939829Z","shell.execute_reply":"2022-05-04T18:30:45.649391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pre-process the testing dataset\ntest_df_1 = pre_process_data(test_df_raw, type='test')\n\ndef NormalizeData(data):\n    return (data - np.min(data)) / (np.max(data) - np.min(data))\n\nfor col in test_df_1.columns:\n    if col != 'id':\n        test_df_1[col] = NormalizeData(test_df_1[col])\n\ntest_df_1 = test_df_1.fillna(0)\n# get the independent variables from the dataframe\nX = np.array(test_df_1.drop(labels=['id'], axis=1))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load the saved model\nfrom tensorflow.keras.models import load_model\nsaved_model = load_model('saved_models/match_prediction.h5')\n\n# get the test results\ntest_results = saved_model.predict(X)\ntest_results_df = pd.DataFrame(test_results, columns=pred_dummy_col_names)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_results_df['id'] = test_df_raw['id']\ntest_results_df = test_results_df[['id','home', 'draw', 'away']]\ntest_results_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_results_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}