{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# MLB submission is complete! \n\n* First of all, thank you very much to those who supported me, upvoted EDA, and excited me! I enjoyed experiencing various things.The top ones are really amazing. I respect them.\n\n* There was no leak just before train_updated.csv came out, and I shared the code that was in 12th place (experienced 1st to 12th place on the way) with explanations.\n\n* If I get worse score or submission error, please laugh me ! (I also laugh at my own...)\n\n## **I share this notebook, but it became long. I'm sorry if it feels hard to read. (Especially, infrence)**\n\n## But, if it is helpful for you, I'm grad if you **upvote**!","metadata":{}},{"cell_type":"markdown","source":"# MLB提出終わりました！　\n\n* まずは、応援してくれた方、EDAのupvote頂いた方、順位争いで熱くさせていただいた方、本当にありがとうございました！ いろいろ経験させていただいて楽しかったです。上位の方、本当にすごいです。尊敬します。\n\n* train_updated.csvが出る直前のリーク無しで、12位だった（途中1位~12位を経験)コードを解説込みでshareしたものです。\n\n* あと、もし結果が悪かったり、submission errorしていたら、笑ってください。私も自身を笑います。\n\n## **notebook公開しましたが、長くなってしまいました。読みにくかったらすみません(特にinference)**\n\n## でも、ご参考になれば、**upvote**頂けたら嬉しいです!","metadata":{}},{"cell_type":"markdown","source":"---------------------------------------------------","metadata":{}},{"cell_type":"markdown","source":"# 0. Summary\n(If I divide it roughly, there were 3 stages of score up, so I call each one the 1st phase, 2nd phase and 3rd phase.)\n\n1. The basic data used was the one merged by the kaggle staff who output it at https://www.kaggle.com/chumajin/eda-of-mlb-for-starter-version.\nref)  https://www.kaggle.com/ryanholbrook/getting-started-with-mlb-player-digital-engagement (thank you and please upvote their work!)\n\n2. For the 1st phase, all the data that can be used in 1. were used as features. \n(Maybe the difference from the published notebook is that the character strings like the date of debut in Major League Baseball and so on are also Label encoded and put in all. )\n\n3. I felt Cross Varidation was unstable if I use only in April 2021, so I divided the whole into 5 by target average and kfolded it.\n\n4. Basically, it's optuna + LightGBM. Score about 1.3490 with 5kfold. (I was surprised that it moved up to No. 1 at that time!) Considering the code published now, it is good.\n\n5. In the 2nd phase, I know the correct answer (target value) 31 days ago, so I put it in the feature quantity. With this, optuna + Light GBM with 5kfold and 1.3373\n(Actually, in addition to this, the feature amount was added to the ensemble and put out.) I used the GCP because of memory insufficient.\n\n6. In the last 3rd phase, Statistically, targets1 to 4 have a large number of 0s and 100s, respectively, and are likely to be np.clip. Therefore, I found that if the target values 0 and 100 are omitted and the target value between them is logged, a clean histogram will be obtained. Using this, I predicted log10 of target and finally made it 10 to the pred power. optuna and light GBM. Now it's 1.3256 with 5k fold. (Because Light GBM alone has this score, is it pretty good?) \n(Actually, in addition to this, the ones with features added, the ones for each position, the ones without log, etc. were ensembled and put out.)\nEnsemble using various features, about 1.3144.)\n\n7. From there, no hitter (perfect game) is obviously a high number, so I corrected it. Also, Shohei Ohtani did not follow the result of LGBM and corrected it(this may be overfit). So at the end, it was 1.3019, 12th place before leak.\n\n8. If submit is the feature amount mentioned in 5 of ↑, on 9/15, 31 days ago is about 8/15 and there is no correct answer, so 31-day shift data cannot be used. Create a model by creating shift data 47 days ago. * Created from the data from the place where there is a correct answer up to 7/31 47 days before 9/16 (I put a margin for some reason).\n The first submission uses the 47-day shift data. The second submission created 15-day shift data, 31-day shift data, and 47-day shift data, respectively, and submitted it as if changing the model when the date (8/1,8/16,9/1) came. I've used train_updata.csv fully, so I can only believe the actual score without submission error!","metadata":{}},{"cell_type":"markdown","source":"####  (大きく分けると3段階のスコアアップがあったので、それぞれ1st phase,2nd phase, 3rd phaseとか呼んでいます。)\n\n\n1. 　基本データは、https://www.kaggle.com/chumajin/eda-of-mlb-for-starter-version でoutputしたkaggleスタッフさんがmergeしてくれたものを使用しました。\n ref) https://www.kaggle.com/ryanholbrook/getting-started-with-mlb-player-digital-engagement (良かったら、彼らのコードをupvoteしてあげてください)\n\n2. 　1st phaseは、1.のデータを使えるものは全部特徴量として使用しました。(公開されているnotebookとは、メジャーリーグにデビューした日とかその辺の文字列もLabel encodingして全部入れたのが、違いです。この辺の文字列はEDAして効果ありそうだなと思っていました。)あと、このままだとtestデータを変換するときに、いろいろと不具合があったので、originalでコードを修正しました。\n \n3.  CVは、2021年4月だけだと不安定だと感じて、全体をtarget Averageで5分割してkfoldしました。\n\n4.  基本的には、optuna + LightGBMです。5kfoldでスコア 1.3490 程度。(これで当時1位に浮上してびっくり！）今公開されているコードを考えるとまぁまぁですかね。\n\n5. 2nd phaseは、31日前の正解(target値)は知っているからそれを特徴量に入れてみました。　これでoptuna + Light GBMで 5kfoldで1.3373 \n  (実際はこれに加えて特徴量加えたものをアンサンブルして出していました。 この辺からメモリが足りなくて、GCP使いました。)\n\n6.  最後の3rd phaseは、統計的にみて、target1～4は、それぞれ、0と100の個数が多くて、np.clipされていそう。そこで、target値の0と100のところは抜いて、その間のtarget値はlogを取ると、きれいなヒストグラムになることがわかりました。これを利用して、targetのlog10を予想して、最後、10のpred乗にするということをやりました。optunaとlight GBMしました。これで、5k foldで1.3256。(Light GBMだけでこのスコアだから、けっこう良いかと)\n(実際はこれに加えて特徴量加えたものや、ポジションごとのもの、logを使わなかったものなどをアンサンブルして出していました。)\n\n7.  いろいろな特徴量使用したものをアンサンブルして、1.3144程度。そこから、no hitter(完全試合)は明らかに数字が高いので、補正。あと大谷翔平選手もLGBMの結果に追従せず、補正。\n それで最後は、1.3019でleak前12位。\n   \n8.  submitは↑の5で述べた特徴量だと、9/15日は、31日前が8/15くらいで正解がないので、31日シフトデータは使用できず。\n　47日前シフトデータを作成して、モデル作成。 ※ 9/16日(マージンをなぜか1日入れてしまった。)の47日前の7/31までの正解があるところからデータから作成。\n1つ目のsubmissionはその47日シフトデータを使用。submission2は15日シフトデータ、31日シフトデータ、47日シフトデータをそれぞれ作成し、日付(8/1,8/16,9/1)になったら、モデルを変えるみたいな感じでsubmitしました。train_updata.csvをフル使用したので、実際のスコアは信じるのみです。submission error起こしてたらout・・・","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## This notebook cannot cover everything, but I will publish 1-8 above with explanations.\n\n## The part of creating optuna and model is omitted.\n\n\nこのnotebookでは、全部はまかなえませんが、上記1-8を解説を入れながら公開していきます。optuna,model作成のところはコードだけにして省略します。","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\nimport sys\nimport warnings\nfrom pathlib import Path\n\nimport os\n\nimport ipywidgets as widgets\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nwarnings.simplefilter(\"ignore\")\nimport datetime as dt\nfrom sklearn.preprocessing import LabelEncoder \n\nimport pickle\nfrom tqdm import tqdm\nimport random\n\nfrom datetime import date, timedelta","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-04T00:50:32.551755Z","iopub.execute_input":"2021-08-04T00:50:32.552221Z","iopub.status.idle":"2021-08-04T00:50:33.69609Z","shell.execute_reply.started":"2021-08-04T00:50:32.55212Z","shell.execute_reply":"2021-08-04T00:50:33.69509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. The basic data used was the one merged by the kaggle staff.\n基本データは、kaggleスタッフさんがmergeしてくれたものを使用しました。","metadata":{}},{"cell_type":"code","source":"train = pd.read_pickle(\"../input/eda-of-mlb-for-starter-version/player_engagement_with_info.pkl\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:50:33.698211Z","iopub.execute_input":"2021-08-04T00:50:33.698538Z","iopub.status.idle":"2021-08-04T00:50:55.309927Z","shell.execute_reply.started":"2021-08-04T00:50:33.698508Z","shell.execute_reply":"2021-08-04T00:50:55.308918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:50:55.312025Z","iopub.execute_input":"2021-08-04T00:50:55.312465Z","iopub.status.idle":"2021-08-04T00:50:56.702361Z","shell.execute_reply.started":"2021-08-04T00:50:55.312418Z","shell.execute_reply":"2021-08-04T00:50:56.70144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. For the 1st phase, all the data that can be used in 1. were used as features. \n(Maybe the difference from the published notebook is that the character strings like the date of debut in Major League Baseball and so on are also Label encoded and put in all. )\n\n","metadata":{}},{"cell_type":"markdown","source":"1st phaseは、1.のデータを使えるものは全部特徴量として使用しました。(公開されているnotebookとは、メジャーリーグにデビューした日とかその辺の文字列もLabel encodingして全部入れたのが、違いです。この辺の文字列はEDAして効果ありそうだなと思っていました。)あと、このままだとtestデータを変換するときに、いろいろと不具合があったので、originalでコードを修正しました。","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The features from the 9th row are used.\n\n\n9列目からを特徴量として使用。","metadata":{}},{"cell_type":"code","source":"features=train.columns[9:].to_list()\nfeatures","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:50:56.703775Z","iopub.execute_input":"2021-08-04T00:50:56.704089Z","iopub.status.idle":"2021-08-04T00:50:56.710632Z","shell.execute_reply.started":"2021-08-04T00:50:56.704061Z","shell.execute_reply":"2021-08-04T00:50:56.709775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Label encoding","metadata":{}},{"cell_type":"code","source":"cols = []\n\nfor col in tqdm(features):\n    if train[col].dtype == \"object\":\n        \n        train[col] = np.where(train[col].isna(),\"NaN\",train[col]) \n        \n       \n        train[col] = train[col].astype(\"category\")\n\n        le=LabelEncoder()\n        le.fit(train[col])\n        train[col] = le.transform(train[col])\n        with open( col + '_encoder.txt', 'wb') as f:\n              pickle.dump(le, f)\n\n\n        cols.append(col)\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:50:56.71196Z","iopub.execute_input":"2021-08-04T00:50:56.712272Z","iopub.status.idle":"2021-08-04T00:51:16.101934Z","shell.execute_reply.started":"2021-08-04T00:50:56.712246Z","shell.execute_reply":"2021-08-04T00:51:16.101002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"targets = [\"target1\", \"target2\", \"target3\", \"target4\"]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:16.103131Z","iopub.execute_input":"2021-08-04T00:51:16.103403Z","iopub.status.idle":"2021-08-04T00:51:16.107306Z","shell.execute_reply.started":"2021-08-04T00:51:16.103376Z","shell.execute_reply":"2021-08-04T00:51:16.106604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['date'] = pd.to_datetime(train['date'], format=\"%Y%m%d\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:16.108483Z","iopub.execute_input":"2021-08-04T00:51:16.108973Z","iopub.status.idle":"2021-08-04T00:51:16.19062Z","shell.execute_reply.started":"2021-08-04T00:51:16.108941Z","shell.execute_reply":"2021-08-04T00:51:16.189582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. kfold\n\nI felt Cross Varidation was unstable if I use only in April 2021, so I divided the whole into 5 by target average and kfolded it.\n\nSince I was doing the CommonLit Readability Prize, I referred to the following. upvote Thank you.\n\n\n","metadata":{}},{"cell_type":"markdown","source":"Cross Validationは、2021年4月だけだと不安定だと感じて、全体をtarget Averageで5分割してkfoldしました。\n\n\nCommonLit Readability Prizeをやっていたので、以下を参考にさせていただきました。upvoteよろしくお願いいたします。\n\nhttps://www.kaggle.com/abhishek/step-1-create-folds","metadata":{}},{"cell_type":"markdown","source":"\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-02T15:26:43.948031Z","iopub.execute_input":"2021-08-02T15:26:43.948513Z","iopub.status.idle":"2021-08-02T15:26:43.95436Z","shell.execute_reply.started":"2021-08-02T15:26:43.94848Z","shell.execute_reply":"2021-08-02T15:26:43.953383Z"}}},{"cell_type":"code","source":"from sklearn import datasets\nfrom sklearn import model_selection\n\ndef create_folds(data, num_splits,target):\n    # we create a new column called kfold and fill it with -1\n    data[\"kfold\"] = -1\n    \n    # the next step is to randomize the rows of the data\n    data = data.sample(frac=1).reset_index(drop=True)\n\n    # calculate number of bins by Sturge's rule\n    # I take the floor of the value, you can also\n    # just round it\n    num_bins = int(np.floor(1 + np.log2(len(data))))\n    \n    # bin targets\n    data.loc[:, \"bins\"] = pd.cut(\n        data[target], bins=num_bins, labels=False\n    )\n    \n    # initiate the kfold class from model_selection module\n    kf = model_selection.StratifiedKFold(n_splits=num_splits)\n    \n    # fill the new kfold column\n    # note that, instead of targets, we use bins!\n    for f, (t_, v_) in enumerate(kf.split(X=data, y=data.bins.values)):\n        data.loc[v_, 'kfold'] = f\n    \n    # drop the bins column\n    data = data.drop(\"bins\", axis=1)\n\n    # return dataframe with folds\n    return data","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:16.194489Z","iopub.execute_input":"2021-08-04T00:51:16.19491Z","iopub.status.idle":"2021-08-04T00:51:16.33354Z","shell.execute_reply.started":"2021-08-04T00:51:16.194878Z","shell.execute_reply":"2021-08-04T00:51:16.33248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:16.33524Z","iopub.execute_input":"2021-08-04T00:51:16.33554Z","iopub.status.idle":"2021-08-04T00:51:16.369568Z","shell.execute_reply.started":"2021-08-04T00:51:16.335511Z","shell.execute_reply":"2021-08-04T00:51:16.368491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"targetAvgを5分割しました。","metadata":{}},{"cell_type":"code","source":"folds = create_folds(train, 5,\"targetAvg\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:16.370833Z","iopub.execute_input":"2021-08-04T00:51:16.37116Z","iopub.status.idle":"2021-08-04T00:51:22.762472Z","shell.execute_reply.started":"2021-08-04T00:51:16.371127Z","shell.execute_reply":"2021-08-04T00:51:22.761326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folds.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:22.763927Z","iopub.execute_input":"2021-08-04T00:51:22.764253Z","iopub.status.idle":"2021-08-04T00:51:22.79336Z","shell.execute_reply.started":"2021-08-04T00:51:22.764221Z","shell.execute_reply":"2021-08-04T00:51:22.792588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. Basically, it's optuna + LightGBM. Score about 1.3490 with 5kfold. \n(I was surprised that it moved up to No. 1 at that time!) Considering the code published now, it is good.\n\n基本的には、optuna + LightGBMです。\n\n\ntargetAvgをもとに、kfold = 0のみoptuna。そのあと、1～4の個別のモデル作成。5kfoldでスコア 1.3490 程度。(これで当時1位に浮上してびっくり！）今公開されているコードを考えるとまぁまぁですかね。","metadata":{}},{"cell_type":"markdown","source":"## 4.1 optuna\nIf optuna did too much, the score was bad. I made it 1000 round.\n\n\noptunaはやりすぎるとスコアが悪かった。1000 roundにしました。","metadata":{}},{"cell_type":"code","source":"import lightgbm as lgb\nimport optuna.integration.lightgbm as lgbo","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:22.794391Z","iopub.execute_input":"2021-08-04T00:51:22.794798Z","iopub.status.idle":"2021-08-04T00:51:24.707769Z","shell.execute_reply.started":"2021-08-04T00:51:22.794767Z","shell.execute_reply":"2021-08-04T00:51:24.706788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\n## optuna ##\n    \ntraindf = folds[folds[\"kfold\"]!=0]\nvaliddf = folds[folds[\"kfold\"]==0]\n\ntraindf = traindf.reset_index(drop=True)\nvaliddf = validdf.reset_index(drop=True)\n\nlgb_train = lgbo.Dataset(traindf[features],traindf[\"targetAvg\"],categorical_feature=cols)\nlgb_valid = lgbo.Dataset(validdf[features],validdf[\"targetAvg\"],categorical_feature=cols)\nlgbm_params_optuna = {\n    'objective': 'mae', \n        \"seed\":42,\n    'metric': 'mae',\n\"verbose\":-1}\n\nres = {}\nmodel = lgbo.train(lgbm_params_optuna, lgb_train, valid_sets=lgb_valid,\n                  verbose_eval=50,  \n                  num_boost_round=1000,  \n                   early_stopping_rounds=10, \n                 evals_result=res)\n\nlgb_params2 = model.params\n\nwith open(\"LGBM_optuna.bin', 'wb') as f:\n          pickle.dump(model2, f)\n\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:24.709091Z","iopub.execute_input":"2021-08-04T00:51:24.7094Z","iopub.status.idle":"2021-08-04T00:51:24.716295Z","shell.execute_reply.started":"2021-08-04T00:51:24.709371Z","shell.execute_reply":"2021-08-04T00:51:24.715359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4.2 model making","metadata":{}},{"cell_type":"code","source":"\"\"\"\n## lgbm ####\n    \nfor fold in range(5):\n    print(\"--fole-----{}---start-----\".format(str(fold)))\n\n    traindf = folds[folds[\"kfold\"]!=fold]\n    validdf = folds[folds[\"kfold\"]==fold]\n\n    traindf = traindf.reset_index(drop=True)\n    validdf = validdf.reset_index(drop=True)\n\n\n    scores = []\n    res = {}\n    \n    for a in targets:\n\n        lgb_train = lgb.Dataset(traindf[features],traindf[a],categorical_feature=cols)\n        lgb_valid = lgb.Dataset(validdf[features],validdf[a],categorical_feature=cols)\n\n        model2 = lgb.train(lgb_params2, lgb_train, valid_sets=lgb_valid,\n                      verbose_eval=50,  \n                      num_boost_round=1000,  \n                      early_stopping_rounds=10, \n                     evals_result=res)\n\n        tmpdf = pd.DataFrame(res)\n        scores.append(np.min(tmpdf[\"valid_0\"][0]))\n\n        with open(\"LGBM_fold\"+str(fold) +\"_\" + a + '.bin', 'wb') as f:\n                  pickle.dump(model2, f)\n\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:24.718043Z","iopub.execute_input":"2021-08-04T00:51:24.718323Z","iopub.status.idle":"2021-08-04T00:51:24.730117Z","shell.execute_reply.started":"2021-08-04T00:51:24.718297Z","shell.execute_reply":"2021-08-04T00:51:24.729033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del folds\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:24.731312Z","iopub.execute_input":"2021-08-04T00:51:24.731793Z","iopub.status.idle":"2021-08-04T00:51:24.868672Z","shell.execute_reply.started":"2021-08-04T00:51:24.731763Z","shell.execute_reply":"2021-08-04T00:51:24.867675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" # 5. In the 2nd phase, we know the correct answer (target value) 31 days ago, so I added it in the features. \n \n With this, optuna + Light GBM with 5kfold and about 1.3373\n\n(Actually, in addition to this, the feature amount was added to the ensemble and submitted.)","metadata":{}},{"cell_type":"markdown","source":"2nd phaseは、31日前の正解(target値)は知っているからそれを特徴量に入れてみました。　これでoptuna + Light GBMで 5kfoldで1.3373 \n \n (実際はこれに加えて特徴量加えたものをアンサンブルして出していました。 )","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5.1 feature engineering","metadata":{}},{"cell_type":"code","source":"train.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:24.86978Z","iopub.execute_input":"2021-08-04T00:51:24.870076Z","iopub.status.idle":"2021-08-04T00:51:24.906656Z","shell.execute_reply.started":"2021-08-04T00:51:24.870047Z","shell.execute_reply":"2021-08-04T00:51:24.90593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5.1.1 Calculate the average value at that time for each playerId (the one used in the riiid competition)\n\nplayerIdごとにその時点での平均値を算出する (riiidコンペで使ったやつ)","metadata":{}},{"cell_type":"code","source":"dfgroup = train.groupby(\"playerId\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:24.907673Z","iopub.execute_input":"2021-08-04T00:51:24.908086Z","iopub.status.idle":"2021-08-04T00:51:24.911825Z","shell.execute_reply.started":"2021-08-04T00:51:24.908043Z","shell.execute_reply":"2021-08-04T00:51:24.911075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_feats = dfgroup[targets].agg([\"cumsum\",\"cumcount\"])\ntrain_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:24.912813Z","iopub.execute_input":"2021-08-04T00:51:24.913111Z","iopub.status.idle":"2021-08-04T00:51:26.013166Z","shell.execute_reply.started":"2021-08-04T00:51:24.913083Z","shell.execute_reply":"2021-08-04T00:51:26.012088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for a in targets:\n    train_feats[( a,   'mean')] = np.where(train_feats[(a,   'cumcount')]==0,np.nan,  train_feats[(a,   'cumsum')]/train_feats[( a,   'cumcount')] )\n    ","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.014764Z","iopub.execute_input":"2021-08-04T00:51:26.015236Z","iopub.status.idle":"2021-08-04T00:51:26.0969Z","shell.execute_reply.started":"2021-08-04T00:51:26.015187Z","shell.execute_reply":"2021-08-04T00:51:26.09605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.099888Z","iopub.execute_input":"2021-08-04T00:51:26.100295Z","iopub.status.idle":"2021-08-04T00:51:26.137275Z","shell.execute_reply.started":"2021-08-04T00:51:26.10026Z","shell.execute_reply":"2021-08-04T00:51:26.136103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I also want to use cumcount (cumulative number of appearances) as a feature.\n\ncumcount（累積登場回数）も特徴量として使いたい。","metadata":{}},{"cell_type":"code","source":"train_feats[\"ct\"] = train_feats[('target1', 'cumcount')]\ntrain_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.138681Z","iopub.execute_input":"2021-08-04T00:51:26.139123Z","iopub.status.idle":"2021-08-04T00:51:26.184301Z","shell.execute_reply.started":"2021-08-04T00:51:26.13908Z","shell.execute_reply":"2021-08-04T00:51:26.183087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Only the right 5 columns are used.\n\n右側5列だけ使用。","metadata":{}},{"cell_type":"code","source":"train_feats = train_feats.iloc[:,-5:]\ntrain_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.185686Z","iopub.execute_input":"2021-08-04T00:51:26.186099Z","iopub.status.idle":"2021-08-04T00:51:26.250739Z","shell.execute_reply.started":"2021-08-04T00:51:26.186056Z","shell.execute_reply":"2021-08-04T00:51:26.24987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Clean the column name\n\nカラム名をきれいに","metadata":{}},{"cell_type":"code","source":"train_feats.columns = [\"target1_mean\",\"target2_mean\",\"target3_mean\",\"target4_mean\",\"ct\"]\ntrain_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.255056Z","iopub.execute_input":"2021-08-04T00:51:26.255335Z","iopub.status.idle":"2021-08-04T00:51:26.274475Z","shell.execute_reply.started":"2021-08-04T00:51:26.255306Z","shell.execute_reply":"2021-08-04T00:51:26.273453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Add dailtyDataDate, playerId","metadata":{}},{"cell_type":"code","source":"train_feats[\"dailyDataDate\"] = train[\"dailyDataDate\"]\ntrain_feats[\"playerId\"] = train[\"playerId\"]\ntrain_feats.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.27711Z","iopub.execute_input":"2021-08-04T00:51:26.277408Z","iopub.status.idle":"2021-08-04T00:51:26.307648Z","shell.execute_reply.started":"2021-08-04T00:51:26.277378Z","shell.execute_reply":"2021-08-04T00:51:26.306586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Calculate the date when shifting by 31 days (we know the correct answer 31 days ago)\n\n31日分シフトしたときの日付を計算（私たちは、３１日前の正解を知っています)","metadata":{}},{"cell_type":"code","source":"period = 31\ntrain_feats[\"dailyDataDate2\"] = train_feats[\"dailyDataDate\"]\ntrain_feats[\"dailyDataDate\"] = train_feats[\"dailyDataDate2\"] + timedelta(days=period)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.309052Z","iopub.execute_input":"2021-08-04T00:51:26.309346Z","iopub.status.idle":"2021-08-04T00:51:26.359517Z","shell.execute_reply.started":"2021-08-04T00:51:26.309317Z","shell.execute_reply":"2021-08-04T00:51:26.35849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_feats.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.360793Z","iopub.execute_input":"2021-08-04T00:51:26.361126Z","iopub.status.idle":"2021-08-04T00:51:26.377009Z","shell.execute_reply.started":"2021-08-04T00:51:26.361095Z","shell.execute_reply":"2021-08-04T00:51:26.375906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Eventually, it will be merged with the data one month later, so dailyDataDate2 is the original date. The dailyDataDate is the data one month later.\n\n\n最終的には、1カ月後のデータとマージするので、dailyDataDate2は元の日付。dailyDataDateは1カ月後のデータとしました。","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next, add the correct answer of targets to train_feats.\n\n\n次に大本の正解をtrain_featsに追記します。","metadata":{}},{"cell_type":"code","source":"targets2 = targets.copy()\ntargets2.append(\"targetAvg\")\ntargets2","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.379166Z","iopub.execute_input":"2021-08-04T00:51:26.379725Z","iopub.status.idle":"2021-08-04T00:51:26.389911Z","shell.execute_reply.started":"2021-08-04T00:51:26.379673Z","shell.execute_reply":"2021-08-04T00:51:26.388884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for a in targets2:\n    train_feats[a] = train[a]\ntrain_feats.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.391401Z","iopub.execute_input":"2021-08-04T00:51:26.391701Z","iopub.status.idle":"2021-08-04T00:51:26.466463Z","shell.execute_reply.started":"2021-08-04T00:51:26.391671Z","shell.execute_reply":"2021-08-04T00:51:26.465485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5.1.2 Adding statics (median,max) values for LAGS","metadata":{}},{"cell_type":"markdown","source":"Next, target LAGS In this case, I took the statics (median,max) values for 31 , 45, 60, and 180 days, respectively.\n\n次にtargetのLAGS この場合、31日、45日、60日、180日の統計値(median,max)をそれぞれ取っていきます。","metadata":{}},{"cell_type":"code","source":"LAGS=[31,45,60,180]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.467788Z","iopub.execute_input":"2021-08-04T00:51:26.468092Z","iopub.status.idle":"2021-08-04T00:51:26.472345Z","shell.execute_reply.started":"2021-08-04T00:51:26.468063Z","shell.execute_reply":"2021-08-04T00:51:26.47168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def makeLAG(num):\n    tmp1 = train_feats.groupby([\"playerId\"])[\"target1\",\"target2\",\"target3\",\"target4\"].rolling(num).agg([\"median\",\"max\"]).reset_index()\n    \n    cols = []\n    cols.append(\"playerId\")\n    cols.append(\"level_1\")\n    for a in targets2[:-1]:\n        for b in [\"median\",\"max\"]:\n            cols.append(a+\"_\" + b)\n            \n    tmp1.columns=cols\n\n    tmp1.columns = [\"Lag\" + str(num) + \"_\" + str(s) for s in tmp1.columns]\n    \n    return tmp1","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.473283Z","iopub.execute_input":"2021-08-04T00:51:26.473654Z","iopub.status.idle":"2021-08-04T00:51:26.486079Z","shell.execute_reply.started":"2021-08-04T00:51:26.473625Z","shell.execute_reply":"2021-08-04T00:51:26.485149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag1 = makeLAG(LAGS[0])","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:26.487288Z","iopub.execute_input":"2021-08-04T00:51:26.487558Z","iopub.status.idle":"2021-08-04T00:51:46.719911Z","shell.execute_reply.started":"2021-08-04T00:51:26.487533Z","shell.execute_reply":"2021-08-04T00:51:46.718883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag1.tail(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:46.721347Z","iopub.execute_input":"2021-08-04T00:51:46.721673Z","iopub.status.idle":"2021-08-04T00:51:46.737803Z","shell.execute_reply.started":"2021-08-04T00:51:46.721643Z","shell.execute_reply":"2021-08-04T00:51:46.736737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag2 = makeLAG(LAGS[1])\nlag3 = makeLAG(LAGS[2])\nlag4 = makeLAG(LAGS[3])","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:51:46.739089Z","iopub.execute_input":"2021-08-04T00:51:46.739541Z","iopub.status.idle":"2021-08-04T00:52:49.351004Z","shell.execute_reply.started":"2021-08-04T00:51:46.7395Z","shell.execute_reply":"2021-08-04T00:52:49.350167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag2.tail(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:49.352105Z","iopub.execute_input":"2021-08-04T00:52:49.35253Z","iopub.status.idle":"2021-08-04T00:52:49.368412Z","shell.execute_reply.started":"2021-08-04T00:52:49.352489Z","shell.execute_reply":"2021-08-04T00:52:49.367372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"concat all LAG dataframes\n\n全部くっつけます","metadata":{}},{"cell_type":"code","source":"lagall = pd.concat([lag1,lag2.iloc[:,2:],lag3.iloc[:,2:],lag4.iloc[:,2:]],axis=1)\nlagall.tail(3)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:49.369642Z","iopub.execute_input":"2021-08-04T00:52:49.370015Z","iopub.status.idle":"2021-08-04T00:52:50.357523Z","shell.execute_reply.started":"2021-08-04T00:52:49.369972Z","shell.execute_reply":"2021-08-04T00:52:50.356462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del lag1,lag2,lag3,lag4\nimport gc\n_ = gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:50.358625Z","iopub.execute_input":"2021-08-04T00:52:50.358903Z","iopub.status.idle":"2021-08-04T00:52:50.494978Z","shell.execute_reply.started":"2021-08-04T00:52:50.358868Z","shell.execute_reply":"2021-08-04T00:52:50.493977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lagall = lagall.iloc[:,1:]\nlagall","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:50.496224Z","iopub.execute_input":"2021-08-04T00:52:50.496497Z","iopub.status.idle":"2021-08-04T00:52:51.839193Z","shell.execute_reply.started":"2021-08-04T00:52:50.49647Z","shell.execute_reply":"2021-08-04T00:52:51.838169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\nSince Lag31_level_1 is the row number of train_feats, use it to attach lagall to train_feats.\n\n\nLag31_level_1がtrain_featsのrow番号なので、それを利用してtrain_featsにlagallをくっつけます。\n","metadata":{}},{"cell_type":"code","source":"lagall = lagall.set_index(\"Lag31_level_1\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:51.840537Z","iopub.execute_input":"2021-08-04T00:52:51.840828Z","iopub.status.idle":"2021-08-04T00:52:52.089703Z","shell.execute_reply.started":"2021-08-04T00:52:51.840798Z","shell.execute_reply":"2021-08-04T00:52:52.088685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lagall","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:52.090887Z","iopub.execute_input":"2021-08-04T00:52:52.091205Z","iopub.status.idle":"2021-08-04T00:52:53.311954Z","shell.execute_reply.started":"2021-08-04T00:52:52.091173Z","shell.execute_reply":"2021-08-04T00:52:53.310963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"concat to train_feats\n\ntrain_featsにくっつけます。\n","metadata":{}},{"cell_type":"code","source":"train_feats = pd.concat([train_feats,lagall],axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:53.313352Z","iopub.execute_input":"2021-08-04T00:52:53.313642Z","iopub.status.idle":"2021-08-04T00:52:54.796451Z","shell.execute_reply.started":"2021-08-04T00:52:53.313611Z","shell.execute_reply":"2021-08-04T00:52:54.795445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del lagall\n_ = gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:54.80007Z","iopub.execute_input":"2021-08-04T00:52:54.800413Z","iopub.status.idle":"2021-08-04T00:52:54.933273Z","shell.execute_reply.started":"2021-08-04T00:52:54.800379Z","shell.execute_reply":"2021-08-04T00:52:54.931949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:54.934872Z","iopub.execute_input":"2021-08-04T00:52:54.935266Z","iopub.status.idle":"2021-08-04T00:52:56.048175Z","shell.execute_reply.started":"2021-08-04T00:52:54.935232Z","shell.execute_reply":"2021-08-04T00:52:56.0474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"targetsはもう使わないので、落とします。","metadata":{}},{"cell_type":"code","source":"train_feats = train_feats.drop(targets2,axis=1)\ntrain_feats","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:52:56.049313Z","iopub.execute_input":"2021-08-04T00:52:56.049716Z","iopub.status.idle":"2021-08-04T00:53:01.172671Z","shell.execute_reply.started":"2021-08-04T00:52:56.049686Z","shell.execute_reply":"2021-08-04T00:53:01.170068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"Separate for train data and test data.\n\ntrainデータ用とtestデータ用に分離します。","metadata":{}},{"cell_type":"code","source":"train_feats_fin = train_feats[train_feats[\"dailyDataDate\"]<\"20210501\"].reset_index(drop=True)\nfutureLAG = train_feats[train_feats[\"dailyDataDate\"]>=\"20210501\"].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:01.175365Z","iopub.execute_input":"2021-08-04T00:53:01.175744Z","iopub.status.idle":"2021-08-04T00:53:02.954717Z","shell.execute_reply.started":"2021-08-04T00:53:01.175692Z","shell.execute_reply":"2021-08-04T00:53:02.953701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del train_feats\n_ = gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:02.956108Z","iopub.execute_input":"2021-08-04T00:53:02.956418Z","iopub.status.idle":"2021-08-04T00:53:03.182975Z","shell.execute_reply.started":"2021-08-04T00:53:02.956389Z","shell.execute_reply":"2021-08-04T00:53:03.18187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"merge train data. futureLAG will be used in inferece.\n\ntrainデータとmergeします。futureLAGはinferenceで使用します。","metadata":{}},{"cell_type":"code","source":"train = pd.merge(train,train_feats_fin,on=[\"dailyDataDate\",\"playerId\"],how=\"left\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:03.184245Z","iopub.execute_input":"2021-08-04T00:53:03.184541Z","iopub.status.idle":"2021-08-04T00:53:11.638613Z","shell.execute_reply.started":"2021-08-04T00:53:03.184511Z","shell.execute_reply":"2021-08-04T00:53:11.637559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del train_feats_fin\n_ = gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:11.640016Z","iopub.execute_input":"2021-08-04T00:53:11.64031Z","iopub.status.idle":"2021-08-04T00:53:11.779719Z","shell.execute_reply.started":"2021-08-04T00:53:11.640281Z","shell.execute_reply":"2021-08-04T00:53:11.778577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:11.78092Z","iopub.execute_input":"2021-08-04T00:53:11.781538Z","iopub.status.idle":"2021-08-04T00:53:12.672686Z","shell.execute_reply.started":"2021-08-04T00:53:11.781499Z","shell.execute_reply":"2021-08-04T00:53:12.67194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5.2 2nd phase Modeling (I used GCP because the memory is insufficient.)","metadata":{}},{"cell_type":"code","source":"train = train.drop(\"dailyDataDate2\",axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:12.673849Z","iopub.execute_input":"2021-08-04T00:53:12.674214Z","iopub.status.idle":"2021-08-04T00:53:17.171705Z","shell.execute_reply.started":"2021-08-04T00:53:12.674179Z","shell.execute_reply":"2021-08-04T00:53:17.170529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features = train.columns[9:].to_list()\nfeatures","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:17.173123Z","iopub.execute_input":"2021-08-04T00:53:17.173448Z","iopub.status.idle":"2021-08-04T00:53:17.181769Z","shell.execute_reply.started":"2021-08-04T00:53:17.173416Z","shell.execute_reply":"2021-08-04T00:53:17.180883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the experimental results, the score increased a little except for numGamesTeam.\n\n\n実験結果から、numGamesTeamを除くと少しスコアが上がりました。","metadata":{}},{"cell_type":"code","source":"features.remove('numGamesTeam')","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:17.183026Z","iopub.execute_input":"2021-08-04T00:53:17.183327Z","iopub.status.idle":"2021-08-04T00:53:17.193392Z","shell.execute_reply.started":"2021-08-04T00:53:17.183298Z","shell.execute_reply":"2021-08-04T00:53:17.19267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\n## kfold ##\n\nfolds = create_folds(train, 5,\"targetAvg\")\n\n\n## optuna ##\n    \ntraindf = folds[folds[\"kfold\"]!=0]\nvaliddf = folds[folds[\"kfold\"]==0]\n\ntraindf = traindf.reset_index(drop=True)\nvaliddf = validdf.reset_index(drop=True)\n\nlgb_train = lgbo.Dataset(traindf[features],traindf[\"targetAvg\"],categorical_feature=cols)\nlgb_valid = lgbo.Dataset(validdf[features],validdf[\"targetAvg\"],categorical_feature=cols)\nlgbm_params_optuna = {\n    'objective': 'mae', \n        \"seed\":42,\n    'metric': 'mae',\n\"verbose\":-1}\n\nres = {}\nmodel = lgbo.train(lgbm_params_optuna, lgb_train, valid_sets=lgb_valid,\n                  verbose_eval=50,  \n                  num_boost_round=1000,  \n                   early_stopping_rounds=10, \n                 evals_result=res)\n\nlgb_params2 = model.params\n\nwith open(\"LGBM_optuna.bin', 'wb') as f:\n          pickle.dump(model2, f)\n\n\n## lgbm ####\n    \nfor fold in range(5):\n    print(\"--fole-----{}---start-----\".format(str(fold)))\n\n    traindf = folds[folds[\"kfold\"]!=fold]\n    validdf = folds[folds[\"kfold\"]==fold]\n\n    traindf = traindf.reset_index(drop=True)\n    validdf = validdf.reset_index(drop=True)\n\n\n    scores = []\n    res = {}\n    \n    for a in targets:\n\n        lgb_train = lgb.Dataset(traindf[features],traindf[a],categorical_feature=cols)\n        lgb_valid = lgb.Dataset(validdf[features],validdf[a],categorical_feature=cols)\n\n        model2 = lgb.train(lgb_params2, lgb_train, valid_sets=lgb_valid,\n                      verbose_eval=50,  \n                      num_boost_round=1000,  \n                      early_stopping_rounds=10, \n                     evals_result=res)\n\n        tmpdf = pd.DataFrame(res)\n        scores.append(np.min(tmpdf[\"valid_0\"][0]))\n\n        with open(\"LGBM_fold\"+str(fold) +\"_\" + a + '.bin', 'wb') as f:\n                  pickle.dump(model2, f)\n\n\"\"\"\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:17.194525Z","iopub.execute_input":"2021-08-04T00:53:17.194955Z","iopub.status.idle":"2021-08-04T00:53:17.206574Z","shell.execute_reply.started":"2021-08-04T00:53:17.194923Z","shell.execute_reply":"2021-08-04T00:53:17.205686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This will be about 1.3370.","metadata":{}},{"cell_type":"markdown","source":"# 6. In the last 3rd phase, I used log scale of targets for learning.\n\nStatistically, targets1 to 4 have a large number of 0s and 100s, respectively, and are likely to be np.clip. Therefore, I found that if the target values 0 and 100 are omitted and the target value between them is logged, a clean histogram will be obtained. Using this, I predicted log10 of target and finally made it 10 to the pred power. optuna and light GBM. Now it's 1.3256 with 5k fold. (Because Light GBM alone has this score, is it pretty good?) ","metadata":{}},{"cell_type":"markdown","source":"最後の3rd phaseは、統計的にみて、target1～4は、それぞれ、0と100の個数が多くて、np.clipされていそう。そこで、target値の0と100のところは抜いて、その間のtarget値はlogを取ると、きれいなヒストグラムになることがわかりました。これを利用して、targetのlog10を予想して、最後、10のpred乗にするということをやりました。optunaとlight GBMしました。これで、5k foldで1.3256。(Light GBMだけでこのスコアだから、けっこう良いかと)","metadata":{}},{"cell_type":"markdown","source":"## 6.1 Analysis of Target1","metadata":{}},{"cell_type":"code","source":"Vcount = train[\"target1\"].value_counts().reset_index()\nVcount.columns = [\"target1\",\"count\"]\nVcount","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:17.207877Z","iopub.execute_input":"2021-08-04T00:53:17.20818Z","iopub.status.idle":"2021-08-04T00:53:17.347049Z","shell.execute_reply.started":"2021-08-04T00:53:17.20815Z","shell.execute_reply":"2021-08-04T00:53:17.346074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The number of 0 and 100 is very large. I guessed it was clipped at 0 and 100, so I removed 0 and 100.\n\n0と100の数が他に比べて異様に多いことがわかりました。0と100でクリップされていることを推測しましたので、0と100は除去しました。","metadata":{}},{"cell_type":"code","source":"analize_t1 = train[\"target1\"][(train[\"target1\"]!=0)&(train[\"target1\"]!=100)].reset_index()\nanalize_t1","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:17.348296Z","iopub.execute_input":"2021-08-04T00:53:17.348601Z","iopub.status.idle":"2021-08-04T00:53:17.403738Z","shell.execute_reply.started":"2021-08-04T00:53:17.348571Z","shell.execute_reply":"2021-08-04T00:53:17.402761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next, when writing a histogram for normal targets 1 to 4, there are many averages near 0, which is not beautiful.\n\n次に、通常のtarget1～4はヒストグラムを書くと、0付近に平均が多く、きれいではありません。","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(25,5))\nfor num,a in enumerate(targets):\n\n    plt.subplot(1,4,num+1)\n    plt.hist(train[a])\n    plt.xlabel(a)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:17.405054Z","iopub.execute_input":"2021-08-04T00:53:17.405343Z","iopub.status.idle":"2021-08-04T00:53:18.277922Z","shell.execute_reply.started":"2021-08-04T00:53:17.405314Z","shell.execute_reply":"2021-08-04T00:53:18.277006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If you pull out 0,100 and log this, you can see that it has a clean distribution (especially target4).\n\n0,100を抜いて、これのlogを取ると、きれいな分布（特にtarget4)になることがわかりました。","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(25,5))\nfor num,a in enumerate(targets):\n    \n    analize_t1 = train[a][(train[a]!=0)&(train[a]!=100)].reset_index()\n\n    plt.subplot(1,4,num+1)\n    plt.hist(np.log(analize_t1[a]))\n    plt.xlabel(\"log \" + a)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:18.279236Z","iopub.execute_input":"2021-08-04T00:53:18.279508Z","iopub.status.idle":"2021-08-04T00:53:19.501327Z","shell.execute_reply.started":"2021-08-04T00:53:18.27948Z","shell.execute_reply":"2021-08-04T00:53:19.500164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Therefore, I predicted the target with log and returned it to the end, and the score went up.\n\nそのため、targetをlogで予想して、最後に戻してあげたらスコアが上がりました。(1.3373→1.3256)","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I pulled out 0 and 100 for each target, did optuna with log, and created a model with lgbm.※ Using GCP\n\n各targetで0と100を抜いて、logでoptunaを行い、lgbmでモデル作成しました。 ※ GCP使用。","metadata":{}},{"cell_type":"code","source":"\"\"\"\n\nfor a in targets:\n\n    ### pull out target 0, target 100\n    \n    train0 = train[(train[a]!=0) & (train[a]!=100)].reset_index(drop=True)\n\n    ### kfold ###\n    \n    folds = create_folds(train0, 5,a)\n\n    folds[a] = np.log10(folds[a])\n\n    ## optuna ##\n    \n    traindf = folds[folds[\"kfold\"]!=0]\n    validdf = folds[folds[\"kfold\"]==0]\n\n    traindf = traindf.reset_index(drop=True)\n    validdf = validdf.reset_index(drop=True)\n\n    lgb_train = lgbo.Dataset(traindf[features],traindf[a],categorical_feature=cols)\n    lgb_valid = lgbo.Dataset(validdf[features],validdf[a],categorical_feature=cols)\n    lgbm_params_optuna = {\n        'objective': 'mae', # Binary classification : 2値分類ではこれを使う\n            \"seed\":42,\n        'metric': 'mae',\n    \"verbose\":-1}\n\n    res = {}\n    model = lgbo.train(lgbm_params_optuna, lgb_train, valid_sets=lgb_valid,\n                      verbose_eval=50,  # Learning result output every 50 iterations : 50イテレーション毎に学習結果出力\n                      num_boost_round=1000,  # Specify the maximum number of iterations : 最大イテレーション回数指定\n                      early_stopping_rounds=10, # Early stopping number : early stoppingを採用するiteration回数\n                     evals_result=res)\n\n    model.params\n\n    lgb_params2 = model.params\n    \n    ## lgbm ####\n    \n    for fold in range(5):\n        print(\"--fole-----{}---start-----\".format(str(fold)))\n        \n        traindf = folds[folds[\"kfold\"]!=fold]\n        validdf = folds[folds[\"kfold\"]==fold]\n\n        traindf = traindf.reset_index(drop=True)\n        validdf = validdf.reset_index(drop=True)\n\n\n        scores = []\n        res = {}\n\n       \n        lgb_train = lgb.Dataset(traindf[features],traindf[a],categorical_feature=cols)\n        lgb_valid = lgb.Dataset(validdf[features],validdf[a],categorical_feature=cols)\n\n        model2 = lgb.train(lgb_params2, lgb_train, valid_sets=lgb_valid,\n                      verbose_eval=50,  # Learning result output every 50 iterations : 50イテレーション毎に学習結果出力\n                      num_boost_round=1000,  # Specify the maximum number of iterations : 最大イテレーション回数指定\n                      early_stopping_rounds=10, # Early stopping number : early stoppingを採用するiteration回数\n                     evals_result=res)\n\n        tmpdf = pd.DataFrame(res)\n        scores.append(np.min(tmpdf[\"valid_0\"][0]))\n\n        with open(savepath + \"/LGBM_fold\"+str(fold) +\"_\" + a + '.bin', 'wb') as f:\n                  pickle.dump(model2, f)\n\n\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:19.50287Z","iopub.execute_input":"2021-08-04T00:53:19.503266Z","iopub.status.idle":"2021-08-04T00:53:19.512271Z","shell.execute_reply.started":"2021-08-04T00:53:19.503223Z","shell.execute_reply":"2021-08-04T00:53:19.511031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This gives a score of 1.3256. After that, I ensembled using the ones created using other features.\n\nこれでスコア1.3256。あとは、他の特徴量を使用して作成したものなどを使って、アンサンブルしました。","metadata":{"execution":{"iopub.status.busy":"2021-08-03T15:19:33.783772Z","iopub.execute_input":"2021-08-03T15:19:33.784216Z","iopub.status.idle":"2021-08-03T15:19:33.792309Z","shell.execute_reply.started":"2021-08-03T15:19:33.784181Z","shell.execute_reply":"2021-08-03T15:19:33.790597Z"}}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 7. Correction\nI found that no hitter (perfect game) is obviously a high number, so I corrected it using median values of all train data.\n\nno hitter(完全試合)の日だけ明らかに飛び値が出ていることがわかったので、置き換えました。","metadata":{}},{"cell_type":"code","source":"train.groupby(\"noHitter\")[targets].median().reset_index()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:19.513548Z","iopub.execute_input":"2021-08-04T00:53:19.513946Z","iopub.status.idle":"2021-08-04T00:53:19.6557Z","shell.execute_reply.started":"2021-08-04T00:53:19.513903Z","shell.execute_reply":"2021-08-04T00:53:19.653971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Also, Shohei Ohtani(playerId 660271) did not follow the result of LGBM and corrected it by using the difference of LGBM pred and correct on April.\n(It has a possibility of overfit. Other players got worse score.)\n\n大谷翔平だけLGBMの予測値が最も合わず、差分を予測値に足したら、スコアが良くなったので、補正しました(たぶん、overfit)。0.05改善するレベル。他のプレイヤーはこれをやると逆にスコアが悪くなりました。\n\n\n","metadata":{}},{"cell_type":"code","source":"april = pd.read_csv(\"../input/optuna16/optuna16_aprildiff.csv\")\napril[\"targetAve_diff\"] = april.iloc[:,1:].mean(axis=1)\napril = april.sort_values(\"targetAve_diff\").reset_index(drop=True)\napril","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:19.657873Z","iopub.execute_input":"2021-08-04T00:53:19.658216Z","iopub.status.idle":"2021-08-04T00:53:19.711337Z","shell.execute_reply.started":"2021-08-04T00:53:19.658184Z","shell.execute_reply":"2021-08-04T00:53:19.710307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Only one person will pull from pred later.\n\n一人だけ後でpredから引きます。","metadata":{}},{"cell_type":"code","source":"targets2 = april.columns[1:5].to_list()\nnum = 1\ntargets2\nfor a in targets2:\n    april[a] = np.where(april.index>=num,0,april[a])\n\napril","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:19.712651Z","iopub.execute_input":"2021-08-04T00:53:19.713012Z","iopub.status.idle":"2021-08-04T00:53:19.737903Z","shell.execute_reply.started":"2021-08-04T00:53:19.712959Z","shell.execute_reply":"2021-08-04T00:53:19.73679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"So at the end, it was 1.3019, 12th place before leak.\n\nそれで最後は1.3019. leak前で12位でした。","metadata":{}},{"cell_type":"code","source":"del train\n_ = gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:19.739339Z","iopub.execute_input":"2021-08-04T00:53:19.739639Z","iopub.status.idle":"2021-08-04T00:53:19.928909Z","shell.execute_reply.started":"2021-08-04T00:53:19.73961Z","shell.execute_reply":"2021-08-04T00:53:19.927804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 7.1 Final inference ( But late submission is not active. just to see)","metadata":{}},{"cell_type":"markdown","source":"The basic idea is mentioned above. You may not be able to understand from here, but this is the actual inference code.\n\n基本的な考え方を上に述べました。ここからは見てもわからないかもしれませんが、実際のinferenceのコードです。late submissionできないみたいです。","metadata":{}},{"cell_type":"markdown","source":"Prepare LAG data to merge with the test data created earlier\n\nテストデータとマージするようのLAGデータを準備","metadata":{}},{"cell_type":"code","source":"futureLAG = pd.read_pickle(\"../input/optuna9/lag_evalsheet_light20210706.pkl\")\nfutureLAG","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:19.930456Z","iopub.execute_input":"2021-08-04T00:53:19.930746Z","iopub.status.idle":"2021-08-04T00:53:21.481518Z","shell.execute_reply.started":"2021-08-04T00:53:19.930719Z","shell.execute_reply":"2021-08-04T00:53:21.480441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"futureLAG = futureLAG.drop(\"dailyDataDate2\",axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:21.482783Z","iopub.execute_input":"2021-08-04T00:53:21.483079Z","iopub.status.idle":"2021-08-04T00:53:21.495529Z","shell.execute_reply.started":"2021-08-04T00:53:21.483052Z","shell.execute_reply":"2021-08-04T00:53:21.494765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 7.1.2 making test features\n","metadata":{}},{"cell_type":"markdown","source":"See the code from EDA's kaggle staff for adjustments in this area. Anyway, I adjusted it so that the test data also flows.\n(This is the code below. Thank you.)\n\nこの辺の調整は、EDAのkaggleのスタッフさんのコードを見てください。とにかくテストデータでも流れるように調整しました。\n(↓のコードです。ありがとうございます。)\n\nhttps://www.kaggle.com/ryanholbrook/getting-started-with-mlb-player-digital-engagement","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training = pd.read_csv(\"../input/mlb-player-digital-engagement-forecasting/train.csv\",nrows=100)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:21.496963Z","iopub.execute_input":"2021-08-04T00:53:21.497293Z","iopub.status.idle":"2021-08-04T00:53:24.287818Z","shell.execute_reply.started":"2021-08-04T00:53:21.497261Z","shell.execute_reply":"2021-08-04T00:53:24.286854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Helper function to unpack json found in daily data\ndef unpack_json(json_str):\n    return np.nan if pd.isna(json_str) else pd.read_json(json_str)\n\ndf_names = ['seasons', 'teams', 'players', 'awards']\n\npath = \"../input/mlb-player-digital-engagement-forecasting\"\n\nfor name in df_names:\n    globals()[name] = pd.read_csv(os.path.join(path,name)+ \".csv\")\n","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:24.289115Z","iopub.execute_input":"2021-08-04T00:53:24.289407Z","iopub.status.idle":"2021-08-04T00:53:24.362467Z","shell.execute_reply.started":"2021-08-04T00:53:24.289377Z","shell.execute_reply":"2021-08-04T00:53:24.361323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#### Unnest various nested data within training (daily) data ####\ndaily_data_unnested_dfs = pd.DataFrame(data = {\n  'dfName': training.drop('date', axis = 1).columns.values.tolist()\n  })\n\ndaily_data_unnested_dfs['df'] = [pd.DataFrame() for row in \n  daily_data_unnested_dfs.iterrows()]\n\nfor df_index, df_row in daily_data_unnested_dfs.iterrows():\n    nestedTableName = str(df_row['dfName'])\n    \n    date_nested_table = training[['date', nestedTableName]]\n    \n    date_nested_table = (date_nested_table[\n      ~pd.isna(date_nested_table[nestedTableName])\n      ].\n      reset_index(drop = True)\n      )\n    \n    daily_dfs_collection = []\n    \n    for date_index, date_row in date_nested_table.iterrows():\n        daily_df = unpack_json(date_row[nestedTableName])\n        \n        daily_df['dailyDataDate'] = date_row['date']\n        \n        daily_dfs_collection = daily_dfs_collection + [daily_df]\n\n    unnested_table = pd.concat(daily_dfs_collection,\n      ignore_index = True).set_index('dailyDataDate').reset_index()\n\n    # Creates 1 pandas df per unnested df from daily data read in, with same name\n    globals()[df_row['dfName']] = unnested_table    \n    \n    daily_data_unnested_dfs['df'][df_index] = unnested_table\n\ndel training\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:24.36386Z","iopub.execute_input":"2021-08-04T00:53:24.364181Z","iopub.status.idle":"2021-08-04T00:53:34.447701Z","shell.execute_reply.started":"2021-08-04T00:53:24.364149Z","shell.execute_reply":"2021-08-04T00:53:34.446827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preparation(training,sample_sub):\n    training['date'] = pd.to_datetime(training['date'], format=\"%Y%m%d\")\n    sample_sub['date'] = pd.to_datetime(sample_sub['date'], format=\"%Y%m%d\")\n    sample_sub = sample_sub[[\"date\",\"date_playerId\"]]\n    sample_sub[\"playerId\"] = [s.split(\"_\")[-1] for s in sample_sub[\"date_playerId\"]]\n    sample_sub[\"playerId\"] = sample_sub[\"playerId\"].astype(\"int\")\n    sample_sub.columns = ['dailyDataDate',\"date_playerId\",\"playerId\"]\n    \n    \n\n\n\n    #### Unnest various nested data within training (daily) data ####\n    daily_data_unnested_dfs = pd.DataFrame(data = {\n      'dfName': training.drop('date', axis = 1).columns.values.tolist()\n      })\n\n    daily_data_unnested_dfs['df'] = [pd.DataFrame() for row in \n      daily_data_unnested_dfs.iterrows()]\n\n    for df_index, df_row in daily_data_unnested_dfs.iterrows():\n        nestedTableName = str(df_row['dfName'])\n\n        date_nested_table = training[['date', nestedTableName]]\n\n        date_nested_table = (date_nested_table[\n          ~pd.isna(date_nested_table[nestedTableName])\n          ].\n          reset_index(drop = True)\n          )\n\n        daily_dfs_collection = []\n\n        for date_index, date_row in date_nested_table.iterrows():\n            daily_df = unpack_json(date_row[nestedTableName])\n\n            daily_df['dailyDataDate'] = date_row['date']\n\n            daily_dfs_collection = daily_dfs_collection + [daily_df]\n            \n        # adding\n        if len(daily_dfs_collection) == 0:\n\n            unnested_table = pd.DataFrame(columns=eval(nestedTableName).columns)\n            unnested_table['dailyDataDate'] = testdf['date']\n\n        else:\n            unnested_table = pd.concat(daily_dfs_collection,\n          ignore_index = True).set_index('dailyDataDate').reset_index()\n\n\n\n        # Creates 1 pandas df per unnested df from daily data read in, with same name\n        globals()[df_row['dfName']] = unnested_table.copy()    \n\n        daily_data_unnested_dfs['df'][df_index] = unnested_table.copy()\n\n    del training\n    gc.collect()\n\n\n\n    #### Get some information on each date in daily data (using season dates of interest) ####\n    dates = pd.DataFrame(data = \n      {'dailyDataDate': games['dailyDataDate'].unique()})\n\n    dates['date'] = pd.to_datetime(dates['dailyDataDate'].astype(str))\n\n    dates['year'] = dates['date'].dt.year\n    dates['month'] = dates['date'].dt.month\n\n    dates_with_info = pd.merge(\n      dates,\n      seasons,\n      left_on = 'year',\n      right_on = 'seasonId'\n      )\n\n    dates_with_info['inSeason'] = (\n      dates_with_info['date'].between(\n        dates_with_info['regularSeasonStartDate'],\n        dates_with_info['postSeasonEndDate'],\n        inclusive = True\n        )\n      )\n\n    dates_with_info['seasonPart'] = np.select(\n      [\n        dates_with_info['date'] < dates_with_info['preSeasonStartDate'], \n        dates_with_info['date'] < dates_with_info['regularSeasonStartDate'],\n        dates_with_info['date'] <= dates_with_info['lastDate1stHalf'],\n        dates_with_info['date'] < dates_with_info['firstDate2ndHalf'],\n        dates_with_info['date'] <= dates_with_info['regularSeasonEndDate'],\n        dates_with_info['date'] < dates_with_info['postSeasonStartDate'],\n        dates_with_info['date'] <= dates_with_info['postSeasonEndDate'],\n        dates_with_info['date'] > dates_with_info['postSeasonEndDate']\n      ], \n      [\n        'Offseason',\n        'Preseason',\n        'Reg Season 1st Half',\n        'All-Star Break',\n        'Reg Season 2nd Half',\n        'Between Reg and Postseason',\n        'Postseason',\n        'Offseason'\n      ], \n      default = np.nan\n      )\n\n    #### Add some pitching stats/pieces of info to player game level stats ####\n\n    player_game_stats = (playerBoxScores.copy().\n      # Change team Id/name to reflect these come from player game, not roster\n      rename(columns = {'teamId': 'gameTeamId', 'teamName': 'gameTeamName'})\n      )\n\n    # Adds in field for innings pitched as fraction (better for aggregation)\n    \n    # add chumajin I don't know why np.where becomes error... this is repaired version\n    if pd.isna(player_game_stats['inningsPitched'])[0]:\n        player_game_stats['inningsPitchedAsFrac'] = np.nan\n    else:\n        player_game_stats['inningsPitchedAsFrac'] = np.where(\n          pd.isna(player_game_stats['inningsPitched']),\n          np.nan,\n          np.floor(player_game_stats['inningsPitched']) +\n            (player_game_stats['inningsPitched'] -\n              np.floor(player_game_stats['inningsPitched'])) * 10/3\n          )\n\n    # Add in Tom Tango pitching game score (https://www.mlb.com/glossary/advanced-stats/game-score)\n    player_game_stats['pitchingGameScore'] = (40\n    #     + 2 * player_game_stats['outs']\n        + 1 * player_game_stats['strikeOutsPitching']\n        - 2 * player_game_stats['baseOnBallsPitching']\n        - 2 * player_game_stats['hitsPitching']\n        - 3 * player_game_stats['runsPitching']\n        - 6 * player_game_stats['homeRunsPitching']\n        )\n\n    # Add in criteria for no-hitter by pitcher (individual, not multiple pitchers)\n    player_game_stats['noHitter'] = np.where(\n      (player_game_stats['gamesStartedPitching'] == 1) &\n      (player_game_stats['inningsPitched'] >= 9) &\n      (player_game_stats['hitsPitching'] == 0),\n      1, 0\n      )\n\n    player_date_stats_agg = pd.merge(\n      (player_game_stats.\n        groupby(['dailyDataDate', 'playerId'], as_index = False).\n        # Some aggregations that are not simple sums\n        agg(\n          numGames = ('gamePk', 'nunique'),\n          # Should be 1 team per player per day, but adding here for 1 exception:\n          # playerId 518617 (Jake Diekman) had 2 games for different teams marked\n          # as played on 5/19/19, due to resumption of game after he was traded\n          numTeams = ('gameTeamId', 'nunique'),\n          # Should be only 1 team for almost all player-dates, taking min to simplify\n          gameTeamId = ('gameTeamId', 'min')\n          )\n        ),\n      # Merge with a bunch of player stats that can be summed at date/player level\n      (player_game_stats.\n        groupby(['dailyDataDate', 'playerId'], as_index = False)\n        [['runsScored', 'homeRuns', 'strikeOuts', 'baseOnBalls', 'hits',\n          'hitByPitch', 'atBats', 'caughtStealing', 'stolenBases',\n          'groundIntoDoublePlay', 'groundIntoTriplePlay', 'plateAppearances',\n          'totalBases', 'rbi', 'leftOnBase', 'sacBunts', 'sacFlies',\n          'gamesStartedPitching', 'runsPitching', 'homeRunsPitching', \n          'strikeOutsPitching', 'baseOnBallsPitching', 'hitsPitching',\n          'inningsPitchedAsFrac', 'earnedRuns', \n          'battersFaced','saves', 'blownSaves', 'pitchingGameScore', \n          'noHitter'\n          ]].\n        sum()\n        ),\n      on = ['dailyDataDate', 'playerId'],\n      how = 'inner'\n      )\n\n    #### Turn games table into 1 row per team-game, then merge with team box scores ####\n    # Filter to regular or Postseason games w/ valid scores for this part\n    games_for_stats = games[\n      np.isin(games['gameType'], ['R', 'F', 'D', 'L', 'W', 'C', 'P']) &\n      ~pd.isna(games['homeScore']) &\n      ~pd.isna(games['awayScore'])\n      ]\n\n    # Get games table from home team perspective\n    games_home_perspective = games_for_stats.copy()\n\n    # Change column names so that \"team\" is \"home\", \"opp\" is \"away\"\n    games_home_perspective.columns = [\n      col_value.replace('home', 'team').replace('away', 'opp') for \n        col_value in games_home_perspective.columns.values]\n\n    games_home_perspective['isHomeTeam'] = 1\n\n    # Get games table from away team perspective\n    games_away_perspective = games_for_stats.copy()\n\n    # Change column names so that \"opp\" is \"home\", \"team\" is \"away\"\n    games_away_perspective.columns = [\n      col_value.replace('home', 'opp').replace('away', 'team') for \n        col_value in games_away_perspective.columns.values]\n\n    games_away_perspective['isHomeTeam'] = 0\n\n    # Put together games from home/away perspective to get df w/ 1 row per team game\n    team_games = (pd.concat([\n      games_home_perspective,\n      games_away_perspective\n      ],\n      ignore_index = True)\n      )\n\n    # Copy over team box scores data to modify\n    team_game_stats = teamBoxScores.copy()\n\n    # Change column names to reflect these are all \"team\" stats - helps \n    # to differentiate from individual player stats if/when joining later\n    team_game_stats.columns = [\n      (col_value + 'Team') \n      if (col_value not in ['dailyDataDate', 'home', 'teamId', 'gamePk',\n        'gameDate', 'gameTimeUTC'])\n        else col_value\n      for col_value in team_game_stats.columns.values\n      ]\n\n    # Merge games table with team game stats\n    team_games_with_stats = pd.merge(\n      team_games,\n      team_game_stats.\n        # Drop some fields that are already present in team_games table\n        drop(['home', 'gameDate', 'gameTimeUTC'], axis = 1),\n      on = ['dailyDataDate', 'gamePk', 'teamId'],\n      # Doing this as 'inner' join excludes spring training games, postponed games,\n      # etc. from original games table, but this may be fine for purposes here \n      how = 'inner'\n      )\n\n    team_date_stats_agg = (team_games_with_stats.\n      groupby(['dailyDataDate', 'teamId', 'gameType', 'oppId', 'oppName'], \n        as_index = False).\n      agg(\n        numGamesTeam = ('gamePk', 'nunique'),\n        winsTeam = ('teamWinner', 'sum'),\n        lossesTeam = ('oppWinner', 'sum'),\n        runsScoredTeam = ('teamScore', 'sum'),\n        runsAllowedTeam = ('oppScore', 'sum')\n        )\n       )\n\n    # Prepare standings table for merge w/ player digital engagement data\n    # Pick only certain fields of interest from standings for merge\n    standings_selected_fields = (standings[['dailyDataDate', 'teamId', \n      'streakCode', 'divisionRank', 'leagueRank', 'wildCardRank', 'pct'\n      ]].\n      rename(columns = {'pct': 'winPct'})\n      )\n\n    # Change column names to reflect these are all \"team\" standings - helps \n    # to differentiate from player-related fields if/when joining later\n    standings_selected_fields.columns = [\n      (col_value + 'Team') \n      if (col_value not in ['dailyDataDate', 'teamId'])\n        else col_value\n      for col_value in standings_selected_fields.columns.values\n      ]\n\n    standings_selected_fields['streakLengthTeam'] = (\n      standings_selected_fields['streakCodeTeam'].\n        str.replace('W', '').\n        str.replace('L', '').\n        astype(float)\n        )\n\n    # Add fields to separate winning and losing streak from streak code\n    standings_selected_fields['winStreakTeam'] = np.where(\n      standings_selected_fields['streakCodeTeam'].str[0] == 'W',\n      standings_selected_fields['streakLengthTeam'],\n      np.nan\n      )\n\n    standings_selected_fields['lossStreakTeam'] = np.where(\n      standings_selected_fields['streakCodeTeam'].str[0] == 'L',\n      standings_selected_fields['streakLengthTeam'],\n      np.nan\n      )\n\n    standings_for_digital_engagement_merge = (pd.merge(\n      standings_selected_fields,\n      dates_with_info[['dailyDataDate', 'inSeason']],\n      on = ['dailyDataDate'],\n      how = 'left'\n      ).\n      # Limit down standings to only in season version\n      query(\"inSeason\").\n      # Drop fields no longer necessary (in derived values, etc.)\n      drop(['streakCodeTeam', 'streakLengthTeam', 'inSeason'], axis = 1).\n      reset_index(drop = True)\n      )\n\n    #### Merge together various data frames to add date, player, roster, and team info ####\n    # Copy over player engagement df to add various pieces to it\n\n    # remove chumajin\n    #player_engagement_with_info = nextDayPlayerEngagement.copy()\n    player_engagement_with_info = sample_sub.copy()\n\n\n    # Take \"row mean\" across targets to add (helps with studying all 4 targets at once)\n    \"\"\"\n    player_engagement_with_info['targetAvg'] = np.mean(\n      player_engagement_with_info[['target1', 'target2', 'target3', 'target4']],\n      axis = 1)\n    \"\"\"\n\n\n    # Merge in date information\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      dates_with_info[['dailyDataDate', 'date', 'year', 'month', 'inSeason',\n        'seasonPart']],\n      on = ['dailyDataDate'],\n      how = 'left'\n      )\n\n    # Merge in some player information\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      players[['playerId', 'playerName', 'DOB', 'mlbDebutDate', 'birthCity',\n        'birthStateProvince', 'birthCountry', 'primaryPositionName']],\n       on = ['playerId'],\n       how = 'left'\n       )\n\n\n    # Merge in some player roster information by date\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      (rosters[['dailyDataDate', 'playerId', 'statusCode', 'status', 'teamId']].\n        rename(columns = {\n          'statusCode': 'rosterStatusCode',\n          'status': 'rosterStatus',\n          'teamId': 'rosterTeamId'\n          })\n        ),\n      on = ['dailyDataDate', 'playerId'],\n      how = 'left'\n      )\n\n    # Merge in team name from player's roster team\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      (teams[['id', 'teamName']].\n        rename(columns = {\n          'id': 'rosterTeamId',\n          'teamName': 'rosterTeamName'\n          })\n        ),\n      on = ['rosterTeamId'],\n      how = 'left'\n      )\n\n    # Merge in some player game stats (previously aggregated) from that date\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      player_date_stats_agg,\n      on = ['dailyDataDate', 'playerId'],\n      how = 'left'\n      )\n\n    # Merge in team name from player's game team\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      (teams[['id', 'teamName']].\n        rename(columns = {\n          'id': 'gameTeamId',\n          'teamName': 'gameTeamName'\n          })\n        ),\n      on = ['gameTeamId'],\n      how = 'left'\n      )\n\n    # Merge in some team game stats/results (previously aggregated) from that date\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      team_date_stats_agg.rename(columns = {'teamId': 'gameTeamId'}),\n      on = ['dailyDataDate', 'gameTeamId'],\n      how = 'left'\n      )\n\n    # Merge in player transactions of note on that date\n\n    # Merge in some pieces of team standings (previously filter/processed) from that date\n    player_engagement_with_info = pd.merge(\n      player_engagement_with_info,\n      standings_for_digital_engagement_merge.\n        rename(columns = {'teamId': 'gameTeamId'}),\n      on = ['dailyDataDate', 'gameTeamId'],\n      how = 'left'\n      )\n\n    #display(player_engagement_with_info)\n    \n    return player_engagement_with_info\n","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:34.449147Z","iopub.execute_input":"2021-08-04T00:53:34.449422Z","iopub.status.idle":"2021-08-04T00:53:34.498534Z","shell.execute_reply.started":"2021-08-04T00:53:34.449396Z","shell.execute_reply":"2021-08-04T00:53:34.497605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model A : maybe I explained in chapter 2～4 score 1.3490","metadata":{}},{"cell_type":"code","source":"features3 = [#'dailyDataDate',\n    #'engagementMetricsDate',\n    #'playerId', 'target1','target2', 'target3', 'target4', 'targetAvg', \n    \n    #'date',\n    'year',\n    'month',\n    'inSeason',\n    'seasonPart',\n    'playerName',\n    'DOB',\n    'mlbDebutDate',\n     'birthCity',\n    'birthStateProvince',\n    'birthCountry',\n    'primaryPositionName',\n    'rosterStatusCode',\n    'rosterStatus',\n     'rosterTeamId',\n    'rosterTeamName', \n    'numGames',\n    'numTeams', \n    'gameTeamId',\n    'runsScored',\n    'homeRuns',\n    \n    'strikeOuts',\n    'baseOnBalls', \n    'hits',\n    'hitByPitch',\n    'atBats', \n    'caughtStealing',\n    'stolenBases',\n    'groundIntoDoublePlay',\n    'groundIntoTriplePlay',\n    'plateAppearances',\n     'totalBases', \n    'rbi', \n    'leftOnBase',\n   'sacBunts',\n    'sacFlies',\n     'gamesStartedPitching',\n    'runsPitching',\n    'homeRunsPitching',\n      'strikeOutsPitching',\n    'baseOnBallsPitching',\n    'hitsPitching',\n       'inningsPitchedAsFrac',\n    'earnedRuns',\n    'battersFaced',\n    'saves',\n    'blownSaves',\n    'pitchingGameScore',\n    'noHitter',\n    'gameTeamName',\n     'gameType',\n    'oppId',\n    'oppName',\n    'numGamesTeam',\n    'winsTeam',\n    'lossesTeam',\n    'runsScoredTeam',\n    'runsAllowedTeam', \n    'divisionRankTeam',\n    'leagueRankTeam', \n    'wildCardRankTeam', \n    'winPctTeam', \n    'winStreakTeam',\n    'lossStreakTeam']","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:34.505844Z","iopub.execute_input":"2021-08-04T00:53:34.506476Z","iopub.status.idle":"2021-08-04T00:53:34.516556Z","shell.execute_reply.started":"2021-08-04T00:53:34.506441Z","shell.execute_reply":"2021-08-04T00:53:34.515754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path3 = \"../input/mlbsharemodela\"\n\ntarget1_models3 = [pickle.load(open(os.path.join(path3,s), 'rb')) for s in os.listdir(path3) if \"target1\" in s]\ntarget2_models3 = [pickle.load(open(os.path.join(path3,s), 'rb')) for s in os.listdir(path3) if \"target2\" in s]\ntarget3_models3 = [pickle.load(open(os.path.join(path3,s), 'rb')) for s in os.listdir(path3) if \"target3\" in s]\ntarget4_models3 = [pickle.load(open(os.path.join(path3,s), 'rb')) for s in os.listdir(path3) if \"target4\" in s]\n\nallmodels3 = [target1_models3,target2_models3,target3_models3,target4_models3]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:34.51836Z","iopub.execute_input":"2021-08-04T00:53:34.518808Z","iopub.status.idle":"2021-08-04T00:53:43.714467Z","shell.execute_reply.started":"2021-08-04T00:53:34.518764Z","shell.execute_reply":"2021-08-04T00:53:43.713529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction3(models):\n    preds=[]\n    for model in models:\n        preds.append(model.predict(test_feats[features3]))\n    preds = np.mean(preds,axis=0)\n    preds = np.clip(preds,0,100)\n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:43.715865Z","iopub.execute_input":"2021-08-04T00:53:43.716212Z","iopub.status.idle":"2021-08-04T00:53:43.721974Z","shell.execute_reply.started":"2021-08-04T00:53:43.716178Z","shell.execute_reply":"2021-08-04T00:53:43.721008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model B \n\nIt is a model using features that are not explained\n\n(説明していない特徴量を使ったモデルです)","metadata":{}},{"cell_type":"code","source":"features = ['year',\n 'month',\n 'inSeason',\n 'seasonPart',\n 'playerName',\n 'DOB',\n 'mlbDebutDate',\n 'birthCity',\n 'birthStateProvince',\n 'birthCountry',\n 'primaryPositionName',\n 'rosterStatusCode',\n 'rosterStatus',\n 'rosterTeamId',\n 'rosterTeamName',\n 'numGames',\n 'numTeams',\n 'gameTeamId',\n 'runsScored',\n 'homeRuns',\n 'strikeOuts',\n 'baseOnBalls',\n 'hits',\n 'hitByPitch',\n 'atBats',\n 'caughtStealing',\n 'stolenBases',\n 'groundIntoDoublePlay',\n 'groundIntoTriplePlay',\n 'plateAppearances',\n 'totalBases',\n 'rbi',\n 'leftOnBase',\n 'sacBunts',\n 'sacFlies',\n 'gamesStartedPitching',\n 'runsPitching',\n 'homeRunsPitching',\n 'strikeOutsPitching',\n 'baseOnBallsPitching',\n 'hitsPitching',\n 'inningsPitchedAsFrac',\n 'earnedRuns',\n 'battersFaced',\n 'saves',\n 'blownSaves',\n 'pitchingGameScore',\n 'noHitter',\n 'gameTeamName',\n 'gameType',\n 'oppId',\n 'oppName',\n 'numGamesTeam',\n 'winsTeam',\n 'lossesTeam',\n 'runsScoredTeam',\n 'runsAllowedTeam',\n 'divisionRankTeam',\n 'leagueRankTeam',\n 'wildCardRankTeam',\n 'winPctTeam',\n 'winStreakTeam',\n 'lossStreakTeam',\n 'target1_mean',\n 'target2_mean',\n 'target3_mean',\n 'target4_mean',\n 'ct',\n 'Lag31_target1_median',\n 'Lag31_target1_max',\n 'Lag31_target2_median',\n 'Lag31_target2_max',\n 'Lag31_target3_median',\n 'Lag31_target3_max',\n 'Lag31_target4_median',\n 'Lag31_target4_max',\n 'Lag45_target1_median',\n 'Lag45_target1_max',\n 'Lag45_target2_median',\n 'Lag45_target2_max',\n 'Lag45_target3_median',\n 'Lag45_target3_max',\n 'Lag45_target4_median',\n 'Lag45_target4_max',\n 'Lag60_target1_median',\n 'Lag60_target1_max',\n 'Lag60_target2_median',\n 'Lag60_target2_max',\n 'Lag60_target3_median',\n 'Lag60_target3_max',\n 'Lag60_target4_median',\n 'Lag60_target4_max',\n 'Lag180_target1_median',\n 'Lag180_target1_max',\n 'Lag180_target2_median',\n 'Lag180_target2_max',\n 'Lag180_target3_median',\n 'Lag180_target3_max',\n 'Lag180_target4_median',\n 'Lag180_target4_max',\n 'Ability_target1_mean',\n 'Ability_target1_median',\n 'Ability_target1_max',\n 'Ability_target1_min',\n 'Ability_target1_std',\n 'Ability_target2_mean',\n 'Ability_target2_median',\n 'Ability_target2_max',\n 'Ability_target2_min',\n 'Ability_target2_std',\n 'Ability_target3_mean',\n 'Ability_target3_median',\n 'Ability_target3_max',\n 'Ability_target3_min',\n 'Ability_target3_std',\n 'Ability_target4_mean',\n 'Ability_target4_median',\n 'Ability_target4_max',\n 'Ability_target4_min',\n 'Ability_target4_std',\n 'Ability_targetAvg_mean',\n 'Ability_targetAvg_median',\n 'Ability_targetAvg_max',\n 'Ability_targetAvg_min',\n 'Ability_targetAvg_std']","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:43.723317Z","iopub.execute_input":"2021-08-04T00:53:43.723592Z","iopub.status.idle":"2021-08-04T00:53:43.738387Z","shell.execute_reply.started":"2021-08-04T00:53:43.723566Z","shell.execute_reply":"2021-08-04T00:53:43.737192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Load models","metadata":{}},{"cell_type":"code","source":"path = \"../input/optuna9\"\n\ntarget1_models = [pickle.load(open(os.path.join(path,s), 'rb')) for s in os.listdir(path) if \"target1\" in s]\ntarget2_models = [pickle.load(open(os.path.join(path,s), 'rb')) for s in os.listdir(path) if \"target2\" in s]\ntarget3_models = [pickle.load(open(os.path.join(path,s), 'rb')) for s in os.listdir(path) if \"target3\" in s]\ntarget4_models = [pickle.load(open(os.path.join(path,s), 'rb')) for s in os.listdir(path) if \"target4\" in s]\n\nallmodels = [target1_models,target2_models,target3_models,target4_models]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:43.739699Z","iopub.execute_input":"2021-08-04T00:53:43.740016Z","iopub.status.idle":"2021-08-04T00:53:51.975449Z","shell.execute_reply.started":"2021-08-04T00:53:43.739964Z","shell.execute_reply":"2021-08-04T00:53:51.974533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction(models):\n    preds=[]\n    for model in models:\n        preds.append(model.predict(test_feats[features]))\n    preds = np.mean(preds,axis=0)\n    preds = np.clip(preds,0,100)\n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:51.976608Z","iopub.execute_input":"2021-08-04T00:53:51.977071Z","iopub.status.idle":"2021-08-04T00:53:51.98152Z","shell.execute_reply.started":"2021-08-04T00:53:51.97703Z","shell.execute_reply":"2021-08-04T00:53:51.980771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model C ( I explained chapter 5 ) score : 1.3373","metadata":{}},{"cell_type":"code","source":"features2 = [#'dailyDataDate',\n    #'engagementMetricsDate',\n    #'playerId', 'target1','target2', 'target3', 'target4', 'targetAvg', \n    \n    #'date',\n    'year',\n    'month',\n    'inSeason',\n    'seasonPart',\n    'playerName',\n    'DOB',\n    'mlbDebutDate',\n     'birthCity',\n    'birthStateProvince',\n    'birthCountry',\n    'primaryPositionName',\n    'rosterStatusCode',\n    'rosterStatus',\n     'rosterTeamId',\n    'rosterTeamName', \n    'numGames',\n    'numTeams', \n    'gameTeamId',\n    'runsScored',\n    'homeRuns',\n    \n    'strikeOuts',\n    'baseOnBalls', \n    'hits',\n    'hitByPitch',\n    'atBats', \n    'caughtStealing',\n    'stolenBases',\n    'groundIntoDoublePlay',\n    'groundIntoTriplePlay',\n    'plateAppearances',\n     'totalBases', \n    'rbi', \n    'leftOnBase',\n   'sacBunts',\n    'sacFlies',\n     'gamesStartedPitching',\n    'runsPitching',\n    'homeRunsPitching',\n      'strikeOutsPitching',\n    'baseOnBallsPitching',\n    'hitsPitching',\n       'inningsPitchedAsFrac',\n    'earnedRuns',\n    'battersFaced',\n    'saves',\n    'blownSaves',\n    'pitchingGameScore',\n    'noHitter',\n    'gameTeamName',\n     'gameType',\n    'oppId',\n    'oppName',\n   # 'numGamesTeam',\n    'winsTeam',\n    'lossesTeam',\n    'runsScoredTeam',\n    'runsAllowedTeam', \n    'divisionRankTeam',\n    'leagueRankTeam', \n    'wildCardRankTeam', \n    'winPctTeam', \n    'winStreakTeam',\n    'lossStreakTeam',\n    'target1_mean', 'target2_mean', 'target3_mean',\n       'target4_mean', 'ct', 'Lag31_target1_median',\n       'Lag31_target2_median', 'Lag31_target3_median',\n       'Lag31_target4_median', 'Lag45_target1_median',\n       'Lag45_target2_median', 'Lag45_target3_median',\n       'Lag45_target4_median', 'Lag60_target1_median',\n       'Lag60_target2_median', 'Lag60_target3_median',\n       'Lag60_target4_median', 'Lag180_target1_median',\n       'Lag180_target2_median', 'Lag180_target3_median',\n       'Lag180_target4_median'\n]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:51.982613Z","iopub.execute_input":"2021-08-04T00:53:51.98304Z","iopub.status.idle":"2021-08-04T00:53:51.996923Z","shell.execute_reply.started":"2021-08-04T00:53:51.982973Z","shell.execute_reply":"2021-08-04T00:53:51.996172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path2 = \"../input/optuna16\"\n\ntarget1_models2 = [pickle.load(open(os.path.join(path2,s), 'rb')) for s in os.listdir(path2) if (\"target1\" in s) & ('numGamesTeam' in s)]\ntarget2_models2 = [pickle.load(open(os.path.join(path2,s), 'rb')) for s in os.listdir(path2) if (\"target2\" in s)  & ('numGamesTeam' in s)]\ntarget3_models2 = [pickle.load(open(os.path.join(path2,s), 'rb')) for s in os.listdir(path2) if (\"target3\" in s)  & ('numGamesTeam' in s)]\ntarget4_models2 = [pickle.load(open(os.path.join(path2,s), 'rb')) for s in os.listdir(path2) if (\"target4\" in s)  & ('numGamesTeam' in s)]\n\nallmodels2 = [target1_models2,target2_models2,target3_models2,target4_models2]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:51.997981Z","iopub.execute_input":"2021-08-04T00:53:51.998407Z","iopub.status.idle":"2021-08-04T00:53:58.356672Z","shell.execute_reply.started":"2021-08-04T00:53:51.998365Z","shell.execute_reply":"2021-08-04T00:53:58.355782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction2(models):\n    preds=[]\n    for model in models:\n        preds.append(model.predict(test_feats[features2]))\n    preds = np.mean(preds,axis=0)\n    preds = np.clip(preds,0,100)\n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:58.357794Z","iopub.execute_input":"2021-08-04T00:53:58.358198Z","iopub.status.idle":"2021-08-04T00:53:58.362373Z","shell.execute_reply.started":"2021-08-04T00:53:58.358169Z","shell.execute_reply":"2021-08-04T00:53:58.36161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model D (I explained in chapter 6) score 1.3256","metadata":{}},{"cell_type":"code","source":"path4 = \"../input/optuna25log\"\n\n\ntarget1_models4 = [pickle.load(open(os.path.join(path4,s), 'rb')) for s in os.listdir(path4) if (\"target1\" in s)]\ntarget2_models4 = [pickle.load(open(os.path.join(path4,s), 'rb')) for s in os.listdir(path4) if (\"target2\" in s)]\ntarget3_models4 = [pickle.load(open(os.path.join(path4,s), 'rb')) for s in os.listdir(path4) if (\"target3\" in s)]\ntarget4_models4 = [pickle.load(open(os.path.join(path4,s), 'rb')) for s in os.listdir(path4) if (\"target4\" in s)]\n\nallmodels4 = [target1_models4,target2_models4,target3_models4,target4_models4]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:53:58.363444Z","iopub.execute_input":"2021-08-04T00:53:58.363857Z","iopub.status.idle":"2021-08-04T00:54:08.745Z","shell.execute_reply.started":"2021-08-04T00:53:58.363814Z","shell.execute_reply":"2021-08-04T00:54:08.744026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The feature is that log is returned by np.power.\n\nnp.powerでlogを戻しているのが特徴です。","metadata":{}},{"cell_type":"code","source":"def prediction4(models):\n    preds=[]\n    for model in models:\n        preds.append(model.predict(test_feats[features2]))\n    preds = np.mean(preds,axis=0)\n    \n    preds = np.power(10,preds) \n    \n    preds = np.clip(preds,0,100)\n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:08.746263Z","iopub.execute_input":"2021-08-04T00:54:08.746581Z","iopub.status.idle":"2021-08-04T00:54:08.751954Z","shell.execute_reply.started":"2021-08-04T00:54:08.746549Z","shell.execute_reply":"2021-08-04T00:54:08.751154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model E : log learning by position. Pitcher, HD, and others. score 1.3250","metadata":{}},{"cell_type":"code","source":"def prediction22(models,test_feats):\n    preds=[]\n    for model in models:\n        preds.append(model.predict(test_feats[features2]))\n    preds = np.mean(preds,axis=0)\n    \n    preds = np.power(10,preds)\n    \n    preds = np.clip(preds,0,100)\n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:08.753216Z","iopub.execute_input":"2021-08-04T00:54:08.753496Z","iopub.status.idle":"2021-08-04T00:54:08.76568Z","shell.execute_reply.started":"2021-08-04T00:54:08.753467Z","shell.execute_reply":"2021-08-04T00:54:08.764443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def returnpreddf(test_feats2,allmodels2):\n    \n    indexes = test_feats2.index\n    \n    test_feats2 = test_feats2.reset_index(drop=True)\n\n    allpreds2=[]\n    for models in allmodels2:\n            allpreds2.append(prediction22(models,test_feats2))\n\n    preddf2 = pd.DataFrame(allpreds2)\n    preddf2 = preddf2.T\n    \n    preddf2[\"index\"] = indexes\n\n    \n    return preddf2","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:08.76728Z","iopub.execute_input":"2021-08-04T00:54:08.767696Z","iopub.status.idle":"2021-08-04T00:54:08.778253Z","shell.execute_reply.started":"2021-08-04T00:54:08.767653Z","shell.execute_reply":"2021-08-04T00:54:08.777346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path5 = \"../input/optuna32pitcher\"\n\n\ntarget1_models5 = [pickle.load(open(os.path.join(path5,s), 'rb')) for s in os.listdir(path5) if (\"target1\" in s)]\ntarget2_models5 = [pickle.load(open(os.path.join(path5,s), 'rb')) for s in os.listdir(path5) if (\"target2\" in s)]\ntarget3_models5 = [pickle.load(open(os.path.join(path5,s), 'rb')) for s in os.listdir(path5) if (\"target3\" in s)]\ntarget4_models5 = [pickle.load(open(os.path.join(path5,s), 'rb')) for s in os.listdir(path5) if (\"target4\" in s)]\n\nallmodels5 = [target1_models5,target2_models5,target3_models5,target4_models5]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:08.779482Z","iopub.execute_input":"2021-08-04T00:54:08.779752Z","iopub.status.idle":"2021-08-04T00:54:17.248403Z","shell.execute_reply.started":"2021-08-04T00:54:08.779725Z","shell.execute_reply":"2021-08-04T00:54:17.24735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path6 = \"../input/optuna32other\"\n\n\ntarget1_models6 = [pickle.load(open(os.path.join(path6,s), 'rb')) for s in os.listdir(path6) if (\"target1\" in s)]\ntarget2_models6 = [pickle.load(open(os.path.join(path6,s), 'rb')) for s in os.listdir(path6) if (\"target2\" in s)]\ntarget3_models6 = [pickle.load(open(os.path.join(path6,s), 'rb')) for s in os.listdir(path6) if (\"target3\" in s)]\ntarget4_models6 = [pickle.load(open(os.path.join(path6,s), 'rb')) for s in os.listdir(path6) if (\"target4\" in s)]\n\nallmodels6 = [target1_models6,target2_models6,target3_models6,target4_models6]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:17.250242Z","iopub.execute_input":"2021-08-04T00:54:17.250691Z","iopub.status.idle":"2021-08-04T00:54:26.86687Z","shell.execute_reply.started":"2021-08-04T00:54:17.250638Z","shell.execute_reply":"2021-08-04T00:54:26.865897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path7 = \"../input/optuna32hd\"\n\n\ntarget1_models7 = [pickle.load(open(os.path.join(path7,s), 'rb')) for s in os.listdir(path7) if (\"target1\" in s)]\ntarget2_models7 = [pickle.load(open(os.path.join(path7,s), 'rb')) for s in os.listdir(path7) if (\"target2\" in s)]\ntarget3_models7 = [pickle.load(open(os.path.join(path7,s), 'rb')) for s in os.listdir(path7) if (\"target3\" in s)]\ntarget4_models7 = [pickle.load(open(os.path.join(path7,s), 'rb')) for s in os.listdir(path7) if (\"target4\" in s)]\n\nallmodels7 = [target1_models7,target2_models7,target3_models7,target4_models7]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:26.868377Z","iopub.execute_input":"2021-08-04T00:54:26.868784Z","iopub.status.idle":"2021-08-04T00:54:27.740469Z","shell.execute_reply.started":"2021-08-04T00:54:26.868743Z","shell.execute_reply":"2021-08-04T00:54:27.739401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if 'kaggle_secrets' in sys.modules:  # only run while on Kaggle\n    import mlb\n\n    env = mlb.make_env()\n    iter_test = env.iter_test()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:27.744785Z","iopub.execute_input":"2021-08-04T00:54:27.745202Z","iopub.status.idle":"2021-08-04T00:54:27.818215Z","shell.execute_reply.started":"2021-08-04T00:54:27.745164Z","shell.execute_reply":"2021-08-04T00:54:27.817021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for (testdf, sample_sub) in iter_test:\n    \n\n    testdf = testdf.reset_index()\n    testdf = testdf.rename(columns={\"index\":\"date\"})\n\n    sample_sub2 = sample_sub.reset_index()\n    \n    ## adding test_feats if you want to see, look at the below test feats.###\n\n    test_feats = preparation(testdf,sample_sub2)\n    test_feats[\"rosterTeamId\"] = np.where(pd.isna(test_feats[\"rosterTeamId\"]),np.nan,test_feats[\"rosterTeamId\"])\n    \n   \n        \n    test_feats[\"dailyDataDate\"] = pd.to_datetime(test_feats[\"dailyDataDate\"], format=\"%Y%m%d\")\n    futureLAG[\"dailyDataDate\"] = pd.to_datetime(futureLAG[\"dailyDataDate\"], format=\"%Y%m%d\")\n\n    test_feats[\"playerId\"] = test_feats[\"playerId\"].astype(\"int\")\n    futureLAG[\"playerId\"] = futureLAG[\"playerId\"].astype(\"int\")\n    \n    test_feats = pd.merge(test_feats,futureLAG,on=[\"dailyDataDate\",\"playerId\"],how=\"left\")\n    \n     ### Fill in nan when there are not enough features in test_feats##\n\n\n    tcols = test_feats.columns[4:].to_list()\n\n    for a in features:\n        if np.isin(a,tcols) == False:\n            test_feats[a] = np.nan\n\n        #############Label encoding########################\n    \n    for col in cols:\n        \n        test_feats[col] = np.where(test_feats[col].isna(),\"NaN\",test_feats[col])\n        \n        with open(os.path.join(\"./\",col + '_encoder.txt'), 'rb') as f:\n              le = pickle.load(f)\n        test_feats[col] = le.transform(test_feats[col])\n    \n    #############Maybe I don't need it.########################\n    \n    for feature in features:\n        if test_feats[feature].dtype==\"object\":\n            test_feats[feature] = test_feats[feature].astype(\"float\")\n        \n\n  #### model A ####\n        \n    allpreds=[]\n    for models in allmodels:\n        allpreds.append(prediction(models))\n\n    preddf = pd.DataFrame(allpreds)\n    preddf = preddf.T\n\n\n    ##### model B #######\n\n    allpreds2=[]\n    for models in allmodels2:\n        allpreds2.append(prediction2(models))\n\n    tmpdf2 = pd.DataFrame(allpreds2)\n    tmpdf2 = tmpdf2.T\n    \n    \n   \n    ##### model C#######\n\n    allpreds3=[]\n    for models in allmodels3:\n        allpreds3.append(prediction3(models))\n\n    tmpdf3 = pd.DataFrame(allpreds3)\n    tmpdf3 = tmpdf3.T\n    \n    ##### model D ###log##\n    \n\n    allpreds4=[]\n    for models in allmodels4:\n        allpreds4.append(prediction4(models))\n\n    tmpdf4 = pd.DataFrame(allpreds4)\n    tmpdf4 = tmpdf4.T\n    \n    ##### model E pitcher #####\n    test_feats2 = test_feats[test_feats['primaryPositionName']==6]\n    preddf2 = returnpreddf(test_feats2,allmodels5)\n    \n\n    ##### model E hd #####\n    test_feats4 = test_feats[test_feats['primaryPositionName']==1]\n    preddf4 = returnpreddf(test_feats4,allmodels7)\n\n    ##### model E other #####\n    test_feats3 = test_feats[(test_feats['primaryPositionName']!=6)]\n    test_feats3 = test_feats3[(test_feats3['primaryPositionName']!=1)]\n    \n    preddf3 = returnpreddf(test_feats3,allmodels6)\n\n    #############################\n    \n        \n    preddf5 = pd.concat([preddf2,preddf3,preddf4])\n    \n    \n    preddf5 = preddf5.sort_values(\"index\").reset_index(drop=True)\n    \n    preddf5 = preddf5.drop(\"index\",axis=1)\n    \n    \n\n    ##### merge ########\n\n    ens = [preddf,tmpdf2,tmpdf3]\n    ens = np.mean(ens,axis=0)\n    preddf = pd.DataFrame(ens)\n    \n    ##### merge2 ########\n\n    ens2 = [preddf5,tmpdf4]\n    ens2 = np.mean(ens2,axis=0)\n    preddf6 = pd.DataFrame(ens2)\n\n    ##### merge3 ########\n\n    ens3 = [preddf,preddf6]\n    ens3 = np.mean(ens3,axis=0)\n    preddf = pd.DataFrame(ens3)\n    \n    \n     ### Shohei Otani ###\n    \n    tmpdf2 = preddf.copy()\n    \n    tmpdf2.columns = targets\n    tmpdf2[\"playerId\"] = test_feats[\"playerId\"]\n\n    tmpdf2 = pd.merge(tmpdf2,april,on=\"playerId\",how=\"left\")\n\n\n    for a in targets:\n        tmpdf2[a] = tmpdf2[a] - tmpdf2[a+\"_diff\"]\n        tmpdf2[a] = np.clip(tmpdf2[a],0,100)\n    tmpdf2 = tmpdf2[targets]\n    \n    preddf = tmpdf2.copy()\n    \n    \n    ### no hitter ###\n    playervalue = []\n\n    for num,a in enumerate(test_feats[\"noHitter\"]):\n        if a==1:\n\n            playervalue.append([100,62.182615,93.614439,100])\n\n        else:\n            playervalue.append([np.nan,np.nan,np.nan,np.nan])\n\n    playerdf = pd.DataFrame(playervalue)\n\n    playerdf[0] = np.where(pd.isna(playerdf[0]),preddf[targets[0]],playerdf[0])\n    playerdf[1] = np.where(pd.isna(playerdf[1]),preddf[targets[1]],playerdf[1])\n    playerdf[2] = np.where(pd.isna(playerdf[2]),preddf[targets[2]],playerdf[2])\n    playerdf[3] = np.where(pd.isna(playerdf[3]),preddf[targets[3]],playerdf[3])\n\n\n    preddf = playerdf.copy()\n    \n    \n    \n\n\n    ###### Clean columns ####\n\n    tmpdf = sample_sub.iloc[:,:1]\n    preddf = preddf.set_index(tmpdf.index)\n\n\n    tmpdf = pd.concat([tmpdf,preddf],axis=1)\n    tmpdf.columns = sample_sub.columns\n\n    # Submit \n    env.predict(tmpdf)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:54:27.81953Z","iopub.execute_input":"2021-08-04T00:54:27.819941Z","iopub.status.idle":"2021-08-04T00:55:41.251379Z","shell.execute_reply.started":"2021-08-04T00:54:27.819892Z","shell.execute_reply":"2021-08-04T00:55:41.250284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 8. About real submission","metadata":{}},{"cell_type":"markdown","source":" If submit is the feature amount mentioned in 5 of ↑, on 9/15, 31 days ago is about 8/15 and there is no correct answer, so 31-day shift data cannot be used. Create a model by creating shift data 47 days ago. * Created from the data from the place where there is a correct answer up to 7/31 47 days before 9/16 (I put a margin for some reason).\n The first submission uses the 47-day shift data without correction for stable submit. The second submission created 15-day shift data, 31-day shift data, and 47-day shift data, respectively, and submitted it as if changing the model when the date (8/1,8/16,9/1) came. I've used train_updata.csv fully, so I can only believe the actual score without submission error!","metadata":{}},{"cell_type":"markdown","source":"submitは↑の5で述べた特徴量だと、9/15日は、31日前が8/15くらいで正解がないので、31日シフトデータは使用できず。\n47日前シフトデータを作成して、モデル作成。 ※ 9/16日(マージンをなぜか1日入れてしまった。)の47日前の7/31までの正解があるところからデータから作成。\n\n1つ目のsubmission1その47日シフトデータを使用(補正無しの安定version)。\n2つ目のsubmission2は15日シフトデータ、31日シフトデータ、47日シフトデータをそれぞれ作成し、日付(8/1,8/16,9/1)になったら、モデルを変えるみたいな感じでsubmitしました(さらに補正あり)。\ntrain_updata.csvをフル使用したので、実際のスコアは信じるのみです。submission error起こしてたらout・・・","metadata":{}},{"cell_type":"markdown","source":"# 9. A postscript","metadata":{}},{"cell_type":"markdown","source":"Thank you for reading to the end. It was difficult to explain and it became long. I'm sorry it's hard to read.\n\nI've done a lot of debugging in the last week, but I'm still afraid of submission errors.\nBut I enjoyed it anyway. Thank you so much for everyone!\n\nI hope your good luck in this competition!","metadata":{}},{"cell_type":"markdown","source":"最後まで読んでもらってありがとうございます。説明が難しくて、長くなりました。読みづらくてすみません。\n\n最後の1週間はデバッグをたくさんしましたが、それでも、submission errorを恐れています。\nけど、どちらにしても楽しめました。本当に皆様ありがとうございました！\n\n皆様の幸運をお祈りしています。","metadata":{}}]}