{"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)\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        \nimport warnings\nwarnings.filterwarnings(\"ignore\")\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 riiideducation\nimport pandas as pd\n\n# You can only call make_env() once, so don't lose it!\n# env = riiideducation.make_env()\n\n# до сюда не трогать","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/train.csv', low_memory=False,  nrows=1000000,\n                       dtype={'row_id': 'int64', 'timestamp': 'int64', 'user_id': 'int32', 'content_id': 'int16', 'content_type_id': 'int8',\n                              'task_container_id': 'int16', 'user_answer': 'int8', 'answered_correctly': 'int8', 'prior_question_elapsed_time': 'float32', \n                             'prior_question_had_explanation': 'boolean',\n                             }\n                      )\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import math","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# task_container_df = pd.DataFrame()\n# task_container_df['task_container_id'] = train_df_q['task_container_id']\n# task_container_df['answered_correctly'] = train_df_q['answered_correctly']\n# task_container_df = task_container_df.groupby('task_container_id', as_index=False).mean()\n# task_container_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 1) Working with questions"},{"metadata":{"trusted":true},"cell_type":"code","source":"# # compute difficulty\n\n# questions['amount_of_right_answers'] = 0\n# questions['answered'] = 0\n\n# for i in range(len(train_df)):\n#     if train_df.loc[i, 'answered_correctly'] == 1:\n#         a = int(train_df.loc[i, 'content_id'])\n#         questions.loc[a,'amount_of_right_answers'] += 1\n#         questions.loc[a,'answered'] += 1\n#     if train_df.loc[i, 'answered_correctly'] == 0:\n#         a = int(train_df.loc[i, 'content_id'])\n#         questions.loc[a, 'answered'] += 1\n# questions['difficulty'] = questions['amount_of_right_answers'] / questions['answered']\n# # questions['difficulty'] = questions['difficulty'].fillna(0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# deal with questions\n\nquestions = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/questions.csv')\nquestions = questions.drop(['bundle_id',],axis=1)\n\nquestions_ = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/questions.csv')\nquestions_ = questions_.drop(['bundle_id',],axis=1)\n\namount_of_right_answers = pd.DataFrame()\namount_of_right_answers['question_id'] = train_df['content_id']\namount_of_right_answers['amount_of_right_answers'] = train_df['answered_correctly']\n# amount_of_right_answers['prior_question_elapsed_time'] = train_df['prior_question_elapsed_time']\namount_of_right_answers  = amount_of_right_answers[amount_of_right_answers['amount_of_right_answers'] != -1]\namount_of_right_answers = amount_of_right_answers.groupby(['question_id'], as_index=False).sum()\n\ntrain_df_q = train_df[train_df['content_type_id'] == 0]\n\n# time = pd.DataFrame()\n# time['question_id'] = train_df_q['content_id']\n# time['prior_question_elapsed_time']  = train_df_q['prior_question_elapsed_time']\n\ntotal_q = pd.DataFrame()\ntotal_q['answered'] = train_df_q['answered_correctly']\ntotal_q['content_id'] = train_df_q['content_id']\ntotal_q = total_q.groupby('content_id').count()\n\nquestions_['answered'] = total_q['answered']\nquestions_ = questions_.merge(amount_of_right_answers, how='inner', on='question_id')\nquestions_['difficulty'] = questions_['amount_of_right_answers'] / questions_['answered']\nquestions_ = questions_.drop(['correct_answer', 'part', 'tags'], axis=1)\nquestions_df = pd.merge(questions, questions_,how='left', on=['question_id'])\n# questions_df = pd.merge(time, questions_,how='left', on=['question_id'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"questions_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Filling missings"},{"metadata":{"trusted":true},"cell_type":"code","source":"part_stat = questions_df.drop(['question_id'], axis=1).dropna().groupby(['part'], as_index=False).mean()\n\nfor row in range (len(questions_df)):\n    if math.isnan(questions_df.loc[row, 'difficulty']):\n        part = questions_df.loc[row, 'part']\n        part_row = part_stat[part_stat['part'] == part]\n        questions_df.loc[row,'difficulty'] = float(part_row['difficulty'])\n#         questions_df.loc[row,'prior_question_elapsed_time'] = float(part_row['prior_question_elapsed_time'])\n        questions_df.loc[row,'amount_of_right_answers'] = int(part_row['amount_of_right_answers'])\n        questions_df.loc[row, 'answered'] = int(part_row['answered'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"questions_df = questions_df.fillna(0)\nquestions_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# About tags"},{"metadata":{"trusted":true},"cell_type":"code","source":"# we only take 1st tag, because it is reasonably connected with tags from lectures\nfor i in range(len(questions_df)):\n    a = str(questions_df.loc[i,'tags']).split(' ')\n    questions_df.loc[i, 'tag_1'] = a[0] \n\nquestions_df = questions_df.drop('tags', axis=1)\nquestions_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2) Lectures prosessing"},{"metadata":{"trusted":true},"cell_type":"code","source":"# lectures = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/lectures.csv')\n# lectures.groupby(lectures['type_of']).count()\n# watched_l = train_df[train_df['content_type_id'] == 1] # df with only lectures","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# About time"},{"metadata":{"trusted":true},"cell_type":"code","source":"answer_time_df = pd.DataFrame()\ntrain_df_q = train_df[train_df['content_type_id'] == 0]\nanswer_time_df['prior_question_elapsed_time'] = train_df_q['prior_question_elapsed_time']\nanswer_time_df['answered_correctly'] = train_df['answered_correctly']\nanswer_time_df = answer_time_df.dropna()\nmeans = answer_time_df.groupby('answered_correctly').mean()\nprint(means)\nproportion_of_right_answers = len(answer_time_df[answer_time_df['answered_correctly'] == 1]) / len(answer_time_df)\nprint('proportion_of_right_answers in all dataset = ', proportion_of_right_answers)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tail_size = 1000\nanswer_time_df_sorted = answer_time_df.sort_values(by=['prior_question_elapsed_time'])\nhead_stat = answer_time_df_sorted.iloc[:tail_size].groupby('answered_correctly').count() / tail_size\ntail_stat = answer_time_df_sorted.iloc[-tail_size:].groupby('answered_correctly').count() / tail_size\nprint('proportion of right answers in head = ', head_stat['prior_question_elapsed_time'][1])\nprint('proportion of right answers in tail = ', tail_stat ['prior_question_elapsed_time'][1])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3) Creating training dataframe"},{"metadata":{"trusted":true},"cell_type":"code","source":"# # user_df\n# user_df = pd.DataFrame()\n# user_df['user_id'] = train_df['user_id'].unique()\n\n# # question_perfomance\n# for i in range(len(user_df)):\n#     user_q = train_df_q[train_df_q['user_id'] == user_df.loc[i,'user_id']]\n#     user_df.loc[i,'answered_all'] = len(user_q)\n#     user_df.loc[i,'answered_correctly'] = len(user_q[user_q['answered_correctly'] == 1])\n# user_df['perfomance'] = user_df['answered_correctly'] / user_df['answered_all']\n# user_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"user_df = pd.DataFrame()\nuser_df['user_id'] = train_df_q['user_id']\nuser_df['performance'] = train_df_q['answered_correctly']\nuser_df = user_df.groupby('user_id', as_index=False).mean()\nuser_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # We transform all the features from test batch to answer_df, to actually predict\nfrom sklearn.preprocessing import MinMaxScaler, OneHotEncoder\n\n\nmmscaler = MinMaxScaler()\nohe = OneHotEncoder()\n\nmean_perfomance = user_df['performance'].mean()\nmean_difficulty = questions_df['difficulty'].mean()\n\n\ndf = train_df.drop(['timestamp','task_container_id', 'user_answer'], axis=1)\ndf['question_id'] = df['content_id']\ndf = df.merge(user_df, on='user_id')\ndf = df.merge(questions_df[['question_id','difficulty','part']], on='question_id')  \n\ndf['performance'] = df['performance'].fillna(value=mean_perfomance)\ndf['difficulty'] = df['difficulty'].fillna(value=mean_difficulty)     \n    \nfeature_df = pd.DataFrame(df[['answered_correctly','prior_question_elapsed_time', 'performance', 'difficulty', 'part', 'prior_question_had_explanation']])\n\nfeature_df['prior_question_elapsed_time'] = df['prior_question_elapsed_time'].dropna()\nfeature_df['prior_question_elapsed_time'] = mmscaler.fit_transform(feature_df['prior_question_elapsed_time'].to_numpy().reshape(-1, 1))\n\n\n\nohe.fit(feature_df['part'].to_numpy().reshape(-1, 1))\ntransformed = pd.DataFrame(ohe.transform(feature_df['part'].to_numpy().reshape(-1, 1)).toarray().astype('int'), columns = [f'part {x}' for x in range(1, 8)])\nfeature_df = pd.concat([feature_df, transformed], axis=1).drop(['part'], axis=1)\n\n\n    \nfeature_df['performance'] =  feature_df['performance'].fillna(value=mean_perfomance)\nfeature_df['difficulty'] =  feature_df['difficulty'].fillna(value=mean_difficulty)   \nfeature_df['prior_question_elapsed_time'] =  feature_df['prior_question_elapsed_time'].fillna(\n        value=feature_df['prior_question_elapsed_time'].mean())\n\nfeature_df['prior_question_had_explanation'] = df['prior_question_had_explanation'].fillna(False).astype('int')\n\n\n\nfeature_df = feature_df.dropna()\nfeature_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4) Training the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"answer_df_q = feature_df[feature_df['answered_correctly'] != -1]\ny = answer_df_q['answered_correctly']\nX = answer_df_q.drop(['answered_correctly'], axis=1)\n\n\nimport sklearn.linear_model\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.metrics import accuracy_score\n\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# log_reg_clf = sklearn.linear_model.LogisticRegression()\n# log_reg_clf.fit(X_train,y_train)\n# log_reg_pred = log_reg_clf.predict(X_test)\n\n# print(cross_val_score(log_reg_clf, X, y, cv=5))\n# print(roc_auc_score(y_test, log_reg_pred))\n# print(accuracy_score(y_test, log_reg_pred))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from sklearn.ensemble import RandomForestClassifier\n# rf_clf = RandomForestClassifier()\n# rf_clf.fit(X_train,y_train)\n# rf_pred = rf_clf.predict(X_test)\n# print(cross_val_score(rf_clf, X, y, cv=5))\n# print(roc_auc_score(y_test, rf_pred))\n# print(accuracy_score(y_test, rf_pred))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from xgboost import XGBClassifier\nxgb_clf = XGBClassifier()\nxgb_clf.fit(X_train, y_train)\nxgb_pred = xgb_clf.predict(X_test)\nprint(cross_val_score(xgb_clf, X, y, cv=5))\nprint(roc_auc_score(y_test, xgb_pred))\nprint(accuracy_score(y_test, xgb_pred))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import lightgbm as lgb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# params={}\n# params['learning_rate']=0.03\n# params['boosting_type']='gbdt' \n# params['objective']='binary' \n# params['metric']='binary_logloss'\n# params['num_leaves']=31\n# params['tree_learner']='serial'\n# params['max_depth']=10\n\n# lgb_train = lgb.Dataset(X_train, label=y_train)\n# lgb_clf=lgb.train(params,lgb_train,80)\n# lgb_pred=lgb_clf.predict(X_test)\n# lgb_pred=lgb_pred.round(0)\n# lgb_pred=lgb_pred.astype(int)\n# print(accuracy_score(y_test, lgb_pred))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def batch_processing(test_df, model, alpha):\n    df = test_df.drop(['timestamp','task_container_id'], axis=1)\n    df['question_id'] = df['content_id']\n    df = df.merge(user_df, on='user_id', how='left')\n    df = df.merge(questions_df[['question_id','difficulty','part']], on='question_id', how='left')  \n\n    df['performance'] = df['performance'].fillna(value=mean_perfomance)\n    df['difficulty'] = df['difficulty'].fillna(value=mean_difficulty)     \n\n    feature_df = pd.DataFrame(df[['prior_question_elapsed_time', 'performance', 'difficulty', 'part', 'prior_question_had_explanation']])\n\n\n    feature_df['prior_question_elapsed_time'] = df['prior_question_elapsed_time'].dropna()\n    feature_df['prior_question_elapsed_time'] = mmscaler.fit_transform(feature_df['prior_question_elapsed_time'].to_numpy().reshape(-1, 1))\n\n    ohe.fit(feature_df['part'].to_numpy().reshape(-1, 1))\n    transformed = ohe.transform(feature_df['part'].to_numpy().reshape(-1, 1)).toarray().astype('int') \n    enc = pd.DataFrame(0, index=np.arange(len(feature_df)), columns=[f'part {x}' for x in range(1,8)])\n    for i in range(len(transformed.T)):\n        enc[f'part {i+1}'] = transformed.T[i]\n    \n    \n    feature_df = pd.concat([feature_df, enc], axis=1).drop(['part'], axis=1)\n\n\n\n    feature_df['performance'] =  feature_df['performance'].fillna(value=mean_perfomance)\n    feature_df['difficulty'] =  feature_df['difficulty'].fillna(value=mean_difficulty)   \n\n\n    feature_df['prior_question_elapsed_time'] =  feature_df['prior_question_elapsed_time'].fillna(\n            value=feature_df['prior_question_elapsed_time'].mean())\n\n    feature_df['prior_question_had_explanation'] = df['prior_question_had_explanation'].fillna(False).astype('int')\n    # feature_df = feature_df.drop(['content_id', 'answered_correctly'], axis=1)\n\n    print(f'With model: {str(model)} and alpha = {alpha}')\n    A = model.predict(feature_df)\n    submit = pd.DataFrame(test_df['row_id'])\n\n    submit['answered_correctly'] = A\n    submit['answered_correctly'] = submit['answered_correctly'].apply(lambda x: 1 if x >= alpha else 0)\n    submit['group_num'] = test_df.index\n\n    print('All_submitted')\n    return submit","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"env = riiideducation.make_env()\n\niter_test = env.iter_test()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# models = [log_reg_clf, rf_clf, xgb_clf, lgb_clf]\n\nfor (test_df, sample_prediction_df) in iter_test:\n    env.predict(batch_processing(test_df,  xgb_clf, 0.75))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_processing(test_df,  xgb_clf, 0.75)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.index","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}