{"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":"markdown","source":"### Importing Modules","metadata":{}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n%matplotlib inline\n\n\nfrom sklearn.model_selection import train_test_split\n# !pip install river\n# from river.ensemble import AdaptiveRandomForestClassifier\n\nfrom lightgbm import LGBMClassifier\n\nfrom sklearn import preprocessing\nfrom sklearn.metrics import log_loss\n\nimport gc","metadata":{"execution":{"iopub.status.busy":"2022-10-08T10:56:55.815715Z","iopub.execute_input":"2022-10-08T10:56:55.816473Z","iopub.status.idle":"2022-10-08T10:56:56.908594Z","shell.execute_reply.started":"2022-10-08T10:56:55.816402Z","shell.execute_reply":"2022-10-08T10:56:56.907751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading Data","metadata":{}},{"cell_type":"markdown","source":"In order to load the data, the format has been changed into parquet to reduce size of the data and increase reading time.\n\nRef: [DR. ALVINLEENH](https://www.kaggle.com/datasets/alvinleenh/tps-rocket-league-data-float16-parquet-format)","metadata":{}},{"cell_type":"code","source":"train0_df = pd.read_parquet('/kaggle/input/tps-rocket-league-data-float16-parquet-format/train_0.parquet.gzip')\ntrain0_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-10-08T10:56:56.914739Z","iopub.execute_input":"2022-10-08T10:56:56.915406Z","iopub.status.idle":"2022-10-08T10:57:02.106087Z","shell.execute_reply.started":"2022-10-08T10:56:56.915363Z","shell.execute_reply":"2022-10-08T10:57:02.105290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Feature Engineering","metadata":{"execution":{"iopub.status.busy":"2022-10-03T02:59:05.817073Z","iopub.execute_input":"2022-10-03T02:59:05.818128Z","iopub.status.idle":"2022-10-03T02:59:05.823310Z","shell.execute_reply.started":"2022-10-03T02:59:05.818082Z","shell.execute_reply":"2022-10-03T02:59:05.822058Z"}}},{"cell_type":"markdown","source":"Preprocessing techniques inspired from [here](https://www.kaggle.com/code/alvinleenh/tpsoct22-ctb-baseline-with-parquet/notebook?scriptVersionId=107048249) and [here](https://www.kaggle.com/code/samuelcortinhas/tps-oct-22-rocket-league-eda/notebook), showcasing critical insight into the data at hand.","metadata":{}},{"cell_type":"code","source":"def preprocessing(data):    \n    \n    # Goal coordinates\n    \n    goal1_coord = (0,-102.5,1.2)\n    goal2_coord = (0,102.5,1.2)\n    \n    \n    \n    # for train\n    if 'game_num' in data.columns:\n        data = data.drop(columns=['game_num', 'event_id', 'event_time',\n                                  'player_scoring_next','team_scoring_next'])\n    # for test\n    elif 'id' in data.columns:\n        data = data.drop(columns='id')\n        \n    \n    \n    # Derived features -   \n    \n    # For each player\n    for i in range(6):\n        \n        # Distance difference between ball and each player across x,y,z axes.\n        data[f'p_{i}_x_diff'] = abs(data['ball_pos_x']-data[f'p{i}_pos_x'])\n        data[f'p_{i}_y_diff'] = abs(data['ball_pos_y']-data[f'p{i}_pos_y'])\n        data[f'p_{i}_z_diff'] = abs(data['ball_pos_z']-data[f'p{i}_pos_z'])\n        \n        # Checking if player hit the ball\n        data[f'p_{i}_hit_ball'] = 0\n        data.loc[(data[f'p_{i}_x_diff']+data[f'p_{i}_y_diff']+data[f'p_{i}_z_diff']) < 10,f'p_{i}_hit_ball'] = 1\n        \n        # Absolute velocity of the players\n        data[f'p{i}_speed'] = np.sqrt((data[f'p{i}_vel_x']**2)+(data[f'p{i}_vel_y']**2)+(data[f'p{i}_vel_z']**2))\n        \n        # Indicating demolished player\n        data[f'p{i}_demo'] = (data[f'p{i}_pos_x'].isna()).astype(int)\n        \n        # Distance from goal1 and goal2\n            # Euclidean\n        data[f'p{i}_dist_to_goal1_euclid'] = np.sqrt((data[f'p{i}_pos_x']-goal1_coord[0])**2 + (data[f'p{i}_pos_y']-goal1_coord[1])**2 + (data[f'p{i}_pos_z']-goal1_coord[2])**2)\n        data[f'p{i}_dist_to_goal2_euclid'] = np.sqrt((data[f'p{i}_pos_x']-goal2_coord[0])**2 + (data[f'p{i}_pos_y']-goal2_coord[1])**2 + (data[f'p{i}_pos_z']-goal2_coord[2])**2)\n            # Manhattan\n        data[f'p{i}_dist_to_goal1_manhat'] = np.absolute(data[f'p{i}_pos_x']-goal1_coord[0]) + np.absolute(data[f'p{i}_pos_y']-goal1_coord[1]) + np.absolute(data[f'p{i}_pos_z']-goal1_coord[2])\n        data[f'p{i}_dist_to_goal2_manhat'] = np.absolute(data[f'p{i}_pos_x']-goal2_coord[0]) + np.absolute(data[f'p{i}_pos_y']-goal2_coord[1]) + np.absolute(data[f'p{i}_pos_z']-goal2_coord[2])     \n    \n    \n    # For ball or team\n    \n    # Absolute velocity of ball\n    data['ball_speed'] = np.sqrt((data['ball_vel_x']**2)+(data['ball_vel_y']**2)+(data['ball_vel_z']**2))\n    \n    # Active players in each team\n    data['active_players_A'] = 3-data['p0_demo']-data['p1_demo']-data['p2_demo']\n    data['active_players_B'] = 3-data['p3_demo']-data['p4_demo']-data['p5_demo']\n    \n    # Distance of ball from goal1 and goal2\n    \n        # Euclidean\n    data['ball_dist_to_goal1_euclid'] = np.sqrt((data['ball_pos_x']-goal1_coord[0])**2 + (data['ball_pos_y']-goal1_coord[1])**2 + (data['ball_pos_z']-goal1_coord[2])**2)\n    data['ball_dist_to_goal2_euclid'] = np.sqrt((data['ball_pos_x']-goal2_coord[0])**2 + (data['ball_pos_y']-goal2_coord[1])**2 + (data['ball_pos_z']-goal2_coord[2])**2)\n    \n        # Manhattan\n    data['ball_dist_to_goal1_manhat'] = np.absolute(data['ball_pos_x']-goal1_coord[0]) + np.absolute(data['ball_pos_y']-goal1_coord[1]) + np.absolute(data['ball_pos_z']-goal1_coord[2])\n    data['ball_dist_to_goal2_manhat'] = np.absolute(data['ball_pos_x']-goal2_coord[0]) + np.absolute(data['ball_pos_y']-goal2_coord[1]) + np.absolute(data['ball_pos_z']-goal2_coord[2])\n    \n    \n    return data","metadata":{"execution":{"iopub.status.busy":"2022-10-08T10:57:02.107303Z","iopub.execute_input":"2022-10-08T10:57:02.107781Z","iopub.status.idle":"2022-10-08T10:57:02.127671Z","shell.execute_reply.started":"2022-10-08T10:57:02.107751Z","shell.execute_reply":"2022-10-08T10:57:02.126585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ### Baseline Adaptive RF Classifier\n\n# Adaptive RF Classifier is an enesmble approach created by River, a library for online machine learning. With the help of its ability to address incremental model training, all the train datasets can be learnt by our model in a continuous fashion.","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-10-08T10:57:02.131117Z","iopub.execute_input":"2022-10-08T10:57:02.131584Z","iopub.status.idle":"2022-10-08T10:57:02.141400Z","shell.execute_reply.started":"2022-10-08T10:57:02.131541Z","shell.execute_reply":"2022-10-08T10:57:02.140578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train test split\n\ntrain = preprocessing(train0_df)\ndel train0_df\ngc.collect()\n\ntarget_cols = ['team_A_scoring_within_10sec','team_B_scoring_within_10sec']\n\nX = train.drop(target_cols, axis=1)\ny = train[target_cols]","metadata":{"execution":{"iopub.status.busy":"2022-10-08T10:57:02.143186Z","iopub.execute_input":"2022-10-08T10:57:02.144043Z","iopub.status.idle":"2022-10-08T10:57:05.153805Z","shell.execute_reply.started":"2022-10-08T10:57:02.143996Z","shell.execute_reply":"2022-10-08T10:57:05.152639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Baseline LightGBM","metadata":{}},{"cell_type":"markdown","source":"Parameters taken from [CHENSN](https://www.kaggle.com/code/chal1ce/lightgbm-baseline-with-feature-importance/notebook?scriptVersionId=107069949)'s work, which is clear and precise.","metadata":{}},{"cell_type":"code","source":"# Respective models for each team\n\n# modelA = AdaptiveRandomForestClassifier(n_models = 500, max_features = None)\n# modelB = AdaptiveRandomForestClassifier(n_models = 500, max_features = None)\n\nparams = {\n    'objective': 'binary',\n    'seed': 42,\n    'num_leaves': 128,\n    'n_estimators': 350,\n    'max_depth': 10,\n    'learning_rate': 0.1,\n    #'feature_fraction': 0.75,\n    'subsample': 0.7,\n    'subsample_freq': 8,\n    'n_jobs': -1,\n    'reg_alpha': 1,\n    'reg_lambda': 2,\n    'min_child_samples': 100,\n}\n\nmodelA = LGBMClassifier(**params)\nmodelB = LGBMClassifier(**params)\n\nbase_model = [modelA, modelB]","metadata":{"execution":{"iopub.status.busy":"2022-10-08T10:57:05.155132Z","iopub.execute_input":"2022-10-08T10:57:05.155470Z","iopub.status.idle":"2022-10-08T10:57:05.162496Z","shell.execute_reply.started":"2022-10-08T10:57:05.155440Z","shell.execute_reply":"2022-10-08T10:57:05.161270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training initial model\n\ndef initial_model(X,y, model):\n    # train test split\n    X_train, X_val, y_train, y_val = train_test_split(X,y,test_size=0.2, random_state=56)\n    pred_train = y_val[target_cols].copy()\n    \n    # training and evaluation\n    for i, feature in enumerate(target_cols):\n        model[i].fit(X_train,y_train[feature],verbose=True)\n        pred_train.loc[:,feature] = model[i].predict_proba(X_val)[:,1]\n        loss = log_loss(y_val[feature],pred_train[feature])\n        print(f\"\\nLogloss for {feature} = {loss}\\n\")\n        \ninitial_model(X,y,base_model)","metadata":{"execution":{"iopub.status.busy":"2022-10-08T10:57:05.164213Z","iopub.execute_input":"2022-10-08T10:57:05.164649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training online model\n\ndef incremental_model(X,y,base_model):\n    # train test split\n        X_train, X_val, y_train, y_val = train_test_split(X,y,test_size=0.15, random_state=56)\n        pred_train = y_val[target_cols].copy()\n        \n        # training and evaluation\n        for i, feature in enumerate(target_cols):\n            base_model[i].fit(X_train, y_train[feature], init_model = base_model[i], verbose=True)\n            pred_train.loc[:,feature] = base_model[i].predict_proba(X_val)[:,1]\n            loss = log_loss(y_val[feature],pred_train[feature])\n            print(f\"\\nLogloss for {feature} = {loss}\\n\")\n\n\n# Use 3 out of 10 datasets            \nfor i in range(1,3):\n    train_df = pd.read_parquet(f'/kaggle/input/tps-rocket-league-data-float16-parquet-format/train_{i}.parquet.gzip')\n    train = preprocessing(train_df)\n    del train_df\n    gc.collect()\n    \n    X = train.drop(target_cols, axis=1)\n    y = train[target_cols]\n    print(f'\\n\\nDataset: train_{i}\\n')\n    incremental_model(X,y,base_model)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prediction on Test","metadata":{}},{"cell_type":"code","source":"# loading test data \ntest_df = pd.read_parquet('/kaggle/input/tps-rocket-league-data-float16-parquet-format/test.parquet.gzip')\n\n# loading sample submission file to make use of labels\nsubmission_df = pd.read_csv('/kaggle/input/tabular-playground-series-oct-2022/sample_submission.csv')\n\n# feature engineering\ntest = preprocessing(test_df)\n\n# Prediction\npred_test = submission_df[target_cols].copy()\n\nfor i, feature in enumerate(target_cols):\n    pred_test.loc[:,feature] = base_model[i].predict_proba(test)[:,1]\n\npred_test.head(5)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Submission","metadata":{}},{"cell_type":"code","source":"submission_csv = pd.DataFrame({'id': submission_df.id, \n                       'team_A_scoring_within_10sec': pred_test['team_A_scoring_within_10sec'],\n                       'team_B_scoring_within_10sec': pred_test['team_B_scoring_within_10sec']})\nsubmission_csv.to_csv('submission.csv', index=False)\nsubmission_csv.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}