{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":45533,"databundleVersionId":5748852,"sourceType":"competition"}],"dockerImageVersionId":30458,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_addons as tfa\nimport tensorflow_decision_forests as tfdf\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt","metadata":{"id":"IanlX-Eqn2O5","execution":{"iopub.status.busy":"2024-11-03T14:09:44.238664Z","iopub.execute_input":"2024-11-03T14:09:44.239529Z","iopub.status.idle":"2024-11-03T14:09:56.460064Z","shell.execute_reply.started":"2024-11-03T14:09:44.239470Z","shell.execute_reply":"2024-11-03T14:09:56.458471Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"TensorFlow Decision Forests v\" + tfdf.__version__)\nprint(\"TensorFlow Addons v\" + tfa.__version__)\nprint(\"TensorFlow v\" + tf.__version__)","metadata":{"id":"gLpK2yAen2O7","execution":{"iopub.status.busy":"2024-11-03T14:09:56.462439Z","iopub.execute_input":"2024-11-03T14:09:56.463084Z","iopub.status.idle":"2024-11-03T14:09:56.469891Z","shell.execute_reply.started":"2024-11-03T14:09:56.463042Z","shell.execute_reply":"2024-11-03T14:09:56.468671Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Reference: https://www.kaggle.com/competitions/predict-student-performance-from-game-play/discussion/384359\ndtypes={\n    'elapsed_time':np.int32,\n    'event_name':'category',\n    'name':'category',\n    'level':np.uint8,\n    'room_coor_x':np.float32,\n    'room_coor_y':np.float32,\n    'screen_coor_x':np.float32,\n    'screen_coor_y':np.float32,\n    'hover_duration':np.float32,\n    'text':'category',\n    'fqid':'category',\n    'room_fqid':'category',\n    'text_fqid':'category',\n    'fullscreen':'category',\n    'hq':'category',\n    'music':'category',\n    'level_group':'category'}\n\ndataset_df = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/train.csv', dtype=dtypes)\nprint(\"Full train dataset shape is {}\".format(dataset_df.shape))","metadata":{"id":"_XItl24kn2O7","execution":{"iopub.status.busy":"2024-11-03T14:09:56.471110Z","iopub.execute_input":"2024-11-03T14:09:56.471859Z","iopub.status.idle":"2024-11-03T14:12:02.017223Z","shell.execute_reply.started":"2024-11-03T14:09:56.471802Z","shell.execute_reply":"2024-11-03T14:12:02.015408Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Display the first 5 examples\ndataset_df.head(5)","metadata":{"id":"-RTRVRiWn2O8","execution":{"iopub.status.busy":"2024-11-03T14:12:02.022647Z","iopub.execute_input":"2024-11-03T14:12:02.023069Z","iopub.status.idle":"2024-11-03T14:12:02.067959Z","shell.execute_reply.started":"2024-11-03T14:12:02.023033Z","shell.execute_reply":"2024-11-03T14:12:02.066542Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/train_labels.csv')","metadata":{"id":"KD4uayl2n2O9","execution":{"iopub.status.busy":"2024-11-03T14:12:02.069600Z","iopub.execute_input":"2024-11-03T14:12:02.070217Z","iopub.status.idle":"2024-11-03T14:12:02.480159Z","shell.execute_reply.started":"2024-11-03T14:12:02.070170Z","shell.execute_reply":"2024-11-03T14:12:02.478649Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels['session'] = labels.session_id.apply(lambda x: int(x.split('_')[0]) )\nlabels['q'] = labels.session_id.apply(lambda x: int(x.split('_')[-1][1:]) )","metadata":{"id":"Kva8_Dbqn2O9","execution":{"iopub.status.busy":"2024-11-03T14:12:02.481752Z","iopub.execute_input":"2024-11-03T14:12:02.482892Z","iopub.status.idle":"2024-11-03T14:12:03.254518Z","shell.execute_reply.started":"2024-11-03T14:12:02.482829Z","shell.execute_reply":"2024-11-03T14:12:03.253040Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Display the first 5 examples\nlabels.head(5)","metadata":{"id":"0eD-KZMvn2O-","execution":{"iopub.status.busy":"2024-11-03T14:12:03.256033Z","iopub.execute_input":"2024-11-03T14:12:03.257277Z","iopub.status.idle":"2024-11-03T14:12:03.272249Z","shell.execute_reply.started":"2024-11-03T14:12:03.257225Z","shell.execute_reply":"2024-11-03T14:12:03.270631Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(3, 3))\nplot_df = labels.correct.value_counts()\nplot_df.plot(kind=\"bar\", color=['b', 'c'])","metadata":{"id":"-l9wBCTYn2O_","execution":{"iopub.status.busy":"2024-11-03T14:12:03.274329Z","iopub.execute_input":"2024-11-03T14:12:03.274779Z","iopub.status.idle":"2024-11-03T14:12:03.527957Z","shell.execute_reply.started":"2024-11-03T14:12:03.274736Z","shell.execute_reply":"2024-11-03T14:12:03.526629Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 20))\nplt.subplots_adjust(hspace=0.5, wspace=0.5)\nplt.suptitle(\"\\\"Correct\\\" column values for each question\", fontsize=14, y=0.94)\nfor n in range(1,19):\n    #print(n, str(n))\n    ax = plt.subplot(6, 3, n)\n\n    # filter df and plot ticker on the new subplot axis\n    plot_df = labels.loc[labels.q == n]\n    plot_df = plot_df.correct.value_counts()\n    plot_df.plot(ax=ax, kind=\"bar\", color=['b', 'c'])\n    \n    # chart formatting\n    ax.set_title(\"Question \" + str(n))\n    ax.set_xlabel(\"\")\n","metadata":{"id":"X238--97n2O_","execution":{"iopub.status.busy":"2024-11-03T14:12:03.529872Z","iopub.execute_input":"2024-11-03T14:12:03.530593Z","iopub.status.idle":"2024-11-03T14:12:05.378608Z","shell.execute_reply.started":"2024-11-03T14:12:03.530549Z","shell.execute_reply":"2024-11-03T14:12:05.377553Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"CATEGORICAL = ['event_name', 'name','fqid', 'room_fqid', 'text_fqid']\nNUMERICAL = ['elapsed_time','level','page','room_coor_x', 'room_coor_y', \n        'screen_coor_x', 'screen_coor_y', 'hover_duration']","metadata":{"id":"cCZWGiL_n2PA","execution":{"iopub.status.busy":"2024-11-03T14:12:05.382808Z","iopub.execute_input":"2024-11-03T14:12:05.383539Z","iopub.status.idle":"2024-11-03T14:12:05.388905Z","shell.execute_reply.started":"2024-11-03T14:12:05.383496Z","shell.execute_reply":"2024-11-03T14:12:05.387578Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Reference: https://www.kaggle.com/code/cdeotte/random-forest-baseline-0-664/notebook\n\ndef feature_engineer(dataset_df):\n    dfs = []\n    for c in CATEGORICAL:\n        tmp = dataset_df.groupby(['session_id','level_group'])[c].agg('nunique')\n        tmp.name = tmp.name + '_nunique'\n        dfs.append(tmp)\n    for c in NUMERICAL:\n        tmp = dataset_df.groupby(['session_id','level_group'])[c].agg('mean')\n        dfs.append(tmp)\n    for c in NUMERICAL:\n        tmp = dataset_df.groupby(['session_id','level_group'])[c].agg('std')\n        tmp.name = tmp.name + '_std'\n        dfs.append(tmp)\n    dataset_df = pd.concat(dfs,axis=1)\n    dataset_df = dataset_df.fillna(-1)\n    dataset_df = dataset_df.reset_index()\n    dataset_df = dataset_df.set_index('session_id')\n    return dataset_df","metadata":{"id":"nHWhAOtTn2PA","execution":{"iopub.status.busy":"2024-11-03T14:12:05.390637Z","iopub.execute_input":"2024-11-03T14:12:05.391420Z","iopub.status.idle":"2024-11-03T14:12:05.401905Z","shell.execute_reply.started":"2024-11-03T14:12:05.391376Z","shell.execute_reply":"2024-11-03T14:12:05.400368Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset_df = feature_engineer(dataset_df)\nprint(\"Full prepared dataset shape is {}\".format(dataset_df.shape))","metadata":{"id":"JKcoPoemn2PA","execution":{"iopub.status.busy":"2024-11-03T14:12:05.403389Z","iopub.execute_input":"2024-11-03T14:12:05.408093Z","iopub.status.idle":"2024-11-03T14:12:46.786004Z","shell.execute_reply.started":"2024-11-03T14:12:05.408031Z","shell.execute_reply":"2024-11-03T14:12:46.784164Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Display the first 5 examples\ndataset_df.head(5)","metadata":{"id":"mvQEsdV1n2PB","execution":{"iopub.status.busy":"2024-11-03T14:12:46.787915Z","iopub.execute_input":"2024-11-03T14:12:46.788294Z","iopub.status.idle":"2024-11-03T14:12:46.824837Z","shell.execute_reply.started":"2024-11-03T14:12:46.788258Z","shell.execute_reply":"2024-11-03T14:12:46.823800Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset_df.describe()","metadata":{"id":"DRusg-N1n2PB","execution":{"iopub.status.busy":"2024-11-03T14:12:46.826134Z","iopub.execute_input":"2024-11-03T14:12:46.826790Z","iopub.status.idle":"2024-11-03T14:12:46.979013Z","shell.execute_reply.started":"2024-11-03T14:12:46.826744Z","shell.execute_reply":"2024-11-03T14:12:46.977620Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"figure, axis = plt.subplots(3, 2, figsize=(10, 10))\n\nfor name, data in dataset_df.groupby('level_group'):\n    axis[0, 0].plot(range(1, len(data['room_coor_x_std'])+1), data['room_coor_x_std'], label=name)\n    axis[0, 1].plot(range(1, len(data['room_coor_y_std'])+1), data['room_coor_y_std'], label=name)\n    axis[1, 0].plot(range(1, len(data['screen_coor_x_std'])+1), data['screen_coor_x_std'], label=name)\n    axis[1, 1].plot(range(1, len(data['screen_coor_y_std'])+1), data['screen_coor_y_std'], label=name)\n    axis[2, 0].plot(range(1, len(data['hover_duration'])+1), data['hover_duration_std'], label=name)\n    axis[2, 1].plot(range(1, len(data['elapsed_time_std'])+1), data['elapsed_time_std'], label=name)\n    \n\naxis[0, 0].set_title('room_coor_x')\naxis[0, 1].set_title('room_coor_y')\naxis[1, 0].set_title('screen_coor_x')\naxis[1, 1].set_title('screen_coor_y')\naxis[2, 0].set_title('hover_duration')\naxis[2, 1].set_title('elapsed_time_std')\n\nfor i in range(3):\n    axis[i, 0].legend()\n    axis[i, 1].legend()\n\nplt.show()","metadata":{"id":"mXIiaq_bn2PC","execution":{"iopub.status.busy":"2024-11-03T14:12:46.980884Z","iopub.execute_input":"2024-11-03T14:12:46.981787Z","iopub.status.idle":"2024-11-03T14:12:49.739498Z","shell.execute_reply.started":"2024-11-03T14:12:46.981738Z","shell.execute_reply":"2024-11-03T14:12:49.738187Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def split_dataset(dataset, test_ratio=0.20):\n    USER_LIST = dataset.index.unique()\n    split = int(len(USER_LIST) * (1 - 0.20))\n    return dataset.loc[USER_LIST[:split]], dataset.loc[USER_LIST[split:]]\n\ntrain_x, valid_x = split_dataset(dataset_df)\nprint(\"{} examples in training, {} examples in testing.\".format(\n    len(train_x), len(valid_x)))","metadata":{"id":"OZfTcCJfn2PC","execution":{"iopub.status.busy":"2024-11-03T14:12:49.741168Z","iopub.execute_input":"2024-11-03T14:12:49.741539Z","iopub.status.idle":"2024-11-03T14:12:50.041835Z","shell.execute_reply.started":"2024-11-03T14:12:49.741504Z","shell.execute_reply":"2024-11-03T14:12:50.040513Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tfdf.keras.get_all_models()","metadata":{"id":"KZBdcVU1n2PE","execution":{"iopub.status.busy":"2024-11-03T14:12:50.043311Z","iopub.execute_input":"2024-11-03T14:12:50.044712Z","iopub.status.idle":"2024-11-03T14:12:50.051487Z","shell.execute_reply.started":"2024-11-03T14:12:50.044634Z","shell.execute_reply":"2024-11-03T14:12:50.050345Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Fetch the unique list of user sessions in the validation dataset. We assigned \n# `session_id` as the index of our feature engineered dataset. Hence fetching \n# the unique values in the index column will give us a list of users in the \n# validation set.\nVALID_USER_LIST = valid_x.index.unique()\n\n# Create a dataframe for storing the predictions of each question for all users\n# in the validation set.\n# For this, the required size of the data frame is: \n# (no: of users in validation set  x no of questions).\n# We will initialize all the predicted values in the data frame to zero.\n# The dataframe's index column is the user `session_id`s. \nprediction_df = pd.DataFrame(data=np.zeros((len(VALID_USER_LIST),18)), index=VALID_USER_LIST)\n\n# Create an empty dictionary to store the models created for each question.\nmodels = {}\n\n# Create an empty dictionary to store the evaluation score for each question.\nevaluation_dict ={}","metadata":{"id":"7Brds67Wn2PD","execution":{"iopub.status.busy":"2024-11-03T14:12:50.053039Z","iopub.execute_input":"2024-11-03T14:12:50.053740Z","iopub.status.idle":"2024-11-03T14:12:50.066460Z","shell.execute_reply.started":"2024-11-03T14:12:50.053677Z","shell.execute_reply":"2024-11-03T14:12:50.065015Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Iterate through questions 1 to 18 to train models for each question, evaluate\n# the trained model and store the predicted values.\nfor q_no in range(1,19):\n\n    # Select level group for the question based on the q_no.\n    if q_no<=3: grp = '0-4'\n    elif q_no<=13: grp = '5-12'\n    elif q_no<=22: grp = '13-22'\n    print(\"### q_no\", q_no, \"grp\", grp)\n    \n        \n    # Filter the rows in the datasets based on the selected level group. \n    train_df = train_x.loc[train_x.level_group == grp]\n    train_users = train_df.index.values\n    valid_df = valid_x.loc[valid_x.level_group == grp]\n    valid_users = valid_df.index.values\n\n    # Select the labels for the related q_no.\n    train_labels = labels.loc[labels.q==q_no].set_index('session').loc[train_users]\n    valid_labels = labels.loc[labels.q==q_no].set_index('session').loc[valid_users]\n\n    # Add the label to the filtered datasets.\n    train_df[\"correct\"] = train_labels[\"correct\"]\n    valid_df[\"correct\"] = valid_labels[\"correct\"]\n\n    # There's one more step required before we can train the model. \n    # We need to convert the datatset from Pandas format (pd.DataFrame)\n    # into TensorFlow Datasets format (tf.data.Dataset).\n    # TensorFlow Datasets is a high performance data loading library \n    # which is helpful when training neural networks with accelerators like GPUs and TPUs.\n    # We are omitting `level_group`, since it is not needed for training anymore.\n    train_ds = tfdf.keras.pd_dataframe_to_tf_dataset(train_df.loc[:, train_df.columns != 'level_group'], label=\"correct\")\n    valid_ds = tfdf.keras.pd_dataframe_to_tf_dataset(valid_df.loc[:, valid_df.columns != 'level_group'], label=\"correct\")\n\n    # We will now create the Gradient Boosted Trees Model with default settings. \n    # By default the model is set to train for a classification task.\n    gbtm = tfdf.keras.GradientBoostedTreesModel(verbose=0)\n    gbtm.compile(metrics=[\"accuracy\"])\n\n    # Train the model.\n    gbtm.fit(x=train_ds)\n\n    # Store the model\n    models[f'{grp}_{q_no}'] = gbtm\n\n    # Evaluate the trained model on the validation dataset and store the \n    # evaluation accuracy in the `evaluation_dict`.\n    inspector = gbtm.make_inspector()\n    inspector.evaluation()\n    evaluation = gbtm.evaluate(x=valid_ds,return_dict=True)\n    evaluation_dict[q_no] = evaluation[\"accuracy\"]         \n\n    # Use the trained model to make predictions on the validation dataset and \n    # store the predicted values in the `prediction_df` dataframe.\n    predict = gbtm.predict(x=valid_ds)\n    prediction_df.loc[valid_users, q_no-1] = predict.flatten()     ","metadata":{"id":"VBO3VCOJn2PF","execution":{"iopub.status.busy":"2024-11-03T14:12:50.071487Z","iopub.execute_input":"2024-11-03T14:12:50.071970Z","iopub.status.idle":"2024-11-03T14:15:04.262183Z","shell.execute_reply.started":"2024-11-03T14:12:50.071923Z","shell.execute_reply":"2024-11-03T14:15:04.260770Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for name, value in evaluation_dict.items():\n  print(f\"question {name}: accuracy {value:.4f}\")\n\nprint(\"\\nAverage accuracy\", sum(evaluation_dict.values())/18)","metadata":{"id":"qPOfPkm7n2PG","execution":{"iopub.status.busy":"2024-11-03T14:15:04.266481Z","iopub.execute_input":"2024-11-03T14:15:04.266921Z","iopub.status.idle":"2024-11-03T14:15:04.275995Z","shell.execute_reply.started":"2024-11-03T14:15:04.266881Z","shell.execute_reply":"2024-11-03T14:15:04.274863Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tfdf.model_plotter.plot_model_in_colab(models['0-4_1'], tree_idx=0, max_depth=3)","metadata":{"id":"od__6uAan2PG","execution":{"iopub.status.busy":"2024-11-03T14:15:04.277739Z","iopub.execute_input":"2024-11-03T14:15:04.278538Z","iopub.status.idle":"2024-11-03T14:15:04.302388Z","shell.execute_reply.started":"2024-11-03T14:15:04.278491Z","shell.execute_reply":"2024-11-03T14:15:04.301012Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Variable importances\n\nVariable importances generally indicate how much a feature contributes to the model predictions or quality. There are several ways to identify important features using TensorFlow Decision Forests. Let us pick one model from models dict and inspect it.\n\nLet us list the available Variable Importances for Decision Trees:","metadata":{"id":"emVV6509n2PG"}},{"cell_type":"code","source":"inspector = models['0-4_1'].make_inspector()\n\nprint(f\"Available variable importances:\")\nfor importance in inspector.variable_importances().keys():\n  print(\"\\t\", importance)","metadata":{"id":"d_gvL9nbn2PH","execution":{"iopub.status.busy":"2024-11-03T14:15:04.304270Z","iopub.execute_input":"2024-11-03T14:15:04.304622Z","iopub.status.idle":"2024-11-03T14:15:04.315889Z","shell.execute_reply.started":"2024-11-03T14:15:04.304588Z","shell.execute_reply":"2024-11-03T14:15:04.314381Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"As an example, let us display the important features for the Variable Importance NUM_AS_ROOT.\n\nThe larger the importance score for NUM_AS_ROOT, the more impact it has on the outcome of the model for Question 1(i.e., model\\[\"0-4_1\"\\]).\n\nBy default, the list is sorted from the most important to the least. From the output you can infer that the feature at the top of the list is used as the root node in most number of trees in the gradient boosted trees  than any other feature.","metadata":{"id":"rnfYz_aGn2PH"}},{"cell_type":"code","source":"# Each line is: (feature name, (index of the feature), importance score)\ninspector.variable_importances()[\"NUM_AS_ROOT\"]","metadata":{"id":"ZDsxqRrwn2PH","trusted":true,"execution":{"iopub.status.busy":"2024-11-03T14:15:04.317852Z","iopub.execute_input":"2024-11-03T14:15:04.318259Z","iopub.status.idle":"2024-11-03T14:15:04.326735Z","shell.execute_reply.started":"2024-11-03T14:15:04.318221Z","shell.execute_reply":"2024-11-03T14:15:04.325539Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Threshold-Moving for Imbalanced Classification\n\nSince the values of the column `correct` is fairly imbalanced, using the default threshold of `0.5` to map the predictions into classes 0 or 1 can result in poor performance. \nIn such cases, to improve performance we will calculate the `F1 score` for a certain range of thresholds and try to find the best threshold aka, threshold with highest `F1 score`. Then we will use this threshold to map the predicted probabilities to class labels 0 or 1.\n\nPlease note that we are using `F1 score` since it is a better metric than `accuracy` to evaluate problems with class imbalance.","metadata":{"id":"PIK5aUH-n2PH"}},{"cell_type":"code","source":"# Create a dataframe of required size:\n# (no: of users in validation set x no: of questions) initialized to zero values\n# to store true values of the label `correct`. \ntrue_df = pd.DataFrame(data=np.zeros((len(VALID_USER_LIST),18)), index=VALID_USER_LIST)\nfor i in range(18):\n    # Get the true labels.\n    tmp = labels.loc[labels.q == i+1].set_index('session').loc[VALID_USER_LIST]\n    true_df[i] = tmp.correct.values\n\nmax_score = 0; best_threshold = 0\n\n# Loop through threshold values from 0.4 to 0.8 and select the threshold with \n# the highest `F1 score`.\nfor threshold in np.arange(0.4,0.8,0.01):\n    metric = tfa.metrics.F1Score(num_classes=2,average=\"macro\",threshold=threshold)\n    y_true = tf.one_hot(true_df.values.reshape((-1)), depth=2)\n    y_pred = tf.one_hot((prediction_df.values.reshape((-1))>threshold).astype('int'), depth=2)\n    metric.update_state(y_true, y_pred)\n    f1_score = metric.result().numpy()\n    if f1_score > max_score:\n        max_score = f1_score\n        best_threshold = threshold\n        \nprint(\"Best threshold \", best_threshold, \"\\tF1 score \", max_score)","metadata":{"id":"2wptRs3In2PH","trusted":true,"execution":{"iopub.status.busy":"2024-11-03T14:15:04.328768Z","iopub.execute_input":"2024-11-03T14:15:04.329172Z","iopub.status.idle":"2024-11-03T14:15:05.542911Z","shell.execute_reply.started":"2024-11-03T14:15:04.329129Z","shell.execute_reply":"2024-11-03T14:15:05.541766Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission\n\nHere you'll use the `best_threshold` calculate in the previous cell","metadata":{"id":"ezA40GQ4n2PH"}},{"cell_type":"code","source":"# Reference\n# https://www.kaggle.com/code/philculliton/basic-submission-demo\n# https://www.kaggle.com/code/cdeotte/random-forest-baseline-0-664/notebook\n\n\nimport jo_wilder\nenv = jo_wilder.make_env()\niter_test = env.iter_test()\n\nlimits = {'0-4':(1,4), '5-12':(4,14), '13-22':(14,19)}\n\nfor (test, sample_submission) in iter_test:\n    test_df = feature_engineer(test)\n    grp = test_df.level_group.values[0]\n    a,b = limits[grp]\n    for t in range(a,b):\n        gbtm = models[f'{grp}_{t}']\n        test_ds = tfdf.keras.pd_dataframe_to_tf_dataset(test_df.loc[:, test_df.columns != 'level_group'])\n        predictions = gbtm.predict(test_ds)\n        mask = sample_submission.session_id.str.contains(f'q{t}')\n        n_predictions = (predictions > best_threshold).astype(int)\n        sample_submission.loc[mask,'correct'] = n_predictions.flatten()\n    \n    env.predict(sample_submission)","metadata":{"id":"gHiXTnTVn2PI","trusted":true,"execution":{"iopub.status.busy":"2024-11-03T14:15:05.544508Z","iopub.execute_input":"2024-11-03T14:15:05.544882Z","iopub.status.idle":"2024-11-03T14:15:11.260258Z","shell.execute_reply.started":"2024-11-03T14:15:05.544846Z","shell.execute_reply":"2024-11-03T14:15:11.259014Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! head submission.csv","metadata":{"id":"iYBXokAyn2PI","trusted":true,"execution":{"iopub.status.busy":"2024-11-03T14:15:11.262000Z","iopub.execute_input":"2024-11-03T14:15:11.262355Z","iopub.status.idle":"2024-11-03T14:15:12.379686Z","shell.execute_reply.started":"2024-11-03T14:15:11.262323Z","shell.execute_reply":"2024-11-03T14:15:12.378075Z"}},"outputs":[],"execution_count":null}]}