{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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)\nimport datatable as dt\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\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","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nfor dirname, _, filenames in os.walk('/kaggle/input/riiid-test-answer-prediction'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n        \ntrain_path = \"../input/riiid-test-answer-prediction/train.csv\"\nquestions_path = \"../input/riiid-test-answer-prediction/questions.csv\"\nlectures_path = \"../input/riiid-test-answer-prediction/lectures.csv\"\n\ntest = \"../input/riiid-test-answer-prediction/example_test.csv\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_types_dict = {\n    'user_id': 'int32', \n    'content_id': 'int16', \n    'answered_correctly': 'int8', \n    'prior_question_elapsed_time': 'float32', \n    'prior_question_had_explanation': 'bool'\n}\n\ntarget = 'answered_correctly'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/train.csv',\n                       low_memory=False, \n                       nrows=500)\n#train_df = train_df.iloc[:500, :]\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# add the feature seen_lecutre \ndf2 = train_df[['user_id','content_type_id']].drop_duplicates()\ndf2['content_type_id'] = df2.content_type_id.apply(lambda x: 1 if x == 0 else 2)\ndf2 = df2.groupby('user_id').sum().reset_index()\ndf2 = df2.rename(index = str, columns = {\"content_type_id\":\"seen_lecture\"})\ndf2['seen_lecture'] = df2.seen_lecture.apply(lambda x: x-1)\ntrain_df = train_df.merge(df2, how='left', on='user_id')\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# construct new features\n# answer for the previous questions\ntrain_df['lag'] = train_df.groupby('user_id')[target].shift()\n\n# cumulative number of correct answers\ncum = train_df.groupby('user_id')['lag'].agg(['cumsum', 'cumcount'])\n# calculate the correctness\ntrain_df['user_correctness'] = cum['cumsum'] / cum['cumcount']\n# drop the 'lag' feature\ntrain_df.drop(columns = ['lag'], inplace = True)\n\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Overall correctness of users\nuser_agg = train_df.groupby('user_id')[target].agg(['sum', 'count'])\n                                                                               \n# Overall difficulty of questions\ncontent_agg = train_df.groupby('content_id')[target].agg(['sum', 'count'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# merge the question dataset\nquestions_df = pd.read_csv(\n    '../input/riiid-test-answer-prediction/questions.csv', \n    usecols = [0, 3],\n    dtype = {'question_id': 'int16', 'part': 'int8'}\n)\ntrain_df = pd.merge(train_df, questions_df, left_on = 'content_id', right_on = 'question_id', how = 'left')\ntrain_df.drop(columns = ['question_id'], inplace = True)\n\n# How many questions have been answered in each content ID?\ntrain_df['content_count'] = train_df['content_id'].map(content_agg['count']).astype('int32')\n\ntrain_df\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nuser_characteristics = train_df.groupby('user_id').agg({'answered_correctly':\n                                                  ['mean', 'median', 'std', 'skew', 'count']})\nuser_characteristics.columns = [\n    'mean_user_acc',\n    'median_user_acc',\n    'std_user_acc',\n    'skew_user_acc',\n    'number_of_answered_q'\n]\nuser_characteristics.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# We saw earlier some dependencies between answered_correctly and the frequency of task_container_id. \n# Therefore I want to add some features for the task_container_id\ntask_container_characteristics = train_df.groupby('task_container_id').agg({'answered_correctly':\n                                                                      ['mean', 'median', 'std', 'skew', 'count']})\ntask_container_characteristics.columns = [\n    'mean_task_acc',\n    'median_task_acc',\n    'std_task_acc',\n    'skew_task_acc',\n    'number_of_asked_task_containers'\n]\ntask_container_characteristics.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"content_characteristics = train_df.groupby('content_id').agg({'answered_correctly':\n                                                        ['mean', 'median', 'std', 'skew', 'count']})\ncontent_characteristics.columns = [\n    'mean_acc',\n    'median_acc',\n    'std_acc',\n    'skew_acc',\n    'number_of_asked_q'\n]\ncontent_characteristics.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = train_df.copy()\ndf = df.merge(user_characteristics, how='left', on='user_id')\ndf = df.merge(task_container_characteristics, how='left', on='task_container_id')\ndf = df.merge(content_characteristics, how='left', on='content_id')\ndf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Drop features that we are not going to use in our model\nfeatures = [\n    'prior_question_elapsed_time', \n    'prior_question_had_explanation',\n    'mean_user_acc',\n    'median_user_acc',\n    'std_user_acc',\n    'skew_user_acc',\n    'number_of_answered_q',\n    'mean_task_acc',\n    'median_task_acc',\n    'std_task_acc',\n    'skew_task_acc',\n    'number_of_asked_task_containers',\n    'mean_acc',\n    'median_acc',\n    'std_acc',\n    'skew_acc',\n    'number_of_asked_q',\n    'user_correctness',\n    'seen_lecture'\n]\n\ncol_to_drop = set(df.columns.values.tolist()).difference(features + [target])\nfor col in col_to_drop:\n    del df[col]\n    \ndf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['prior_question_had_explanation'] = df['prior_question_had_explanation'].fillna(value=False).astype(bool)\ndf = df.fillna(value=0.5)\ndf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}