{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Notebookについて\nこのNotebookではRiiid! Answer Correctness Predictionのコンペ説明と簡単なEDAからriideducationモジュールを使った最初のSubmitまで行うためのものです。<br/>\nこのNotebookからスタートして自分のNotebookを作っていくと捗るかも?"},{"metadata":{},"cell_type":"markdown","source":"# Descroption\nあなたの好きな先生を思い出してみてください。彼らはあなたに学ぶためのやる気とインスピレーションを与えてくれました。彼らはあなたの長所と短所を知っていたので、あなたの能力に基づいて授業が行わることがあったでしょう。例えば、微積分に進む前に代数を理解しているかどうかを確認します。しかし、多くの生徒へ個人に合わせた学習にまでは着手できていません。データが溢れている世の中では、あなたのようなデータサイエンティストが支援することができます。機械学習は世界中の若者に成功への道を提供することができ、あなたをこのミッションへ招待します。\n\n2018年、2億6000万人の子どもたちが学校に通っていませんでした。同時に、これらの若い生徒の半数以上が、最低限の読解力と数学の基準を満たしていませんでした。COVID-19によってほとんどの国が一時的に学校を閉鎖せざるを得なくなったとき、教育はすでに厳しい状況に置かれていました。これにより、学習の機会と知的発達がさらに遅れることになりました。すべての国でより格差が拡大する可能性があります。私たちは、出席、エンゲージメント、個別への注目するという観点から、現在の教育システムを再考する必要があります。\n\n教育市場に創造的な破壊を提供するAIソリューションプロバイダーであるRiiid Labsは、世界の教育関係者にAIを活用した従来の学習方法を再考させる方法を与えています。教育の機会均等を強く信じているRiiidは、2017年にディープラーニングアルゴリズムに基づいたAIチューターを発売し、100万人以上の韓国の学生を魅了した。今年は、1億人以上の生徒のインタラクションを収録した世界最大のAI教育用オープンデータベース「EdNet」をリリースしました。\n\n今回のコンペでは、学生の知識を経時的にモデル化する「知識トレース」のアルゴリズムを作成することが課題となっています。目標は、将来のインタラクションで学生がどのようなパフォーマンスを発揮するかを正確に予測することです。Riiid の EdNet データを使用して機械学習のスキルを組み合わせます。\n\nあなたの革新的なアルゴリズムは、教育におけるグローバルな課題に取り組むのに役立つでしょう。成功すれば、インターネットに接続している学生であれば、どこに住んでいるかに関係なく、パーソナライズされた学習体験の恩恵を享受することが可能になります。あなたの参加により、私たちは、COVID-19後の世界における教育のためのより良くより公平なモデルを構築することができます。\n\n# Evaluation\n提出物は、予測された確率と観察されたターゲットの間のAUC(ROC曲線の下の領域)で評価されます。\n\nAUCについて簡単な説明すると、偽陽性がなるべく少なくかつ真陽性がなるべく多くなると良い評価となる指標です。\n\n\n## 参考\n- [AUCについて](https://www.medcalc.org/manual/roc-curves.php#:~:text=The%20area%20under%20the%20ROC,groups%20(diseased%2Fnormal).)\n- [【ROC曲線とAUC】機械学習の評価指標についての基礎講座](https://www.randpy.tokyo/entry/roc_auc)\n- [機械学習の評価指標 – ROC曲線とAUC](https://techblog.gmo-ap.jp/2018/12/14/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E8%A9%95%E4%BE%A1%E6%8C%87%E6%A8%99-roc%E6%9B%B2%E7%B7%9A%E3%81%A8auc/)\n\n\n## Submission File\nこれはカーネルコンペでKaggleのカーネルを使ってサブミットする必要があります。\n\n\n\n# Notebook制限\n- CPU Notebook <= 9 hours run-time\n- GPU Notebook <= 9 hours run-time\n- TPU Notebook <= 3 hours run-time\n\n# Rules\n- チーム外でのコード、データの共有はできません\n- チーム人数は最大5名までです\n- 1日あたり5回のサブミットが可能です\n- 最終提出物としては最大2つまで選択可能です","attachments":{}},{"metadata":{},"cell_type":"markdown","source":"# Introduction\nこのコンペでは、各生徒がどの問題を正解できるかを予測します。<br/>\n\nコンペの特徴\n- Kaggle Notebooksからのみサブミットできます\n- riiideducationというカスタムのPythonモジュールを使用する必要があります。このモジュールの目的は、情報の流れを制御して、将来のデータを使用して予測を行わないようにするためのものです。このモジュールを適切に使用しないと、コードが失敗する可能性があります。\n"},{"metadata":{},"cell_type":"markdown","source":"# Library"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport sys\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib as plt\nimport seaborn as sns\n\nimport riiideducation\nenv = riiideducation.make_env()\n\nimport warnings\nwarnings.simplefilter(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load Data"},{"metadata":{},"cell_type":"markdown","source":"train.csvがあまりに大きいため普通に読み込むとメモリに収まりません。<br/>\n以下のNotebookを参考にデータを読み込みました。\n\n[Tutorial on reading large datasets](https://www.kaggle.com/rohanrao/tutorial-on-reading-large-datasets)\n\npandasでデータを読み込む際型推測に多くのリソースを割くため事前に型を定義しておくとその分のリソースを節約できます。"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/train.csv', low_memory=False, nrows=10**5, \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 = train_df.query('answered_correctly != -1').reset_index(drop=True)\ntrain_df['prior_question_had_explanation'] = train_df['prior_question_had_explanation'].astype(float)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# %%time\nexample_test_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/example_test.csv')\nlectures_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/lectures.csv')\nquestions_df = pd.read_csv('/kaggle/input/riiid-test-answer-prediction/questions.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import display\ndisplay(example_test_df.head())\ndisplay(lectures_df.head())\ndisplay(questions_df.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import display\ndisplay(example_test_df.info())\ndisplay(lectures_df.info())\ndisplay(questions_df.info())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# iter_test関数\nテストセット内の質問の各バッチをループするジェネレータ。便宜上、サンプルのテスト行に直接アクセスできますが、コードはAPIを介して実際のテストセットからのみ行を取得できます。予測を呼び出すと、次のバッチに進むことができます。\n\n\nYields:\n- より多くのバッチがあり、predictは最後のyield以降正常に呼び出されましたが、次のタプルが生成されます。\n    - test_df: 次のバッチのテスト機能と前のバッチのユーザー応答を含むDataFrame。\n    - sample_prediction_df: 予測例を含むDataFrame。記入して予測関数に戻すことを目的としています。\n- 前回のyield以降、predictが正常に呼び出されなかった場合、エラーが出力され、Noneが生成されます。"},{"metadata":{"trusted":true},"cell_type":"code","source":"iter_test = env.iter_test()\n(test_df, sample_prediction_df) = next(iter_test)\ntest_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_prediction_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"現在のバッチの予測を行わずに次のバッチに続行しようとすると、以下のようなエラーが発生することに注意してください。"},{"metadata":{"trusted":true},"cell_type":"code","source":"next(iter_test)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# predict関数\n現在のバッチの予測を保存します。 iter_testジェネレーターから返されるsample_prediction_dfで見たものと同じ形式を期待します。\n\n引数:\n- predictions_df：sample_prediction_dfと同じ形式である必要があるDataFrame。\n\niter_testジェネレーターの反復が成功した後に呼び出されない場合、この関数は例外を発生させます。"},{"metadata":{"trusted":true},"cell_type":"code","source":"env.predict(sample_prediction_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loopについて\nテストセットジェネレーターの残りのすべてのバッチをループして、それぞれのデフォルトの予測を作成しましょう。 iter_testジェネレーターは、最後に到達すると、値の戻りを停止します。\n\n独自のノートブックを作成するときは、iter_test / predictループについての仮定をできるだけ少なくする堅牢なコードを作成するようにしてください。たとえば、テストセットには、これまでtrain内で観察されたことのない質問IDが含まれています。\n\nこのコンテストでは、基本的にsample_prediction_dfの構造はされません。"},{"metadata":{"trusted":true},"cell_type":"code","source":"for (test_df, sample_prediction_df) in iter_test:\n    test_df['answered_correctly'] = 0.5\n    env.predict(test_df.loc[test_df['content_type_id'] == 0, ['row_id', 'answered_correctly']])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# コード変更に伴うiterの再実行はNotebookの再起動が必要です\nmake_envを呼び出すか、iter_testを使って反復処理を行うことはノートブックの実行ごとに一度だけ許されています。しかし、モデルをイテレートしている間に、何かを試して、モデルを少し変えて、もう一度やってみるのは合理的です。残念ながら、単にコードを再実行しようとしたり、ブラウザのページをリフレッシュしようとしても、以前と同じNotebookの実行セッションで実行されていることになり、riideducationモジュールはまだエラーを投げます。これを回避するには、ノートブックの実行セッションを明示的に再起動する必要があります。これはノートブックエディタのメニューバーの上部にある \"Run\"->\"Restart Session \"をクリックすることで行うことができます。"},{"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}