{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport gc\nimport random\nfrom tqdm import tqdm\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.model_selection import train_test_split\n\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.utils.rnn as rnn_utils\nfrom torch.autograd import Variable\nfrom torch.utils.data import Dataset, DataLoader\nimport pickle","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load data"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nwith open('../input/rid-group-w-lag-time/group_w_lag_time.p','rb') as f:\n    group=pickle.load(f)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!cp ../input/rid-test110/Network.py .\nfrom Network import *\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n# device = torch.device(\"cpu\")\n\nn_skill=13523\nMAX_SEQ=129\n\nmodels=[]\nlayers=[6]\nfor i, nlayer in enumerate(layers):\n    if nlayer is not None:\n        model = SAKTModel(n_skill, max_seq=MAX_SEQ, embed_dim=256, nlayers=nlayer).to(device)\n        model = nn.DataParallel(model)\n\n        model.load_state_dict(torch.load(f\"../input/rid-test110-loss-weight/model1.pth\"))\n\n        model.eval()\n        models.append(model)\n        \nfor i, nlayer in enumerate(layers):\n    if nlayer is not None:\n        model = SAKTModel(n_skill, max_seq=MAX_SEQ, embed_dim=384, nlayers=nlayer, nheads=12).to(device)\n        model = nn.DataParallel(model)\n\n        model.load_state_dict(torch.load(f\"../input/rid-test110-loss-weight-12head/model1.pth\"))\n\n        model.eval()\n        models.append(model)        \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for user in group.index:\n    group[user]=group[user][:6]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"question_cluster=pd.read_csv('../input/rid-tag-community/question_cmnts.csv')\n\nquestion_df=pd.read_csv('../input/riiid-test-answer-prediction/questions.csv')\npossible_tags=[]\nfor i, tags in enumerate(question_df.tags):\n    try:\n        tags=tags.split()\n        for tag in tags:\n            tag=int(tag)\n            if tag not in possible_tags:\n                possible_tags.append(tag)\n    except:\n        pass\n\ntag_encoding=np.zeros((len(question_df),len(possible_tags)))\nfor i, tags in enumerate(question_df.tags):\n    try:\n        tags=tags.split()\n        for tag in tags:\n            tag=int(tag)\n            tag_encoding[i,tag]=1\n    except:\n\n        #exit()\n        #print(i)\n        pass#exit()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"## Test"},{"metadata":{"trusted":true},"cell_type":"code","source":"def task_mask(tasks):\n    seq_length=len(tasks)\n    future_mask = np.triu(np.ones((seq_length, seq_length)), k=1).astype('bool')\n    container_mask= np.ones((seq_length, seq_length))\n    container_mask=(container_mask*tasks.reshape(1,-1))==(container_mask*tasks.reshape(-1,1))\n    #comparison_mask=np.ones((seq_length, seq_length))*tasks.reshape(-1,1)\n    #mask=future_mask(task)\n    future_mask=future_mask+container_mask\n    np.fill_diagonal(future_mask,0)\n    return future_mask\n\n\nclass TestDataset(Dataset):\n    def __init__(self, samples, test_df, question_cluster=question_cluster, tag_encoding=tag_encoding, max_seq=MAX_SEQ):\n        super(TestDataset, self).__init__()\n        self.samples = samples\n        self.user_ids = [x for x in test_df[\"user_id\"].unique()]\n        self.test_df = test_df\n        self.n_skill = 13523\n        self.max_seq = max_seq\n        self.question_cluster=np.append(question_cluster.community.values,[5])\n        self.tag_encoding=np.concatenate([tag_encoding,np.zeros((1,188))],0)\n        \n    def __len__(self):\n        return self.test_df.shape[0]\n\n    def __getitem__(self, index):\n        test_info = self.test_df.iloc[index]\n    \n        user_id = test_info[\"user_id\"]\n        target_id = test_info[\"content_id\"]\n        elapsed_time=test_info[\"prior_question_elapsed_time\"]\n        explanation=test_info[\"prior_question_had_explanation\"]\n        time_stamp=test_info[\"timestamp\"]\n        task_container=test_info[\"task_container_id\"]\n        #et_ = test_info[\"prior_question_elapsed_time\"]\n        \n        \n        q = np.zeros(self.max_seq, dtype=int)\n        q[:]=13523\n        qa = np.zeros(self.max_seq, dtype=int)\n        et = np.zeros(self.max_seq, dtype=int)\n        pq = np.zeros(self.max_seq, dtype=int)\n        ts = np.zeros(self.max_seq, dtype=int)\n        tasks = np.zeros(self.max_seq, dtype=int)\n        \n        if user_id in self.samples.index:\n            q_, qa_, et_, pq_, ts_, tasks_ = self.samples[user_id]\n            \n            seq_len = len(q_)\n\n            if seq_len >= self.max_seq:\n                q = q_[-self.max_seq:]\n                qa = qa_[-self.max_seq:]\n                et = et_[-self.max_seq:]\n                pq = pq_[-self.max_seq:]\n                ts = ts_[-self.max_seq:]\n                tasks = tasks_[-self.max_seq:]\n                \n            else:\n                q[-seq_len:] = q_\n                qa[-seq_len:] = qa_\n                et[-seq_len:] = et_\n                pq[-seq_len:] = pq_\n                ts[-seq_len:] = ts_\n                tasks[-seq_len:] = tasks_\n        \n        x = q[1:].copy()\n        xa = qa[1:].copy()\n        #x += (qa[1:] == 1) * self.n_skill\n        \n        questions = np.append(q[2:], [target_id])\n        pq = np.append(pq[2:], [explanation])\n        et = np.append(et[2:], [elapsed_time])//1000\n        ts = (np.append(ts[2:], [time_stamp])-ts[1:])/1000\n        tasks= np.append(tasks[1:], [task_container])\n        \n        for i in range(len(ts)-1):\n            if tasks[i+1]==tasks[i+2]:\n                ts[i+1]=ts[i]\n                #xa[i+1]=xa[i]\n        #print(tasks[1:])\n        #print(ts)\n        et = np.clip(et,0,300)\n        #et = np.clip(et,0,300)\n        #print(f\"###last elapsed time: {et[-1]}###\")\n        mask=(questions==13523)\n        mask[0]=False\n        cluster=self.question_cluster[questions]\n        tags=self.tag_encoding[questions]\n        \n        #attention_mask=task_mask(tasks[1:])\n        attention_mask=0\n        #attention_mask[:,0]=False\n        \n        return questions, xa, et, pq, ts, attention_mask, mask, cluster, tags","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import riiideducation\n\nenv = riiideducation.make_env()\niter_test = env.iter_test()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import psutil\n\n\n\nprev_test_df = None\n\nfor (test_df, sample_prediction_df) in tqdm(iter_test):\n    #HDKIM\n    if (prev_test_df is not None) & (psutil.virtual_memory().percent<90):\n        print(psutil.virtual_memory().percent)\n        prev_test_df['answered_correctly'] = eval(test_df['prior_group_answers_correct'].iloc[0])\n        prev_test_df['prior_question_elapsed_time']=prev_test_df['prior_question_elapsed_time'].fillna(0)\n        prev_test_df['prior_question_elapsed_time']=prev_test_df['prior_question_elapsed_time'].values        \n        #prev_test_df['prior_question_had_explanation']=prev_test_df['prior_question_had_explanation'].fillna(False).astype('int')\n        prev_test_df = prev_test_df[prev_test_df.content_type_id == False]\n        prev_group = prev_test_df[['user_id', 'content_id', 'answered_correctly','prior_question_elapsed_time','prior_question_had_explanation','timestamp','task_container_id']].groupby('user_id').apply(lambda r: (\n            r['content_id'].values,\n            r['answered_correctly'].values,\n            r['prior_question_elapsed_time'].values,\n            r['prior_question_had_explanation'].values,\n            r['timestamp'].values,\n            r['task_container_id'].values))\n        for prev_user_id in prev_group.index:\n            prev_group_content = prev_group[prev_user_id][0]\n            prev_group_ac = prev_group[prev_user_id][1]\n            prev_group_et = prev_group[prev_user_id][2]\n            prev_group_pq = prev_group[prev_user_id][3]\n            prev_group_ts = prev_group[prev_user_id][4]\n            prev_group_tc = prev_group[prev_user_id][5]\n            if prev_user_id in group.index:\n                group[prev_user_id] = (np.append(group[prev_user_id][0],prev_group_content), \n                                       np.append(group[prev_user_id][1],prev_group_ac),\n                                       np.append(group[prev_user_id][2],prev_group_et),\n                                       np.append(group[prev_user_id][3],prev_group_pq),\n                                       np.append(group[prev_user_id][4],prev_group_ts),\n                                       np.append(group[prev_user_id][5],prev_group_tc))\n \n            else:\n                group[prev_user_id] = (prev_group_content,prev_group_ac,prev_group_et,prev_group_pq,prev_group_ts,prev_group_tc)\n            if len(group[prev_user_id][0])>MAX_SEQ:\n                new_group_content = group[prev_user_id][0][-MAX_SEQ:]\n                new_group_ac = group[prev_user_id][1][-MAX_SEQ:]\n                new_group_et = group[prev_user_id][2][-MAX_SEQ:]\n                new_group_pq = group[prev_user_id][3][-MAX_SEQ:]\n                new_group_ts = group[prev_user_id][4][-MAX_SEQ:]\n                new_group_tc = group[prev_user_id][5][-MAX_SEQ:]\n                group[prev_user_id] = (new_group_content,new_group_ac,new_group_et,new_group_pq,new_group_ts,new_group_tc)\n\n    vec=test_df['prior_question_had_explanation'].to_numpy()\n    for i, entry in enumerate(vec):\n        try:\n            if entry != 0:\n                pass\n        except:\n            vec[i]=2\n\n    vec=vec.astype(int)\n    test_df['prior_question_had_explanation']=test_df['prior_question_had_explanation'].fillna(True).astype(int)\n    test_df['prior_question_had_explanation']=vec                \n                \n                \n    prev_test_df = test_df.copy()\n    \n    test_df = test_df[test_df.content_type_id == False]\n\n    test_dataset = TestDataset(group, test_df)\n    test_dataloader = DataLoader(test_dataset, batch_size=51200, shuffle=False)\n    \n    outs = []\n\n    for item in tqdm(test_dataloader):\n        target_id = item[0].to(device).long()\n        xa = item[1].to(device).long()\n        et = item[2].to(device).float()\n        et = torch.clamp(et,0,300)\n        et[et!=et] = 0\n\n        #et = item[3].to(device).float()\n        #x=torch.nan_to_num(x,nan=0)\n        #print(et)\n        #print(et)\n        pq = item[3].to(device).long()\n        ts = item[4].to(device).float()\n        ts = torch.clamp(ts,0,1440)\n        ts[ts!=ts] = 0\n        attn_mask = item[5].to(device).bool()\n        mask=item[6].to(device).bool()\n        cluster=item[7].to(device).long()\n        tags=item[8].to(device).float()\n        \n        outputs=[]\n        with torch.no_grad():\n            for model in models:\n                #print(target_id.shape)\n                output = model(target_id, xa, et, ts, pq, None, mask, cluster, tags)\n                outputs.append(output)\n        \n        output=torch.sigmoid(torch.stack(outputs,0)).mean(0)\n        \n        output = output[:, -1]\n        #print(output.shape)\n        # pred = (output >= 0.5).long()\n        # loss = criterion(output, label)\n\n        # val_loss.append(loss.item())\n        # num_corrects += (pred == label).sum().item()\n        # num_total += len(label)\n\n        # labels.extend(label.squeeze(-1).data.cpu().numpy())\n        outs.extend(output.view(-1).data.cpu().numpy())\n        \n    test_df['answered_correctly'] =  outs\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}