{"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":"Credit to @columbia2131 - I started with his notebook and then added an external data set with descriptive statistics of the targets for each player.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"## About Dataset","metadata":{}},{"cell_type":"markdown","source":"generated by the code below","metadata":{}},{"cell_type":"code","source":"%%capture\n\"\"\"\n!pip install pandarallel \n\nimport gc\n\nimport numpy as np\nimport pandas as pd\nfrom pathlib import Path\n\nfrom pandarallel import pandarallel\npandarallel.initialize()\n\nBASE_DIR = Path('../input/mlb-player-digital-engagement-forecasting')\ntrain = pd.read_csv(BASE_DIR / 'train.csv')\n\nnull = np.nan\ntrue = True\nfalse = False\n\nfor col in train.columns:\n\n    if col == 'date': continue\n\n    _index = train[col].notnull()\n    train.loc[_index, col] = train.loc[_index, col].parallel_apply(lambda x: eval(x))\n\n    outputs = []\n    for index, date, record in train.loc[_index, ['date', col]].itertuples():\n        _df = pd.DataFrame(record)\n        _df['index'] = index\n        _df['date'] = date\n        outputs.append(_df)\n\n    outputs = pd.concat(outputs).reset_index(drop=True)\n\n    outputs.to_csv(f'{col}_train.csv', index=False)\n    outputs.to_pickle(f'{col}_train.pkl')\n\n    del outputs\n    del train[col]\n    gc.collect()\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-06-18T18:09:59.864312Z","iopub.execute_input":"2021-06-18T18:09:59.865043Z","iopub.status.idle":"2021-06-18T18:09:59.870421Z","shell.execute_reply.started":"2021-06-18T18:09:59.865005Z","shell.execute_reply":"2021-06-18T18:09:59.869788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## DATA PREPARATION","metadata":{"execution":{"iopub.status.busy":"2021-06-16T09:14:33.869464Z","iopub.execute_input":"2021-06-16T09:14:33.869905Z","iopub.status.idle":"2021-06-16T09:14:33.874766Z","shell.execute_reply.started":"2021-06-16T09:14:33.869879Z","shell.execute_reply":"2021-06-16T09:14:33.873097Z"}}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom pathlib import Path\nfrom sklearn.metrics import mean_absolute_error\nfrom datetime import timedelta\nfrom functools import reduce\nfrom tqdm import tqdm\nimport lightgbm as lgbm\nimport mlb\nimport gc","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:05.157826Z","iopub.execute_input":"2021-06-29T18:36:05.158681Z","iopub.status.idle":"2021-06-29T18:36:07.773621Z","shell.execute_reply.started":"2021-06-29T18:36:05.158555Z","shell.execute_reply":"2021-06-29T18:36:07.771964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BASE_DIR = Path('../input/mlb-player-digital-engagement-forecasting')\nTRAIN_DIR = Path('../input/mlb-pdef-train-dataset')","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:07.775729Z","iopub.execute_input":"2021-06-29T18:36:07.776186Z","iopub.status.idle":"2021-06-29T18:36:07.781607Z","shell.execute_reply.started":"2021-06-29T18:36:07.776143Z","shell.execute_reply":"2021-06-29T18:36:07.780299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"players = pd.read_csv(BASE_DIR / 'players.csv')\n\nrosters = pd.read_pickle(TRAIN_DIR / 'rosters_train.pkl')\ntargets = pd.read_pickle(TRAIN_DIR / 'nextDayPlayerEngagement_train.pkl')\nscores = pd.read_pickle(TRAIN_DIR / 'playerBoxScores_train.pkl')\nscores = scores.groupby(['playerId', 'date']).sum().reset_index()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:07.783665Z","iopub.execute_input":"2021-06-29T18:36:07.784377Z","iopub.status.idle":"2021-06-29T18:36:13.101520Z","shell.execute_reply.started":"2021-06-29T18:36:07.784328Z","shell.execute_reply":"2021-06-29T18:36:13.100430Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"targets_id = ['playerId','date']\nTGTCOLS = ['target1', 'target2', 'target3', 'target4']\nrosters_id = ['playerId']\nrosters_cat = [\"statusCode\",\"status\"]\n\n\npscores_id = [\"playerId\", 'teamId'] #, \"gamePk\"\npscores_cat = [\"jerseyNum\",\"positionCode\",\"positionName\",\"positionType\"]\npscores_num = ['home', \n               'gamesPlayedBatting', 'flyOuts', 'groundOuts', 'runsScored', 'doubles', 'triples', \n               'homeRuns', 'strikeOuts', 'baseOnBalls', 'intentionalWalks', 'hits', 'hitByPitch', \n               'atBats', 'caughtStealing', 'stolenBases', 'groundIntoDoublePlay', 'groundIntoTriplePlay', \n               'plateAppearances', 'totalBases', 'rbi', 'leftOnBase', 'sacBunts', 'sacFlies', \n               'catchersInterference', 'pickoffs', 'gamesPlayedPitching', 'gamesStartedPitching', \n               'completeGamesPitching', 'shutoutsPitching', 'winsPitching', 'lossesPitching', 'flyOutsPitching', \n               'airOutsPitching', 'groundOutsPitching', \n               'runsPitching', 'doublesPitching', 'triplesPitching', 'homeRunsPitching', 'strikeOutsPitching', \n               'baseOnBallsPitching', 'intentionalWalksPitching', 'hitsPitching', 'hitByPitchPitching', \n               'atBatsPitching', 'caughtStealingPitching', 'stolenBasesPitching', 'inningsPitched', \n               'saveOpportunities', 'earnedRuns', 'battersFaced', 'outsPitching', 'pitchesThrown', \n               'balls', 'strikes', 'hitBatsmen', 'balks', 'wildPitches', 'pickoffsPitching', 'rbiPitching', \n               'gamesFinishedPitching', 'inheritedRunners', 'inheritedRunnersScored', 'catchersInterferencePitching', \n               'sacBuntsPitching', 'sacFliesPitching', 'saves', 'holds', 'blownSaves', 'assists', \n               'putOuts', 'errors', 'chances']\n\nstats_cols = ['target1_mean','target1_median','target1_std','target1_min','target1_max',\n              'target1_prob',\n              'target2_mean','target2_median','target2_std','target2_min','target2_max',\n              'target2_prob',\n              'target3_mean','target3_median','target3_std','target3_min',\n              'target3_max','target3_prob',\n              'target4_mean','target4_median','target4_std',\n              'target4_min','target4_max','target4_prob']\n#\nfeature_col = pscores_num + stats_cols","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:33.847584Z","iopub.execute_input":"2021-06-29T18:36:33.847971Z","iopub.status.idle":"2021-06-29T18:36:33.859224Z","shell.execute_reply.started":"2021-06-29T18:36:33.847940Z","shell.execute_reply":"2021-06-29T18:36:33.857811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"player_target_stats = pd.read_csv(\"../input/player-target-stats/player_target_stats.csv\")\ndata_names=player_target_stats.columns.values.tolist()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:34.980846Z","iopub.execute_input":"2021-06-29T18:36:34.981323Z","iopub.status.idle":"2021-06-29T18:36:35.014760Z","shell.execute_reply.started":"2021-06-29T18:36:34.981286Z","shell.execute_reply":"2021-06-29T18:36:35.013383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creat dataset\ntrain = targets[targets_id + TGTCOLS]\ntrain = train.merge(rosters[rosters_id + rosters_cat + [\"date\"]], \n                    on=['playerId', 'date'], how='left')\ntrain = train.merge(scores[pscores_id  + pscores_num  + [\"date\"]], \n                    on=['playerId', 'date'], how='left')\ntrain = train.merge(player_target_stats, how='inner', left_on=[\"playerId\"],right_on=[\"playerId\"])","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:35.888782Z","iopub.execute_input":"2021-06-29T18:36:35.891231Z","iopub.status.idle":"2021-06-29T18:36:44.114469Z","shell.execute_reply.started":"2021-06-29T18:36:35.891178Z","shell.execute_reply":"2021-06-29T18:36:44.113330Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nX = train[feature_col].fillna(0.).values\ny = train[TGTCOLS].values","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:45.219375Z","iopub.execute_input":"2021-06-29T18:36:45.219776Z","iopub.status.idle":"2021-06-29T18:36:50.121250Z","shell.execute_reply.started":"2021-06-29T18:36:45.219745Z","shell.execute_reply":"2021-06-29T18:36:50.119829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## MODEL","metadata":{}},{"cell_type":"code","source":"import 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","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:36:55.322659Z","iopub.execute_input":"2021-06-29T18:36:55.323058Z","iopub.status.idle":"2021-06-29T18:37:01.667620Z","shell.execute_reply.started":"2021-06-29T18:36:55.323008Z","shell.execute_reply":"2021-06-29T18:37:01.666430Z"},"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    nh = 50\n    x = L.Dense(nh, activation=\"relu\", name=\"d1\")(inp)\n    x = L.Dense(nh, activation=\"relu\", name=\"d2\")(x)\n    #x = L.Dense(nh, activation=\"relu\", name=\"d3\")(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=\"adam\")\n    return model","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:37:01.669146Z","iopub.execute_input":"2021-06-29T18:37:01.669443Z","iopub.status.idle":"2021-06-29T18:37:01.680034Z","shell.execute_reply.started":"2021-06-29T18:37:01.669413Z","shell.execute_reply":"2021-06-29T18:37:01.678930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net = make_model(X.shape[1])\nprint(net.summary())","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:37:01.681648Z","iopub.execute_input":"2021-06-29T18:37:01.681940Z","iopub.status.idle":"2021-06-29T18:37:01.818114Z","shell.execute_reply.started":"2021-06-29T18:37:01.681912Z","shell.execute_reply":"2021-06-29T18:37:01.817102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net.fit(X, y, batch_size=30_000, epochs=5)\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:39:12.064540Z","iopub.execute_input":"2021-06-29T18:39:12.065169Z","iopub.status.idle":"2021-06-29T18:39:30.043592Z","shell.execute_reply.started":"2021-06-29T18:39:12.065126Z","shell.execute_reply":"2021-06-29T18:39:30.042770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Inference","metadata":{}},{"cell_type":"code","source":"null = np.nan\ntrue = True\nfalse = False\n\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, sample_prediction_df) in iter_test: # make predictions here\n    \n    sample_prediction_df = sample_prediction_df.reset_index(drop=True)\n    \n    # creat dataset\n    sample_prediction_df['playerId'] = sample_prediction_df['date_playerId']\\\n                                        .map(lambda x: int(x.split('_')[1]))\n    # Dealing with missing values\n    if test_df['rosters'].iloc[0] == test_df['rosters'].iloc[0]:\n        test_rosters = pd.DataFrame(eval(test_df['rosters'].iloc[0]))\n    else:\n        test_rosters = pd.DataFrame({'playerId': sample_prediction_df['playerId']})\n        for col in rosters.columns:\n            if col == 'playerId': continue\n            test_rosters[col] = np.nan\n            \n    if test_df['playerBoxScores'].iloc[0] == test_df['playerBoxScores'].iloc[0]:\n        test_scores = pd.DataFrame(eval(test_df['playerBoxScores'].iloc[0]))\n    else:\n        test_scores = pd.DataFrame({'playerId': sample_prediction_df['playerId']})\n        for col in scores.columns:\n            if col == 'playerId': continue\n            test_scores[col] = np.nan\n    test_scores = test_scores.groupby('playerId').sum().reset_index()\n    test = sample_prediction_df[['playerId']].copy()\n    test = test.merge(test_rosters[rosters_id + rosters_cat], on='playerId', how='left')\n    test = test.merge(test_scores[pscores_id  + pscores_num], on='playerId', how='left')\n    test = test.merge(player_target_stats, how='inner', left_on=[\"playerId\"],right_on=[\"playerId\"])\n    \n    Xe = test[feature_col].fillna(0.).values\n    pe = net.predict(Xe)\n    pe = np.clip(pe, 0, 100)\n    \n    # predict\n    # to come...\n    \n    # merge submission\n    sample_prediction_df[TGTCOLS] = pe\n    sample_prediction_df = sample_prediction_df.fillna(0.)\n    del sample_prediction_df['playerId']\n    \n    env.predict(sample_prediction_df)","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:37:37.453238Z","iopub.execute_input":"2021-06-29T18:37:37.453667Z","iopub.status.idle":"2021-06-29T18:37:40.960635Z","shell.execute_reply.started":"2021-06-29T18:37:37.453630Z","shell.execute_reply":"2021-06-29T18:37:40.959448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_prediction_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:38:00.456409Z","iopub.execute_input":"2021-06-29T18:38:00.456822Z","iopub.status.idle":"2021-06-29T18:38:00.473256Z","shell.execute_reply.started":"2021-06-29T18:38:00.456787Z","shell.execute_reply":"2021-06-29T18:38:00.472156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_prediction_df.max()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T18:38:33.771954Z","iopub.execute_input":"2021-06-29T18:38:33.772334Z","iopub.status.idle":"2021-06-29T18:38:33.783692Z","shell.execute_reply.started":"2021-06-29T18:38:33.772303Z","shell.execute_reply":"2021-06-29T18:38:33.782394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}