{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Light GBM の基礎\n## 今回の目的 : とりあえず、Light GBMを流して、submitまでしてみる\n## 流している間に、Light GBMとは何なのかを解説"},{"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 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":{},"cell_type":"markdown","source":"# 1. input dataの追加\n## https://www.kaggle.com/rohanrao/riiid-train-data-multiple-formats を追加する"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"%%time\ntraindf = pd.read_pickle(\"../input/riiid-train-data-multiple-formats/riiid_train.pkl.gzip\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## pd.read_csvでは、約5分以上読み込みかかるが、pklだと、1分未満で読み込み可能\n## ※ GPU使用したcudfだと、17 sec程度"},{"metadata":{"trusted":true},"cell_type":"code","source":"traindf","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 約1億行のデータ。使う行だけにスリミングする"},{"metadata":{"trusted":true},"cell_type":"code","source":"traindf = traindf[[\"user_id\",\"content_id\",\"task_container_id\",\"answered_correctly\",\"prior_question_had_explanation\"]]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 講義を除去"},{"metadata":{"trusted":true},"cell_type":"code","source":"traindf = traindf[traindf[\"answered_correctly\"]!=-1] # inferenceではcontent_type_id　== 0を使用。メモリ削減と計算量削減のため、こちらではこうやっている","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"traindf","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. trainデータとvalidationデータの生成。\n### 今回はユーザーごとに、24個問題と回答結果を抽出。\n### うち18個をtrainデータ。6個をvalidationデータとする"},{"metadata":{"trusted":true},"cell_type":"code","source":"usergroup = traindf.groupby(\"user_id\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = usergroup.tail(24)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train[train[\"user_id\"]==115]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## メモリ確保のために1億行データを削除"},{"metadata":{"trusted":true},"cell_type":"code","source":"del traindf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# メモリ解放\nimport gc\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# prior_question_had_explanationのnanデータ置換"},{"metadata":{"trusted":true},"cell_type":"code","source":"train[\"prior_question_had_explanation\"] = train[\"prior_question_had_explanation\"].fillna(False).astype(\"bool\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## trainデータ24個から後ろ6個をvalidationにして抽出して、そのindexを除去することにより、train 18個、validation 6個とする"},{"metadata":{"trusted":true},"cell_type":"code","source":"usergroup2 = train.groupby(\"user_id\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val = usergroup2.tail(6)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = train.drop(val.index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 念のため、reset index"},{"metadata":{"trusted":true},"cell_type":"code","source":"train = train.reset_index(drop=True)\nval = val.reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. Modeling"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 学習させるcolumnをFEATURES, ラベルをTARGET"},{"metadata":{"trusted":true},"cell_type":"code","source":"FEATURES = [\"content_id\",\"task_container_id\",\"prior_question_had_explanation\"]\nTARGET = \"answered_correctly\"","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":"train[FEATURES]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3.1 データセット"},{"metadata":{"trusted":true},"cell_type":"code","source":"# データセットを生成する\nlgb_train = lgb.Dataset(train[FEATURES], train[TARGET])\nlgb_eval = lgb.Dataset(val[FEATURES], val[TARGET])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3.2 パラメータ設定"},{"metadata":{"trusted":true},"cell_type":"code","source":"# LightGBM のハイパーパラメータbasic\nlgbm_params = {\n    # 二値分類問題\n    'objective': 'binary',\n    # AUC の最大化を目指す\n    'metric': 'auc',\n    # Fatal の場合出力\n    'verbosity': -1,\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# 他のnotebookから持ってきたパラメータ\nlgbm_params2 = {\n    'objective': 'binary',\n    'seed': 42,\n    'metric': 'auc',\n    'learning_rate': 0.05,\n    'max_bin': 800,\n    'num_leaves': 80\n}","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4.学習 -この間に解説-"},{"metadata":{"trusted":true},"cell_type":"code","source":"# 上記のパラメータでモデルを学習する\nmodel = lgb.train(lgbm_params2, lgb_train, valid_sets=lgb_eval,\n                  verbose_eval=50,  # 50イテレーション毎に学習結果出力\n                  num_boost_round=1000,  # 最大イテレーション回数指定\n                  early_stopping_rounds=100\n                 )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# 使うかもしれないので、modelの保存方法とロード方法\n\nimport pickle\n\nmodel_name = \"LGBMmodel.bin\"\n\n# モデルの保存\npickle.dump(model, open(model_name, 'wb'))\n\n# モデルのロード方法\nestimator = pickle.load(open(model_name, 'rb'))\n\n# そうすると、estimatorが↑でいうmodelの代わりとして使える。","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## feature importanceの表示"},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.save_model(f'model.txt')\nlgb.plot_importance(model, importance_type='gain')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### 以下は参考"},{"metadata":{"trusted":true},"cell_type":"code","source":"# テストデータを予測する\ny_pred = model.predict(val[FEATURES], num_iteration=model.best_iteration)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# AUC (Area Under the Curve) を計算する\nfrom sklearn import metrics\nfpr, tpr, thresholds = metrics.roc_curve(val[TARGET], y_pred)\nauc = metrics.auc(fpr, tpr)\nprint(auc)\n\n# ROC曲線をプロット\nplt.plot(fpr, tpr, label='ROC curve (area = %.2f)'%auc)\nplt.legend()\nplt.title('ROC curve')\nplt.xlabel('False Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.grid(True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. inference"},{"metadata":{"trusted":true},"cell_type":"code","source":"# testdataで練習","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_test = pd.read_csv(\"../input/riiid-test-answer-prediction/example_test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_test = ex_test[ex_test[\"content_type_id\"]==0] #講義のみにする\nex_test[\"prior_question_had_explanation\"] = ex_test[\"prior_question_had_explanation\"].fillna(False).astype(\"bool\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_train = ex_test[FEATURES]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_train","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## ここで予測"},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_train[\"answered_correctly\"] = model.predict(ex_train,model.best_iteration)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# submitでrow_idが入るので、row_idを大本データから挿入\nex_train[\"row_id\"] = ex_test[\"row_id\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ex_train","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## submit fileの形式にする"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = ex_train[['row_id', 'answered_correctly']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## ここまでの流れを関数化しておくと楽"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predictdf(ex_test):\n    ex_test = ex_test[ex_test[\"content_type_id\"]==0] #講義のみにする\n    ex_test[\"prior_question_had_explanation\"] = ex_test[\"prior_question_had_explanation\"].fillna(False).astype(\"bool\")\n    ex_train = ex_test[FEATURES]\n    ex_train[\"answered_correctly\"] = model.predict(ex_train,model.best_iteration)\n    ex_train[\"row_id\"] = ex_test[\"row_id\"]\n    submission = ex_train[['row_id', 'answered_correctly']]\n  \n    return submission\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictdf(ex_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 6. submit"},{"metadata":{},"cell_type":"markdown","source":"## お決まりのやり方と思ってもらえれば良い。"},{"metadata":{"trusted":true},"cell_type":"code","source":"import riiideducation\nenv = riiideducation.make_env()\niter_test = env.iter_test()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for (test_df, sample_prediction_df) in iter_test:\n    \n    \n    submission = predictdf(test_df)\n    submission[\"answered_correctly\"] = submission[\"answered_correctly\"].fillna(0.707)\n    \n    env.predict(submission)","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}