{"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\nimport gc\nimport tensorflow as tf\n\nfrom matplotlib import pyplot as plt \n\nfrom tensorflow.keras import Model, Input\nfrom tensorflow.keras.layers import Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom tensorflow.keras.models import load_model\n\nfrom sklearn.model_selection import TimeSeriesSplit\nfrom sklearn.preprocessing import StandardScaler\n\nfrom datetime import datetime, timedelta\nfrom tqdm.auto import tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv('../input/mlb-player-digital-engagement-forecasting/train.csv')\nprint(df_train.shape)\ndf_train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.info()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def json_to_df(df, column):\n    num_rows = len(df)\n    \n    data_list = []\n    for row in tqdm(range(num_rows)):\n        \n        json_data = df.iloc[row][column]\n        if str(json_data) != \"nan\":\n            data = pd.read_json(json_data)\n            data_list.append(data)\n        \n    all_data = pd.concat(data_list, axis = 0)\n    \n    return all_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"player_engagement = json_to_df(df_train, 'nextDayPlayerEngagement')\nplayer_engagement.insert(0, 'date', pd.to_datetime(player_engagement['engagementMetricsDate'])-\\\n                                                   timedelta(days=1))\nplayer_engagement['engagementMetricsDate'] = pd.to_datetime(player_engagement['engagementMetricsDate'])\nplayer_engagement.reset_index(drop=True, inplace=True)\nprint(player_engagement.shape)\nplayer_engagement.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"player_engagement[['target1','target2','target3','target4']] = player_engagement[['target1','target2','target3','target4']].astype(np.float16)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playerBoxScores = json_to_df(df_train, 'playerBoxScores')\nplayerBoxScores = playerBoxScores.reset_index(drop=True)\nplayerBoxScores.insert(0, 'date', pd.to_datetime(playerBoxScores['gameDate']))\nplayerBoxScores = playerBoxScores.drop(columns=['gameDate'])\nprint(playerBoxScores.shape)\nplayerBoxScores.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playerBoxScores_columns = ['date',\n                           'playerId',\n                           'homeRuns',\n                           'rbi',\n                           'atBats',\n                           'stolenBases',\n                           'hits',\n                           'runsScored',\n                           'earnedRuns',\n                           'hitsPitching',\n                           'intentionalWalksPitching',\n                           'strikeOuts',\n                           'saves'\n                          ]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag = 100\n\nlag_df = player_engagement.loc[player_engagement['date'] >= player_engagement.loc[0, 'date'] +\\\n                               timedelta(lag)]\n\nfor x in tqdm(range(1, (lag+1))):\n    drop_columns = [f'date_{x}', f'engagementMetricsDate_{x}']\n    lag_df = lag_df.merge(player_engagement, how='left', \n                          left_on=['date', 'playerId'],\n                          right_on=['engagementMetricsDate', 'playerId'],\n                          suffixes=['',f'_{x}'])\n    lag_df.drop(columns=drop_columns, inplace=True)\n    lag_df['date'] = lag_df['date'] - timedelta(days=1)\n    \nlag_df['date'] = lag_df['date'] + timedelta(days=lag)\nlag_df = lag_df.drop(columns=['engagementMetricsDate'])\nlag_df = lag_df.dropna()\nlag_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_columns = [x for x in lag_df.columns[6:]]\nfeature_columns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag_df.info()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag_df = lag_df.sort_values(by=['date','playerId']).reset_index(drop=True)\nlag_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for x in range(4):\n    columns = [f'target{x+1}_{i+1}' for i in range(lag)]\n    lag_df[f'target{x+1}_median'] = lag_df[columns].median(axis=1).astype(np.float32)\n    lag_df = lag_df.drop(columns=columns)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag_df = lag_df.merge(playerBoxScores[playerBoxScores_columns], how='left', on=['date', 'playerId'])\nlag_df = lag_df.fillna(0.)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lag_df.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model(input_shape):\n    inputs = Input(shape=input_shape)\n    \n    x = Dense(50, activation='relu')(inputs)\n    x = Dropout(0.2)(x)\n    x = Dense(50, activation='relu')(x)\n    x = Dropout(0.2)(x)\n\n    outputs = Dense(4, activation='linear')(x)\n    \n    model = Model(inputs=inputs, outputs=outputs)\n    \n#     model.summary()\n    \n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target_columns = [x for x in lag_df.columns[2:6]]\ntarget_columns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_columns = [x for x in lag_df.columns[6:]]\nfeature_columns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# scaler = StandardScaler()\n\nsplits = 10\n\ntss = TimeSeriesSplit(n_splits=splits)\n\nsplit = 1\n\nfor train_index, val_index in tss.split(lag_df):\n    X_train = lag_df.loc[train_index, feature_columns].to_numpy()\n#     X_train = scaler.fit_transform(X_train)\n    y_train = lag_df.loc[train_index, target_columns].to_numpy()\n    \n    X_val = lag_df.loc[val_index, feature_columns].to_numpy()\n#     X_val = scaler.fit_transform(X_val)\n    y_val = lag_df.loc[val_index, target_columns].to_numpy()\n    \n    input_shape = (X_train.shape[1],)\n    \n    model = create_model(input_shape)\n\n    model.compile(\n        optimizer='rmsprop',\n        loss='mean_absolute_error'\n    )\n\n#     es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)\n    mc = ModelCheckpoint(f'best_model_split{split}.h5', monitor='val_loss', mode='min',\n                         save_best_only=True,verbose=1)\n\n    history = model.fit(X_train,\n                        y_train,\n                        validation_data=(X_val, y_val),\n                        epochs=10,\n                        batch_size=30_000,\n                        callbacks=[mc])\n\n    plt.figure()\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.ylabel('loss')\n    plt.xlabel('epochs')\n    plt.title(f'Training-Validation Loss Split-{split}')\n    plt.legend(['train_loss', 'val_loss'], loc='upper right')\n    plt.show()\n    \n    split += 1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction(df, test_df):\n    df = df.reset_index()\n    df['date'] = pd.to_datetime(df['date'], format='%Y%m%d')\n    df['playerId'] = df['date_playerId'].apply(lambda x: x.split('_')[1]).astype(int)\n    \n    for x in range(lag):\n        df['date'] = df['date'] - timedelta(days=1)\n        df = df.merge(player_engagement, how='left', on=['date', 'playerId'], suffixes=['',f'_{x+1}'])\n        df = df.fillna(0.)\n    \n    for x in range(4):\n        columns = [f'target{x+1}_{i+1}' for i in range(lag)]\n        df[f'target{x+1}_median'] = df[columns].median(axis=1)\n        df = df.drop(columns=columns)\n    \n    pbs_test = json_to_df(test_df, 'playerBoxScores')\n    pbs_test = pbs_test.reset_index(drop=True)\n    pbs_test.insert(0, 'date', pd.to_datetime(pbs_test['gameDate']))\n    pbs_test = pbs_test.drop(columns=['gameDate'])\n    \n    df = df.merge(pbs_test[playerBoxScores_columns], how='left', on=['date', 'playerId'])\n    df = df.fillna(0.)\n    \n    pred = np.zeros(df[target_columns].shape)\n    \n    for x in range(splits):\n        best_model = load_model(f'./best_model_split{x+1}.h5')\n        pred += best_model.predict(df[feature_columns].to_numpy()) / splits\n    \n    return pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"player_engagement = player_engagement.drop(columns=['engagementMetricsDate'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import mlb\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:\n    targets = prediction(sample_prediction_df, test_df)\n    sample_prediction_df[target_columns] = np.clip(targets, 0, 100)\n    env.predict(sample_prediction_df)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}