{"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":"code","source":"import pandas as pd\nimport numpy as np\nfrom datetime import timedelta\nfrom tqdm import tqdm\nimport gc\nfrom functools import reduce\nfrom sklearn.model_selection import StratifiedKFold\nimport tensorflow as tf\nimport tensorflow.keras.layers as L\nimport tensorflow.keras.models as M\nfrom sklearn.metrics import mean_absolute_error, mean_squared_error\nfrom tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\nfrom keras import optimizers\n\nimport mlb\n\nROOT_DIR = \"../input/mlb-player-digital-engagement-forecasting\"\nTGTCOLS = [\"target1\",\"target2\",\"target3\",\"target4\"]\nLAGS = list(range(1,18))\nFECOLS = [f\"{col}_{lag}\" for lag in reversed(LAGS) for col in TGTCOLS]","metadata":{"execution":{"iopub.status.busy":"2021-06-21T08:35:24.128361Z","iopub.execute_input":"2021-06-21T08:35:24.128702Z","iopub.status.idle":"2021-06-21T08:35:24.137373Z","shell.execute_reply.started":"2021-06-21T08:35:24.128674Z","shell.execute_reply":"2021-06-21T08:35:24.136084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LAGS","metadata":{"execution":{"iopub.status.busy":"2021-06-21T08:22:16.882078Z","iopub.execute_input":"2021-06-21T08:22:16.882482Z","iopub.status.idle":"2021-06-21T08:22:16.891461Z","shell.execute_reply.started":"2021-06-21T08:22:16.882435Z","shell.execute_reply":"2021-06-21T08:22:16.890091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def flatten(df, col):\n    du = (df.pivot(index=\"playerId\", columns=\"EvalDate\", \n               values=col).add_prefix(f\"{col}_\").\n      rename_axis(None, axis=1).reset_index())\n    return du\n\ndef reducer(left, right):\n    return left.merge(right, on=\"playerId\")\n\ndef dataframe(dataframe, col, bool_in=False):\n    tp = dataframe.loc[ ~dataframe[col].isnull() ,[col]].copy()\n    dataframe.drop(col, axis=1, inplace=True)\n    \n    tp[col] = tp[col].str.replace(\"null\",'\"\"')\n    if bool_in:\n        tp[col] = tp[col].str.replace(\"false\",'\"False\"')\n        tp[col] = tp[col].str.replace(\"true\",'\"True\"')\n    tp[col] = tp[col].apply(lambda x: eval(x) )\n    a = tp[col].sum()\n    gc.collect()\n    return pd.DataFrame(a)\n\ndef train_lag(df, lag=1):\n    dp = df[[\"playerId\",\"EvalDate\"]+TGTCOLS].copy()\n    dp[\"EvalDate\"] = dp[\"EvalDate\"] + timedelta(days=lag) \n    df = df.merge(dp, on=[\"playerId\", \"EvalDate\"], suffixes=[\"\",f\"_{lag}\"], how=\"left\")\n    return df\n\ndef test_lag(sub):\n    sub[\"playerId\"] = sub[\"date_playerId\"].apply(lambda s: int(  s.split(\"_\")[1]  ) )\n    assert sub.date.nunique() == 1\n    dte = sub[\"date\"].unique()[0]\n    \n    eval_dt = pd.to_datetime(dte, format=\"%Y%m%d\")\n    dtes = [eval_dt + timedelta(days=-k) for k in LAGS]\n    mp_dtes = {eval_dt + timedelta(days=-k):k for k in LAGS}\n    \n    sl = LAST.loc[LAST.EvalDate.between(dtes[-1], dtes[0]), [\"EvalDate\",\"playerId\"]+TGTCOLS].copy()\n    sl[\"EvalDate\"] = sl[\"EvalDate\"].map(mp_dtes)\n    du = [flatten(sl, col) for col in TGTCOLS]\n    du = reduce(reducer, du)\n    return du, eval_dt","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:09:07.990124Z","iopub.execute_input":"2021-06-21T05:09:07.990497Z","iopub.status.idle":"2021-06-21T05:09:08.00825Z","shell.execute_reply.started":"2021-06-21T05:09:07.990467Z","shell.execute_reply":"2021-06-21T05:09:08.007343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# tr = pd.read_csv(f\"{ROOT_DIR}/train.csv\")\ntr = pd.read_csv(\"../input/mlb-data/target.csv\")\nprint(tr.shape)\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:09:08.803678Z","iopub.execute_input":"2021-06-21T05:09:08.804094Z","iopub.status.idle":"2021-06-21T05:09:11.295938Z","shell.execute_reply.started":"2021-06-21T05:09:08.804062Z","shell.execute_reply":"2021-06-21T05:09:11.295009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr[\"EvalDate\"] = pd.to_datetime(tr[\"EvalDate\"])\ntr[\"EvalDate\"] = tr[\"EvalDate\"] + timedelta(days=-1)\ntr[\"EvalYear\"] = tr[\"EvalDate\"].dt.year\n\nMED_DF = tr.groupby([\"playerId\",\"EvalYear\"])[TGTCOLS].median().reset_index()\nMEDCOLS = [\"tgt1_med\",\"tgt2_med\", \"tgt3_med\", \"tgt4_med\"]\nMED_DF.columns = [\"playerId\",\"EvalYear\"] + MEDCOLS","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:09:11.297188Z","iopub.execute_input":"2021-06-21T05:09:11.297585Z","iopub.status.idle":"2021-06-21T05:09:12.594176Z","shell.execute_reply.started":"2021-06-21T05:09:11.297555Z","shell.execute_reply":"2021-06-21T05:09:12.593071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MED_DF.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:09:12.596005Z","iopub.execute_input":"2021-06-21T05:09:12.596295Z","iopub.status.idle":"2021-06-21T05:09:12.616665Z","shell.execute_reply.started":"2021-06-21T05:09:12.596266Z","shell.execute_reply":"2021-06-21T05:09:12.615359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for lag in tqdm(LAGS):\n    tr = train_lag(tr, lag=lag)\n    gc.collect()\n\n\ntr = tr.sort_values(by=[\"playerId\", \"EvalDate\"])\nprint(tr.shape)\ntr = tr.dropna()\nprint(tr.shape)\ntr = tr.merge(MED_DF, on=[\"playerId\",\"EvalYear\"])\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:09:12.618067Z","iopub.execute_input":"2021-06-21T05:09:12.618353Z","iopub.status.idle":"2021-06-21T05:10:20.653508Z","shell.execute_reply.started":"2021-06-21T05:09:12.618326Z","shell.execute_reply":"2021-06-21T05:10:20.652705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:10:20.654949Z","iopub.execute_input":"2021-06-21T05:10:20.655354Z","iopub.status.idle":"2021-06-21T05:10:20.685543Z","shell.execute_reply.started":"2021-06-21T05:10:20.655327Z","shell.execute_reply":"2021-06-21T05:10:20.684509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = tr[FECOLS+MEDCOLS].values\ny = tr[TGTCOLS].values\ncl = tr[\"playerId\"].values\n\nNFOLDS = 5\nskf = StratifiedKFold(n_splits=NFOLDS)\nfolds = skf.split(X, cl)\nfolds = list(folds)","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:10:20.687477Z","iopub.execute_input":"2021-06-21T05:10:20.688008Z","iopub.status.idle":"2021-06-21T05:10:26.894826Z","shell.execute_reply.started":"2021-06-21T05:10:20.68795Z","shell.execute_reply":"2021-06-21T05:10:26.893876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:10:26.896316Z","iopub.execute_input":"2021-06-21T05:10:26.896773Z","iopub.status.idle":"2021-06-21T05:10:26.904337Z","shell.execute_reply.started":"2021-06-21T05:10:26.896732Z","shell.execute_reply":"2021-06-21T05:10:26.903046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_model(n_in):\n    inp = L.Input(name=\"inputs\", shape=(n_in,))\n    x = L.Dense(50, activation=\"relu\", name=\"d3\")(inp)\n#     x = L.Dropout(0.2)(x)\n    x = L.Dense(50, activation=\"relu\", name=\"d4\")(x)\n#     x = L.Dropout(0.2)(x)\n    preds = L.Dense(4, activation=\"linear\", name=\"preds\")(x)\n    \n    model = M.Model(inp, preds, name=\"ANN\")\n    model.compile(loss=\"mean_absolute_error\", optimizer=optimizers.Adamax(lr=0.001, decay=1e-3))\n    return model\nmodel = make_model(X.shape[1])","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:10:26.906593Z","iopub.execute_input":"2021-06-21T05:10:26.906899Z","iopub.status.idle":"2021-06-21T05:10:27.043456Z","shell.execute_reply.started":"2021-06-21T05:10:26.90687Z","shell.execute_reply":"2021-06-21T05:10:27.042383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:10:27.045294Z","iopub.execute_input":"2021-06-21T05:10:27.045718Z","iopub.status.idle":"2021-06-21T05:10:27.056325Z","shell.execute_reply.started":"2021-06-21T05:10:27.045674Z","shell.execute_reply":"2021-06-21T05:10:27.055191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"oof = np.zeros(y.shape)\nnets = []\nEPOCHS  = 100\nfor idx in range(NFOLDS):\n    print(\"FOLD:\", idx)\n    tr_idx, val_idx = folds[idx]\n    ckpt = ModelCheckpoint(f\"w{idx}.h5\", monitor='val_loss', verbose=1, save_best_only=True,mode='min')\n    reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,patience=3, min_lr=0.0005)\n    es = EarlyStopping(monitor='val_loss', patience=6)\n    reg = make_model(X.shape[1])\n    reg.fit(X[tr_idx], y[tr_idx], epochs=EPOCHS, batch_size=20_000, \n            validation_data=(X[val_idx], y[val_idx]),\n            verbose=1, callbacks=[ckpt, reduce_lr, es])\n    reg.load_weights(f\"w{idx}.h5\")\n    oof[val_idx] = reg.predict(X[val_idx], batch_size=20_000, verbose=1)\n    nets.append(reg)\n    gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:10:27.057857Z","iopub.execute_input":"2021-06-21T05:10:27.058533Z","iopub.status.idle":"2021-06-21T05:12:55.554287Z","shell.execute_reply.started":"2021-06-21T05:10:27.0585Z","shell.execute_reply":"2021-06-21T05:12:55.553079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"oof.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:12:55.556712Z","iopub.execute_input":"2021-06-21T05:12:55.557151Z","iopub.status.idle":"2021-06-21T05:12:55.564239Z","shell.execute_reply.started":"2021-06-21T05:12:55.557108Z","shell.execute_reply":"2021-06-21T05:12:55.563001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mae = mean_absolute_error(y, oof)\nmse = mean_squared_error(y, oof, squared=False)\nprint(\"mae:\", mae)\nprint(\"mse:\", mse)","metadata":{"execution":{"iopub.status.busy":"2021-06-21T05:12:55.565811Z","iopub.execute_input":"2021-06-21T05:12:55.566247Z","iopub.status.idle":"2021-06-21T05:12:55.809344Z","shell.execute_reply.started":"2021-06-21T05:12:55.566205Z","shell.execute_reply":"2021-06-21T05:12:55.808288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from sklearn.model_selection import StratifiedKFold\n# from sklearn.svm import SVR\n# from sklearn.metrics import mean_squared_error\n    \n\n# def rmse_score(y_true,y_pred):\n#     return np.sqrt(mean_squared_error(y_true,y_pred))\n\n# def get_preds_svm(X,y,nfolds=5,C=10,kernel='rbf'):\n#     scores = list()\n#     preds = np.zeros(y.shape)\n    \n#     for idx in range(NFOLDS):\n#         tr_idx, val_idx = folds[idx]\n#         model = SVR(C=C,kernel=kernel,gamma='auto')\n        \n#         model.fit(X[tr_idx],y[tr_idx])\n#         prediction = model.predict(X[val_idx])\n#         score = rmse_score(prediction,y[val_idx])\n#         print(f'Fold {idx} , rmse score: {score}')\n#         scores.append(score)\n#         preds[val_idx] += prediction\n#         gc.collect()\n        \n#     print(\"mean rmse\",np.mean(scores))\n#     return np.array(preds)/nfolds","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# svm_preds1 = get_preds_svm(X, y[:, 0])\n# svm_preds2 = get_preds_svm(X, y[:, 1])\n# svm_preds3 = get_preds_svm(X, y[:, 2])\n# svm_preds4 = get_preds_svm(X, y[:, 3])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bound_dt = pd.to_datetime(\"2021-01-01\")\nLAST = tr.loc[tr.EvalDate>bound_dt].copy()","metadata":{"execution":{"iopub.status.busy":"2021-06-20T18:07:34.545825Z","iopub.execute_input":"2021-06-20T18:07:34.546269Z","iopub.status.idle":"2021-06-20T18:07:34.799194Z","shell.execute_reply.started":"2021-06-20T18:07:34.546233Z","shell.execute_reply":"2021-06-20T18:07:34.797869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LAST_MED_DF = MED_DF.loc[MED_DF.EvalYear==2021].copy()\nLAST_MED_DF.drop(\"EvalYear\", axis=1, inplace=True)\ndel tr","metadata":{"execution":{"iopub.status.busy":"2021-06-20T18:07:37.70766Z","iopub.execute_input":"2021-06-20T18:07:37.708258Z","iopub.status.idle":"2021-06-20T18:07:37.722413Z","shell.execute_reply.started":"2021-06-20T18:07:37.708219Z","shell.execute_reply":"2021-06-20T18:07:37.721271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LAST.shape, LAST_MED_DF.shape, MED_DF.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-20T18:07:38.786843Z","iopub.execute_input":"2021-06-20T18:07:38.787262Z","iopub.status.idle":"2021-06-20T18:07:38.793614Z","shell.execute_reply.started":"2021-06-20T18:07:38.787229Z","shell.execute_reply":"2021-06-20T18:07:38.792785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FE = []; SUB = [];\nenv = mlb.make_env() # initialize the environment\niter_test = env.iter_test() # iterator which loops over each date in test set\n\nfor (test_df, sub) in iter_test:\n    # Features computation at Evaluation Date\n    sub = sub.reset_index()\n    sub_fe, eval_dt = test_lag(sub)\n    sub_fe = sub_fe.merge(LAST_MED_DF, on=\"playerId\", how=\"left\")\n    sub_fe = sub_fe.fillna(0.)\n    \n    _preds = 0.\n    for reg in nets:\n        _preds += reg.predict(sub_fe[FECOLS + MEDCOLS]) / NFOLDS\n    sub_fe[TGTCOLS] = np.clip(_preds, 0, 100)\n    sub.drop([\"date\"]+TGTCOLS, axis=1, inplace=True)\n    sub = sub.merge(sub_fe[[\"playerId\"]+TGTCOLS], on=\"playerId\", how=\"left\")\n    sub.drop(\"playerId\", axis=1, inplace=True)\n    sub = sub.fillna(0.)\n    # Submit\n    env.predict(sub)\n    # Update Available information\n    sub_fe[\"EvalDate\"] = eval_dt\n    #sub_fe.drop(MEDCOLS, axis=1, inplace=True)\n    LAST = LAST.append(sub_fe)\n    LAST = LAST.drop_duplicates(subset=[\"EvalDate\",\"playerId\"], keep=\"last\")","metadata":{"execution":{"iopub.status.busy":"2021-06-20T18:07:39.71648Z","iopub.execute_input":"2021-06-20T18:07:39.717018Z","iopub.status.idle":"2021-06-20T18:07:47.945782Z","shell.execute_reply.started":"2021-06-20T18:07:39.716983Z","shell.execute_reply":"2021-06-20T18:07:47.944744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}