{"cells":[{"metadata":{},"cell_type":"markdown","source":"<h1> <center>Riiid! Answer Correctness Prediction </h1>\n   "},{"metadata":{},"cell_type":"markdown","source":"![](data:image/jpeg;base64,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)"},{"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)\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 5GB 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":{},"cell_type":"markdown","source":"<h2> Table of content</h2>\n<ul><li><a id=\"#preparation\"> Preperation </a> </li>\n    <li> <a id=\"#data\"> Load the datas </a> </li> \n    <li> <a id=\"#data_preparation\"> Data Preparation </a> </li>\n    <li> <a id=\"#feature_engineering\"> Feature engineering </a> </li>\n    <li> <a id=\"#exploration\"> Datas Explorations </a> </li>\n    <li> <a id=\"#preprocessing\"> Data preprocessing </a> </li>\n</ul>\n</br>"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"cell_type":"markdown","source":"<h2 id=preparation> Preperation</h2>\n<p> Import the required librairies </p>"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"import seaborn as sns \nimport matplotlib.pyplot as plt\nimport plotly.express as px\nimport gc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def reduce_mem_usage(df):\n    \"\"\" iterate through all the columns of a dataframe and modify the data type\n        to reduce memory usage.        \n    \"\"\"\n    start_mem = df.memory_usage().sum() / 1024**2\n    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))\n    \n    for col in df.columns:\n        col_type = df[col].dtype\n        \n        if col_type != object:\n            c_min = df[col].min()\n            c_max = df[col].max()\n            if str(col_type)[:3] == 'int':\n                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n                    df[col] = df[col].astype(np.int8)\n                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                    df[col] = df[col].astype(np.int16)\n                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                    df[col] = df[col].astype(np.int32)\n                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                    df[col] = df[col].astype(np.int64)  \n            else:\n                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                    df[col] = df[col].astype(np.float16)\n                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                    df[col] = df[col].astype(np.float32)\n                else:\n                    df[col] = df[col].astype(np.float64)\n        else:\n            df[col] = df[col].astype('category')\n\n    end_mem = df.memory_usage().sum() / 1024**2\n    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))\n    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))\n    \n    return df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 id=\"data\"> Load the datas </h2>"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"train=pd.read_csv('/kaggle/input/riiid-test-answer-prediction/train.csv',dtype={'row_id':'int64',\\\n                                                                               'timestamp':'int64',\\\n                                                                               'user_id':'int32',\\\n                                                                               'content_id':'int16',\\\n                                                                               'content_type_id':'int8',\\\n                                                                               'task_container_id':'int16',\\\n                                                                               'user_answer':'int8',\\\n                                                                               'answered_correctly':'int8',\\\n                                                                               'prior_question_elapsed_time':'float32',\\\n                                                                               'prior_question_had_explanation':'boolean'})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train=train.sort_values(by=['timestamp'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 id=data_preparation> Data Preparation </h2>"},{"metadata":{},"cell_type":"markdown","source":"<p> <font color=greenwhite> <b> We will imput missing values for the variables prior_question_elapsed_time and prior_question_had_explanation."},{"metadata":{"trusted":true},"cell_type":"code","source":"#We know for users first question bundle, prior_question_elapsed_time should be null and prior_question_had_explanation should be False.\ntrain['prior_question_elapsed_time'].fillna(0,inplace=True)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train['prior_question_had_explanation'].fillna(False,inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train=train.sort_values(by=[\"timestamp\"])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 id=\"feature_engineering\"> Feature engineering </h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"def nb_previous_lectures(i):\n    idd=train.loc[i,'user_id']\n    indices=[j  for j in train.index if j<=i]\n    ext=train.loc[indices]\n    dd=ext[(ext['user_id']==idd) & (ext['content_type_id']==1)]\n    nb=dd['content_type_id'].sum()\n    return nb","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 id=exploration> Datas Explorations </h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Number of students on this dataset.\n\nusers=len(train['user_id'].unique())\nprint('There is data of {} students in the training set '.format(users))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# percentil of the question and lecture events in the training dataset.\nevents={0:\"question\",1:\"lecture\"}\nlabels=list(events.values())\nval=[train['content_type_id'].value_counts().loc[0],train['content_type_id'].value_counts().loc[1]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig=px.pie(names=labels,values=val,title=\"events percentile\")\nfig.update_layout(title={'x':0.475,'y':0.9,'xanchor':'center','yanchor':'top'})\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<p> <font color=greenwhite><b> More than 98 % of the events in our training datas are question events. </b></p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# substructe the data concern only the question events.\nqt=train[train['content_type_id']==1]\ntr=train[train['content_type_id']==0]\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_u=tr.groupby(['user_id']).agg({'answered_correctly':'mean'})\ntr_u=reduce_mem_usage(tr_u)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig=px.histogram(tr_u,x='answered_correctly',title='distribution of performance  level of students ',\\\n                 nbins=10,histnorm='probability')\nfig.update_layout(title={'x':0.475,'y':0.9,'xanchor':'center','yanchor':'top'})\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<font color=greenwhite><b> We notice from the chart above that :        \n    - About 50% of students reply correctly to 50% until 70% of their questions.   \n    - About 17% of students reply correctly to 70% until 90% of their questions.   \n    - About 0.3 of students reply correctly to 100% of their questions.    \n==> About 67% of the students reply correctly to more than 50% of their questions.</b>"},{"metadata":{"trusted":true},"cell_type":"code","source":"del(users)\ndel(events)\ndel(labels)\ndel(val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df=pd.pivot_table(tr,index=[\"prior_question_had_explanation\"],\\\n                  values=[\"answered_correctly\"],aggfunc='sum')\ndf['answered_correctly']=(df['answered_correctly']/len(tr))*100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.heatmap(df,annot=True,cbar=False)\nplt.title(\"Pivot table of answered_correctly with prior_question_had_explanation\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<font color=greenwhite><b> 61% of correct answers had carried out by students who had seen prior questions explanation. Moreover, students who had not seen previous questions explanation, sucssed only in 4.9 % of questions.\n    \n    ==> reading previous questions explanations is very helpful task to enhance student performance level. "},{"metadata":{"trusted":true},"cell_type":"code","source":"def quartile_range(vl,q1,q2,q3):\n    \"\"\" This function allow to class the value of the introduced variable into his quartile range.\"\"\"\n    if vl<=q1:\n        return \"Q1\"\n    elif q1<vl<=q2:\n        return \"Q2\"\n    elif q2<vl<=q3:\n        return \"Q3\"\n    else:\n        return \"Q4\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df=tr[[\"answered_correctly\",\"prior_question_elapsed_time\"]]\nq1=df[\"prior_question_elapsed_time\"].quantile(0.25)\nq2=df[\"prior_question_elapsed_time\"].quantile(0.5)\nq3=df[\"prior_question_elapsed_time\"].quantile(0.75)\ndf['prior_question_elapsed_time_quartile']=[quartile_range(vl,q1,q2,q3) \\\n                                            for vl in df['prior_question_elapsed_time']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cnt=df[[\"answered_correctly\",\"prior_question_elapsed_time_quartile\"]].pivot_table(index=\"answered_correctly\",\\\n                                                                             columns=\"prior_question_elapsed_time_quartile\",aggfunc=len)\ntx=df['answered_correctly'].value_counts()\nty=df[\"prior_question_elapsed_time_quartile\"].value_counts()\ntx=pd.DataFrame(tx)\nty=pd.DataFrame(ty)\ntx.columns=['values']\nty.columns=['values']\nn=len(df)\nind=tx.dot(ty.T)/n\nms=((cnt-ind)**2)/ind\ncf=ms.sum().sum()\nsns.heatmap(cnt,annot=True)\nplt.title(\"Pivot table of answered_correctly with prior_question_elapsed_time quartile\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"The estimated correlation between answered_correctly and prior_question_elapsed_time_quartile equal \\\nto :{}\".format(cf))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<font color=greenwhite><b> We notice from the chart above, that the elapsed time for the previous question, affect the ability of student to reply correctly to the question. More the elapsed time fom the prior question is high, less the student has a chance to reply correctly to the question."},{"metadata":{"trusted":true},"cell_type":"code","source":"del(df)\ndel(cnt)\ndel(q1)\ndel(q2)\ndel(q3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lectures=qt.groupby('user_id').agg({\"content_type_id\":['count']})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lectures=lectures.reset_index()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lectures.columns=['user_id','lectures_count']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_time=train.groupby('user_id').agg({'timestamp':['max']})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_time=user_time.reset_index()\nuser_time.columns=['user_id','max_timestamp']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lectures=lectures.merge(user_time,on='user_id',how='left')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lectures[\"time_lecture\"]=lectures[\"max_timestamp\"]/lectures[\"lectures_count\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del(lectures[\"max_timestamp\"])\ndel(lectures[\"lectures_count\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del(train)\ndel(user_time)\ndel(qt)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr=tr.merge(lectures,on='user_id',how='left')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df=tr[['answered_correctly','time_lecture']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"q1=df['time_lecture'].quantile(0.25)\nq2=df['time_lecture'].quantile(0.5)\nq3=df['time_lecture'].quantile(0.75)\ndf['time_lecture_quantile']=[quartile_range(v,q1,q2,q3) for v in df[\"time_lecture\"]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cnt=df[['answered_correctly','time_lecture_quantile']].pivot_table(index=\"answered_correctly\",\\\n                                                                  columns=\"time_lecture_quantile\",aggfunc=len)\n\ntx=df['answered_correctly'].value_counts()\nty=df['time_lecture_quantile'].value_counts()\ntx=pd.DataFrame(tx)\nty=pd.DataFrame(ty)\ntx.columns=['values']\nty.columns=['values']\nn=len(df)\nind=tx.dot(ty.T)/n\nmesure=((cnt-ind)**2)/ind\ncoef=mesure.sum().sum()\nsns.heatmap(cnt,annot=True)\nplt.title(\"correlation betwen correct answer and number of lecture by time of each student\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"The estimated correlation coeficient between answered_correctly and number\\\nof previous lecture of each student equal to :{}\".format(coef))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<font color=greenwhite><b> The green graph above and the estimated correlation mesure between answered_correctly and time_lecture_quantile , confirm the high correlation between them. It means the ability of the student to reply correctly on each question depend to his lecture frequency."}],"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}