{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"from fastai.tabular.all import *\n\nimport gc\n\nimport riiideducation","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def get_task_chars(data):\n    mean_task_exp = train_df[['task_container_id','prior_question_had_explanation']].groupby('task_container_id').agg('mean').astype('float16')\n    mean_task_exp.columns = ['mean_task_exp']\n\n    task_diff = 1 - train_df[['task_container_id','answered_correctly']].groupby('task_container_id').agg('mean')\n    task_diff.columns = ['task_diff_inv']\n\n    task_chars = task_diff.join(mean_task_exp)\n    \n    return task_chars\n\n\n\ndef get_user_chars(data):\n    # User data\n    user_prof = data[['user_id','answered_correctly']].groupby('user_id').agg({'mean'}).droplevel(level=0,axis=1)\n    user_prof.columns = ['user_prof']\n    user_prof['user_prof_inv'] = 1-user_prof.user_prof\n    user_prof = user_prof.astype({'user_prof':'float32','user_prof_inv':'float32'})\n\n    df0 = data.loc[data['prior_question_had_explanation']==0,['answered_correctly','user_id']].groupby(['user_id']).agg('count')\n    df1 = data.loc[data['prior_question_had_explanation']==1,['answered_correctly','user_id']].groupby(['user_id']).agg('count')\n\n    mean_user_p_e = df1/(df0+df1)\n    mean_user_p_e.columns = ['mean_user_p_e']\n    mean_user_p_e.fillna(mean_user_p_e.mean(),inplace=True)\n\n    user_chars = user_prof.join(mean_user_p_e)\n\n    # User data per part\n    user_part_chars = data[['user_id','answered_correctly','part']].groupby(['user_id','part']).agg('mean')\n    user_part_chars.columns = ['user_part_prof']\n    user_part_chars['user_part_prof_inv'] = 1- user_part_chars.user_part_prof\n    user_part_chars.reset_index(inplace=True)\n\n    part_diff = data[['answered_correctly','part']].groupby('part').agg({'answered_correctly': 'mean'})\n    part_diff.columns = ['part_diff']\n    part_diff['part_diff_inv'] = 1- part_diff.part_diff\n\n    user_part_chars = user_part_chars.merge(part_diff,on='part',right_index=True,how='left')\n    \n    user_chars = user_chars.merge(user_part_chars,left_index=True,right_on='user_id',how='left')\n    \n    return user_chars\n\n\n\ndef load_model():\n    return load_learner('../input/riiid-model/fastai_nn_v6_15_epochs_wd')\n\n\nclass user:\n    def __init__(self):\n        self.questions_answered = 0\n        self.answered_correctly = 0\n        self.user_prof = 0.\n        self.user_prof_inv = 1.\n        \n        self.user_comm_prof = 0.\n        self.user_comm_prof_inv = 0.\n        \n        self.questions_per_part = dict((x,0) for x in range(8))\n        self.correct_per_part = dict((x,0) for x in range(8))\n        self.user_part_prof = dict((x,0.) for x in range(8))\n        self.user_part_prof_inv = dict((x,0.) for x in range(8))\n\n        self.had_explanation = 0\n        self.no_explanation = 0\n        self.mean_user_p_e = 0.\n\n        \n    def train_update(self, data):\n        self.questions_answered = self.questions_answered + 1\n        self.questions_per_part[data['part']] = self.questions_per_part[data['part']] + 1\n\n        if data['answered_correctly']==1:\n            self.answered_correctly = self.answered_correctly + 1\n            self.correct_per_part[data['part']] = self.correct_per_part[data['part']] + 1\n\n        if data['prior_question_had_explanation']==1:\n            self.had_explanation = self.had_explanation + 1\n        else:\n            self.no_explanation = self.no_explanation + 1\n\n    def test_update(self, data):\n        self.questions_answered = self.questions_answered + 1\n        self.questions_per_part[data['part']] = self.questions_per_part[data['part']] + 1\n\n        if data['prior_question_had_explanation']==1:\n            self.had_explanation = self.had_explanation + 1\n        else:\n            self.no_explanation = self.no_explanation + 1        \n    \n    def update_answers(self,data):\n        self.answered_correctly = self.answered_correctly + 1\n        self.correct_per_part[data['part']] = self.correct_per_part[data['part']] + 1\n        self.do_the_monster_math()\n        \n    def do_the_monster_math(self):\n        self.user_prof = self.answered_correctly / self.questions_answered\n        self.user_prof_inv = 1 - self.user_prof\n        \n        for part in self.questions_per_part:\n            if self.questions_per_part[part]==0:\n                continue\n            self.user_part_prof[part] = self.correct_per_part[part] / self.questions_per_part[part]\n            self.user_part_prof_inv[part] = 1 - self.user_part_prof[part]\n        \n        self.mean_user_p_e = self.had_explanation / (self.had_explanation + self.no_explanation)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# %%time\nquestions_df = pd.read_csv('../input/riiid-test-answer-prediction/questions.csv',\n                          usecols=['question_id','part'],\n                          dtype={'question_id':'int32','part':'int8'})\n\nwith open('../input/riiid-model/final.pickle', 'rb') as handle:\n    train_dict = pickle.load(handle)\n\ntry:\n    model = load_model()\nexcept Exception as e:\n    print('model:  ',e)\n\nenv = riiideducation.make_env()\niter_test = env.iter_test()\nfirst_pass = True\n\nfor (test_df, sample_prediction_df) in iter_test:\n    test_df = test_df.merge(questions_df,left_on='content_id',right_on='question_id',how='left').drop('question_id',axis=1)\n    test_df.loc[:,'prior_question_had_explanation'].fillna(False,inplace=True)\n    \n    # Add Features\n    if first_pass == False:\n        try:\n            old_df['answered_correctly'] = eval(test_df.iat[0,-3])\n            for _,row in old_df.iterrows():\n                if row['content_type_id']==0:\n                    if row['answered_correctly']==1:\n                        train_dict[row['user_id']].update_answers(row)\n                    else:\n                        train_dict[row['user_id']].do_the_monster_math()\n        except Exception as e:\n            print('first: ',e)\n\n            \n    old_df = test_df[['row_id','user_id','part','content_type_id']]\n    \n    cols = ['user_part_prof','user_part_prof_inv','user_prof','user_prof_inv','mean_user_p_e','num_qs_ans']\n    test_df.loc[:,cols] = np.nan\n    test_df[cols] = test_df[cols].astype('float16')\n    \n    for index,row in test_df.iterrows():\n        try:\n            if row['user_id'] not in train_dict:\n                train_dict[row['user_id']] = user()\n            if row['content_type_id']==0:\n                train_dict[row['user_id']].test_update(row)\n            test_df.iloc[index,-6:] = [train_dict[row['user_id']].user_part_prof[row['part']],\n                                       train_dict[row['user_id']].user_part_prof_inv[row['part']],\n                                       train_dict[row['user_id']].user_prof,\n                                       train_dict[row['user_id']].user_prof_inv,\n                                       train_dict[row['user_id']].mean_user_p_e,\n                                       train_dict[row['user_id']].questions_answered]\n\n        except Exception as e:\n            print('last: ',e)\n            pass\n    \n    first_pass = False\n    \n    # Predictions\n    dl = model.dls.test_dl(test_df[['user_id','content_id','user_part_prof','user_part_prof_inv','user_prof','user_prof_inv','mean_user_p_e','num_qs_ans']])\n    preds,_ = model.get_preds(dl=dl)\n    test_df['answered_correctly'] = list(map(np.float64, preds.argmax(axis=1)))\n\n    env.predict(test_df.loc[test_df['content_type_id']==0,['row_id', 'answered_correctly']])","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}