{"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":"# EDA: Predict Student Performance from Game Play","metadata":{}},{"cell_type":"code","source":"import pandas as pd, numpy as np, gc\nfrom IPython.display import display\n\nimport jo_wilder","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:33:35.683418Z","iopub.execute_input":"2023-04-10T16:33:35.683873Z","iopub.status.idle":"2023-04-10T16:33:35.689904Z","shell.execute_reply.started":"2023-04-10T16:33:35.683835Z","shell.execute_reply":"2023-04-10T16:33:35.688837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Ground truth labels","metadata":{}},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/train_labels.csv')","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:45:37.498033Z","iopub.execute_input":"2023-04-10T16:45:37.498437Z","iopub.status.idle":"2023-04-10T16:45:37.851883Z","shell.execute_reply.started":"2023-04-10T16:45:37.498401Z","shell.execute_reply":"2023-04-10T16:45:37.850806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:45:41.379161Z","iopub.execute_input":"2023-04-10T16:45:41.379566Z","iopub.status.idle":"2023-04-10T16:45:41.392319Z","shell.execute_reply.started":"2023-04-10T16:45:41.379530Z","shell.execute_reply":"2023-04-10T16:45:41.391298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split \"session_id\" into session id AND question number\n\ndef split_session_id(df):\n    df = df.copy()\n    df['q'] = df['session_id'].apply(lambda x: x.split('_')[-1][1:]).astype('int8')\n    df['session_id'] = df['session_id'].apply(lambda x: x.split('_')[0]).astype('int64')\n    return df\n\nlabels = split_session_id(labels)\n\ndisplay(labels)","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:46:52.886658Z","iopub.execute_input":"2023-04-10T16:46:52.887057Z","iopub.status.idle":"2023-04-10T16:46:53.415807Z","shell.execute_reply.started":"2023-04-10T16:46:52.887023Z","shell.execute_reply":"2023-04-10T16:46:53.414670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# All 18 questions appear 23562 times\nlabels['q'].value_counts().sort_index()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:47:11.019307Z","iopub.execute_input":"2023-04-10T16:47:11.019783Z","iopub.status.idle":"2023-04-10T16:47:11.032777Z","shell.execute_reply.started":"2023-04-10T16:47:11.019742Z","shell.execute_reply":"2023-04-10T16:47:11.031762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# There are 23562 unique session ids\nlabels['session_id'].nunique()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:49:13.089556Z","iopub.execute_input":"2023-04-10T16:49:13.090747Z","iopub.status.idle":"2023-04-10T16:49:13.112993Z","shell.execute_reply.started":"2023-04-10T16:49:13.090677Z","shell.execute_reply":"2023-04-10T16:49:13.111989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Each session id has 18 unique questions\n(labels.groupby('session_id')['q'].nunique() == 18).all()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:49:59.653082Z","iopub.execute_input":"2023-04-10T16:49:59.653508Z","iopub.status.idle":"2023-04-10T16:49:59.710656Z","shell.execute_reply.started":"2023-04-10T16:49:59.653468Z","shell.execute_reply":"2023-04-10T16:49:59.709631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Session ids in game play data *'train.csv'*","metadata":{}},{"cell_type":"code","source":"session_id = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/train.csv', usecols=[0])","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:51:38.880620Z","iopub.execute_input":"2023-04-10T16:51:38.881088Z","iopub.status.idle":"2023-04-10T16:53:06.311803Z","shell.execute_reply.started":"2023-04-10T16:51:38.881029Z","shell.execute_reply":"2023-04-10T16:53:06.310704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# There are a lot more rows than there are in train_labels.csv\nsession_id","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:03:19.891923Z","iopub.execute_input":"2023-04-10T17:03:19.892347Z","iopub.status.idle":"2023-04-10T17:03:19.906276Z","shell.execute_reply.started":"2023-04-10T17:03:19.892311Z","shell.execute_reply":"2023-04-10T17:03:19.905204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# There are 23562 session_ids, and each appears different number of times\nsession_id.groupby('session_id')['session_id'].count()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:53:47.515396Z","iopub.execute_input":"2023-04-10T16:53:47.516618Z","iopub.status.idle":"2023-04-10T16:53:48.310715Z","shell.execute_reply.started":"2023-04-10T16:53:47.516570Z","shell.execute_reply":"2023-04-10T16:53:48.309721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# It's the same set of session ids that is in 'train_labels.csv' as 'train.csv'.\nset(labels['session_id'].unique()) == set(session_id['session_id'].unique())","metadata":{"execution":{"iopub.status.busy":"2023-04-10T16:54:45.563257Z","iopub.execute_input":"2023-04-10T16:54:45.563651Z","iopub.status.idle":"2023-04-10T16:54:45.745356Z","shell.execute_reply.started":"2023-04-10T16:54:45.563614Z","shell.execute_reply":"2023-04-10T16:54:45.744270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The first 881 rows belong to the same session id.\n# Let's look at the whole training data for this session id.\nsession_id.iloc[:881]['session_id'].unique()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:05:53.569096Z","iopub.execute_input":"2023-04-10T17:05:53.569532Z","iopub.status.idle":"2023-04-10T17:05:53.580192Z","shell.execute_reply.started":"2023-04-10T17:05:53.569493Z","shell.execute_reply":"2023-04-10T17:05:53.579169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del labels, session_id\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:05:55.777485Z","iopub.execute_input":"2023-04-10T17:05:55.777929Z","iopub.status.idle":"2023-04-10T17:05:56.171894Z","shell.execute_reply.started":"2023-04-10T17:05:55.777889Z","shell.execute_reply":"2023-04-10T17:05:56.170588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/train.csv', nrows=881)","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:06:28.337224Z","iopub.execute_input":"2023-04-10T17:06:28.337631Z","iopub.status.idle":"2023-04-10T17:06:28.351960Z","shell.execute_reply.started":"2023-04-10T17:06:28.337596Z","shell.execute_reply":"2023-04-10T17:06:28.350544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# From the column names it looks like each row represents an event during the game play. \n# e.g. 'event_name', 'elapsed_time'\ndf","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:06:31.350682Z","iopub.execute_input":"2023-04-10T17:06:31.351124Z","iopub.status.idle":"2023-04-10T17:06:31.392083Z","shell.execute_reply.started":"2023-04-10T17:06:31.351088Z","shell.execute_reply":"2023-04-10T17:06:31.391064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Notice that there is no question number like in train_labels.csv\ndf.columns","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:12:53.570239Z","iopub.execute_input":"2023-04-10T17:12:53.570710Z","iopub.status.idle":"2023-04-10T17:12:53.578348Z","shell.execute_reply.started":"2023-04-10T17:12:53.570668Z","shell.execute_reply":"2023-04-10T17:12:53.577090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Looks like index more or less increases with elapsed time\ndf.plot(x='elapsed_time', y='index');","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:21:48.966127Z","iopub.execute_input":"2023-04-10T18:21:48.967351Z","iopub.status.idle":"2023-04-10T18:21:49.189635Z","shell.execute_reply.started":"2023-04-10T18:21:48.967284Z","shell.execute_reply":"2023-04-10T18:21:49.188497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The level also increases as the game goes on\ndf.plot(x='elapsed_time', y='level');","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:16:50.733629Z","iopub.execute_input":"2023-04-10T17:16:50.734105Z","iopub.status.idle":"2023-04-10T17:16:50.923180Z","shell.execute_reply.started":"2023-04-10T17:16:50.734059Z","shell.execute_reply":"2023-04-10T17:16:50.921925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The levels in the level_group column correspond to the levels in level column.\n(\n    df.groupby('level_group')['level']\n    .value_counts()\n    .sort_index()\n)","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:19:31.661416Z","iopub.execute_input":"2023-04-10T17:19:31.661843Z","iopub.status.idle":"2023-04-10T17:19:31.681822Z","shell.execute_reply.started":"2023-04-10T17:19:31.661805Z","shell.execute_reply":"2023-04-10T17:19:31.680829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Numeric columns' summary\nnumeric_summary = df.describe()\n\nnumeric_summary","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:26:40.447537Z","iopub.execute_input":"2023-04-10T17:26:40.447966Z","iopub.status.idle":"2023-04-10T17:26:40.503248Z","shell.execute_reply.started":"2023-04-10T17:26:40.447929Z","shell.execute_reply":"2023-04-10T17:26:40.502147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Object-type columns' summary\ndf.describe(include=['O'])","metadata":{"execution":{"iopub.status.busy":"2023-04-10T17:36:19.541938Z","iopub.execute_input":"2023-04-10T17:36:19.542401Z","iopub.status.idle":"2023-04-10T17:36:19.571952Z","shell.execute_reply.started":"2023-04-10T17:36:19.542361Z","shell.execute_reply":"2023-04-10T17:36:19.570784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del df\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:23:40.472410Z","iopub.execute_input":"2023-04-10T18:23:40.472906Z","iopub.status.idle":"2023-04-10T18:23:41.049786Z","shell.execute_reply.started":"2023-04-10T18:23:40.472864Z","shell.execute_reply":"2023-04-10T18:23:41.048785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Public test data and sample submission","metadata":{}},{"cell_type":"code","source":"ss = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:23:47.982472Z","iopub.execute_input":"2023-04-10T18:23:47.983307Z","iopub.status.idle":"2023-04-10T18:23:48.011578Z","shell.execute_reply.started":"2023-04-10T18:23:47.983261Z","shell.execute_reply":"2023-04-10T18:23:48.010262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:24:27.125309Z","iopub.execute_input":"2023-04-10T18:24:27.126205Z","iopub.status.idle":"2023-04-10T18:24:27.137042Z","shell.execute_reply.started":"2023-04-10T18:24:27.126159Z","shell.execute_reply":"2023-04-10T18:24:27.135689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss = split_session_id(ss)","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:24:29.597809Z","iopub.execute_input":"2023-04-10T18:24:29.598234Z","iopub.status.idle":"2023-04-10T18:24:29.605754Z","shell.execute_reply.started":"2023-04-10T18:24:29.598195Z","shell.execute_reply":"2023-04-10T18:24:29.604772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# There are 3 session ids, and for each there're 18 quesionts (1-18)\n# for which we need to predict whether they are answered correctly.\n\nss.groupby('session_id')['q'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:25:56.819689Z","iopub.execute_input":"2023-04-10T18:25:56.820381Z","iopub.status.idle":"2023-04-10T18:25:56.832232Z","shell.execute_reply.started":"2023-04-10T18:25:56.820339Z","shell.execute_reply":"2023-04-10T18:25:56.831067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv('/kaggle/input/predict-student-performance-from-game-play/test.csv')","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:34:33.051154Z","iopub.execute_input":"2023-04-10T18:34:33.051641Z","iopub.status.idle":"2023-04-10T18:34:33.089837Z","shell.execute_reply.started":"2023-04-10T18:34:33.051591Z","shell.execute_reply":"2023-04-10T18:34:33.088740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# These are the same session ids as in sample_submission.csv.\n# Each session has a different number of events.\ntest.groupby('session_id')['index'].count()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:35:44.517355Z","iopub.execute_input":"2023-04-10T18:35:44.518529Z","iopub.status.idle":"2023-04-10T18:35:44.527890Z","shell.execute_reply.started":"2023-04-10T18:35:44.518474Z","shell.execute_reply":"2023-04-10T18:35:44.526660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Events at all 23 levels (0-22) are available for each session id\ntest.groupby('session_id')['level'].nunique()","metadata":{"execution":{"iopub.status.busy":"2023-04-10T18:38:07.121795Z","iopub.execute_input":"2023-04-10T18:38:07.122683Z","iopub.status.idle":"2023-04-10T18:38:07.132091Z","shell.execute_reply.started":"2023-04-10T18:38:07.122636Z","shell.execute_reply":"2023-04-10T18:38:07.131047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission API","metadata":{}},{"cell_type":"code","source":"# It looks like predictions for all 18 questions will not\n# be submitted at the same time.  \n# Instead, we'll first be given game play data for levels 0-4, and\n# we will need to submit our predictions for questions 1-3.\n# Only after this is done will we then be given data for levels 5-12, and\n# we will need to submit our predictions for questions 4-13.\n# Finally, after doing this, game data for levels 13-22 will be given, and \n# we will need to submit our predictions for questions 14-18.\n\n\nenv = jo_wilder.make_env()\niter_test = env.iter_test()\n\nfor i in range(10):\n    try:\n        test, ss = next(iter_test)\n    except StopIteration:\n        break\n    \n    print(f'Submission batch {i}')\n    \n    print(\n        'Session ids in test data:', test['session_id'].unique()\n    )\n    print(\n        'Game levels in test data', test['level'].unique()\n    )\n    \n    print(\n        'Session ids in sample submission',\n        ss['session_id'].apply(lambda x: x.split('_')[0]).astype('int64').unique()\n         )\n    print(\n        'Questions in sample submission', \n        ss['session_id'].apply(lambda x: x.split('_')[-1][1:]).astype('int8').unique()\n         )\n\n    print()\n    \n    env.predict(ss)   # Need to submit before loading next batch of test data","metadata":{"execution":{"iopub.status.busy":"2023-04-09T13:38:59.192984Z","iopub.execute_input":"2023-04-09T13:38:59.193322Z","iopub.status.idle":"2023-04-09T13:38:59.308412Z","shell.execute_reply.started":"2023-04-09T13:38:59.193295Z","shell.execute_reply":"2023-04-09T13:38:59.307416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}