{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2021-07-30T03:54:24.61512Z","iopub.execute_input":"2021-07-30T03:54:24.615509Z","iopub.status.idle":"2021-07-30T03:54:24.656925Z","shell.execute_reply.started":"2021-07-30T03:54:24.615475Z","shell.execute_reply":"2021-07-30T03:54:24.655893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nimport sys\nimport warnings\nimport pickle\nfrom pathlib import Path\n\nimport ipywidgets as widgets\n\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport catboost\nfrom sklearn.metrics import mean_squared_error\nfrom sklearn.ensemble import RandomForestRegressor\nfrom statsmodels.tsa.seasonal import seasonal_decompose","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:24.658297Z","iopub.execute_input":"2021-07-30T03:54:24.658582Z","iopub.status.idle":"2021-07-30T03:54:24.665387Z","shell.execute_reply.started":"2021-07-30T03:54:24.658554Z","shell.execute_reply":"2021-07-30T03:54:24.663756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load dataset","metadata":{}},{"cell_type":"code","source":"df_names = ['playerBoxScores', 'teamBoxScores', 'playerTwitterFollowers', 'teamTwitterFollowers', 'awards', 'events',\n           'games', 'standings', 'rosters', 'transactions']\npath = \"../input/mlb-pdef-train-dataset\"\n\ntrain_dict = {}\nfor index in range(len(df_names)):\n    train_dict[df_names[index]] = pd.read_pickle(os.path.join(path,df_names[index]) + \"_train.pkl\")","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:24.66737Z","iopub.execute_input":"2021-07-30T03:54:24.667875Z","iopub.status.idle":"2021-07-30T03:54:39.460593Z","shell.execute_reply.started":"2021-07-30T03:54:24.667638Z","shell.execute_reply":"2021-07-30T03:54:39.458968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_names = ['seasons', 'teams', 'players', 'awards']\npath = \"../input/mlb-player-digital-engagement-forecasting\"\n\nmy_dict = {}\nfor index in range(len(df_names)):\n    my_dict[df_names[index]] = pd.read_csv(os.path.join(path,df_names[index]) + \".csv\")","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:39.46311Z","iopub.execute_input":"2021-07-30T03:54:39.463574Z","iopub.status.idle":"2021-07-30T03:54:39.505994Z","shell.execute_reply.started":"2021-07-30T03:54:39.463514Z","shell.execute_reply":"2021-07-30T03:54:39.505199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target = pd.read_pickle('../input/mlb-pdef-train-dataset/nextDayPlayerEngagement_train.pkl')\ntarget = target.drop(['index'], axis = 1)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:39.507341Z","iopub.execute_input":"2021-07-30T03:54:39.50774Z","iopub.status.idle":"2021-07-30T03:54:39.913289Z","shell.execute_reply.started":"2021-07-30T03:54:39.507712Z","shell.execute_reply":"2021-07-30T03:54:39.9124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualize the mean and correlation of target values","metadata":{}},{"cell_type":"markdown","source":"After taking mean over different players, we can see how the mean of targets move over time and their correlations. ","metadata":{}},{"cell_type":"code","source":"target_date = target.groupby('engagementMetricsDate').mean().drop(['playerId', 'date'], axis = 1)\ntarget_date.plot(figsize=(20,5))","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:39.91462Z","iopub.execute_input":"2021-07-30T03:54:39.915057Z","iopub.status.idle":"2021-07-30T03:54:40.531558Z","shell.execute_reply.started":"2021-07-30T03:54:39.915026Z","shell.execute_reply":"2021-07-30T03:54:40.530453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the plot above, \"target 2\" value shows a much wider variation but the four engagement measurements change in a similar wary since they are correlated with each other. In  the correlation matrix shown below, we find that \"target 1\" is highly correlated with \"target 2\" and \"target 3\" while \"target 4\" is less correlated with the other three values.  ","metadata":{}},{"cell_type":"code","source":"target_player = target.groupby('playerId').mean()\ntarget_corr = target_player.corr()\nsns.heatmap(target_corr, vmin = 0.5)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:40.533145Z","iopub.execute_input":"2021-07-30T03:54:40.533564Z","iopub.status.idle":"2021-07-30T03:54:40.972051Z","shell.execute_reply.started":"2021-07-30T03:54:40.53352Z","shell.execute_reply":"2021-07-30T03:54:40.970994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Seasonal Decomposition","metadata":{}},{"cell_type":"markdown","source":"Apart from correlation, the time series plots also shows a calendar related effect, for example, a peak around March (the start of each season). To better understand the seasonal properties, we apply a seasonal decomposition to investigate the trend and seasonality. Since the amplitude of the seasonal variation does not change as the trend rises or falls, I use an additive decoposition.","metadata":{}},{"cell_type":"code","source":"trend, seasonal = pd.DataFrame(), pd.DataFrame()\nfor i in target_date:    \n    series = target_date[i]\n    result = seasonal_decompose(series, model='multiplicative', period = 365)\n    trend[i] = result.trend\n    seasonal[i] = result.seasonal","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:40.97362Z","iopub.execute_input":"2021-07-30T03:54:40.974081Z","iopub.status.idle":"2021-07-30T03:54:41.036946Z","shell.execute_reply.started":"2021-07-30T03:54:40.974028Z","shell.execute_reply":"2021-07-30T03:54:41.036004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The trend component shows the rises and falls in the four series, ignoring the seasonality and any small random fluctuations.\n\nFrom the four plots below, we find that target 1 and target 2 have an almost oppsite trend and target 4's trend is totally different from the other 3 measurements.\n\n* For target 1, it goes down from the end of 2019 and remained low until around July 2020 (it may due to the covid).\n* For target 2, it increases when target 1 decreases and started to decrease when target 1 start to rise.\n* For target 3, it drop sharply from July 2019 and started to fluctuate from July 2020 (a similar trend with target 1).\n* Target 4 is the only target value that has a cycle, the single cycle period is about 3-4 months.","metadata":{}},{"cell_type":"code","source":"fig, axes = plt.subplots(2, 2, figsize = (16, 8))\naxes[0, 0].plot(trend['target1'])\naxes[0, 0].set_title('trend of target1')\naxes[0, 0].set_xticks(trend.index[::180])\naxes[0, 1].plot(trend['target2'])\naxes[0, 1].set_title('trend of target2')\naxes[0, 1].set_xticks(trend.index[::180])\naxes[1, 0].plot(trend['target3'])\naxes[1, 0].set_title('trend of target3')\naxes[1, 0].set_xticks(trend.index[::180])\naxes[1, 1].plot(trend['target4'])\naxes[1, 1].set_title('trend of target4')\naxes[1, 1].set_xticks(trend.index[::180])","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:41.038484Z","iopub.execute_input":"2021-07-30T03:54:41.038935Z","iopub.status.idle":"2021-07-30T03:54:42.444878Z","shell.execute_reply.started":"2021-07-30T03:54:41.038887Z","shell.execute_reply":"2021-07-30T03:54:42.443865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The seasonality plot shows that all the target measurements have a roughly one-year pattern. Target 1 has an obvious spike around March every year. It should be related to the start of each season. Target 2 and 3 also reach peak around March but they fluctuate before and after the peak. From target 1 to 4, the seasonal patten  is becoming less obvious. As for target 4, it shows a big variation throughout the year, instead of a seasonal pattern\n. ","metadata":{}},{"cell_type":"code","source":"fig, axes = plt.subplots(2, 2, figsize = (16, 8))\naxes[0, 0].plot(seasonal['target1'])\naxes[0, 0].set_title('seasonality of target1')\naxes[0, 0].set_xticks(seasonal.index[::240])\naxes[0, 1].plot(seasonal['target2'])\naxes[0, 1].set_title('seasonality of target2')\naxes[0, 1].set_xticks(seasonal.index[::240])\naxes[1, 0].plot(seasonal['target3'])\naxes[1, 0].set_title('seasonality of target3')\naxes[1, 0].set_xticks(seasonal.index[::240])\naxes[1, 1].plot(seasonal['target4'])\naxes[1, 1].set_title('seasonality of target4')\naxes[1, 1].set_xticks(seasonal.index[::240])","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:42.447665Z","iopub.execute_input":"2021-07-30T03:54:42.448014Z","iopub.status.idle":"2021-07-30T03:54:43.65118Z","shell.execute_reply.started":"2021-07-30T03:54:42.447982Z","shell.execute_reply":"2021-07-30T03:54:43.649909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Anythig Different in 2020?","metadata":{}},{"cell_type":"markdown","source":"Due to covid, the regular season started in July instead of March. I expect that the fans engagement will be different in 2020. To verify my guess, I plot the difference of each target between 2020 and 2019 (from March to August), and then compare them with the difference between 2019 and 2018.","metadata":{}},{"cell_type":"code","source":"target['engagementMetricsDate'] = pd.to_datetime(target['engagementMetricsDate'], format = \"%Y-%m-%d\")\ntarget['year'] = target['engagementMetricsDate'].dt.year","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:43.653187Z","iopub.execute_input":"2021-07-30T03:54:43.653494Z","iopub.status.idle":"2021-07-30T03:54:44.334023Z","shell.execute_reply.started":"2021-07-30T03:54:43.653462Z","shell.execute_reply":"2021-07-30T03:54:44.333075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target_2020 = target[target['year']==2020].drop(['date', 'year', 'playerId'], axis = 1).groupby(\n    'engagementMetricsDate').mean().reset_index()\ntarget_2019 = target[target['year']==2019].drop(['date', 'year', 'playerId'], axis = 1).groupby(\n    'engagementMetricsDate').mean().reset_index()\ntarget_2018 = target[target['year']==2018].drop(['date', 'year', 'playerId'], axis = 1).groupby(\n    'engagementMetricsDate').mean().reset_index()","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:44.335325Z","iopub.execute_input":"2021-07-30T03:54:44.335606Z","iopub.status.idle":"2021-07-30T03:54:44.566637Z","shell.execute_reply.started":"2021-07-30T03:54:44.335578Z","shell.execute_reply":"2021-07-30T03:54:44.565639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"value_2020 = target_2020[(target_2020['engagementMetricsDate'] < pd.Timestamp('2020-08-01')) & (\n    target_2020['engagementMetricsDate'] > pd.Timestamp('2020-02-29'))].reset_index()\nvalue_2019 = target_2019[(target_2019['engagementMetricsDate'] < pd.Timestamp('2019-08-01')) & (\n    target_2019['engagementMetricsDate'] > pd.Timestamp('2019-02-28'))].reset_index()\nvalue_2018 = target_2018[(target_2018['engagementMetricsDate'] < pd.Timestamp('2018-08-01')) & (\n    target_2018['engagementMetricsDate'] > pd.Timestamp('2018-02-28'))].reset_index()","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:44.567825Z","iopub.execute_input":"2021-07-30T03:54:44.568114Z","iopub.status.idle":"2021-07-30T03:54:44.58212Z","shell.execute_reply.started":"2021-07-30T03:54:44.568086Z","shell.execute_reply":"2021-07-30T03:54:44.580767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"diff_2020 = (value_2020 - value_2019)[['target1', 'target2', 'target3', 'target4']].set_index(\n    (pd.period_range(start='2020-03-01', end='2020-07-31', freq='d').to_timestamp()))\ndiff_2019 = (value_2019 - value_2018)[['target1', 'target2', 'target3', 'target4']].set_index(\n    (pd.period_range(start='2020-03-01', end='2020-07-31', freq='d').to_timestamp()))","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:44.58364Z","iopub.execute_input":"2021-07-30T03:54:44.584348Z","iopub.status.idle":"2021-07-30T03:54:44.604374Z","shell.execute_reply.started":"2021-07-30T03:54:44.584301Z","shell.execute_reply":"2021-07-30T03:54:44.60367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Since we choose the same period each year, if nothing special happens, the value in different years should remain similar and the difference series will fluctuate around 0. As for the difference series of target 1, there's a slight decrease 2020, especially between April and July.","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(1, 2, figsize = (15,5), sharey = True)\n\naxs[0].plot(diff_2020['target1'].index, diff_2020['target1'], color='black')\naxs[0].axhline(y=0,linestyle='--',color='red')\naxs[0].set_title('Target 1: difference between 2020 and 2019')\naxs[1].plot(diff_2019['target1'].index, diff_2019['target1'])\naxs[1].axhline(y=0,linestyle='--',color='red')\naxs[1].set_title('Target 1: difference between 2019 and 2018')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:44.605658Z","iopub.execute_input":"2021-07-30T03:54:44.606149Z","iopub.status.idle":"2021-07-30T03:54:45.015973Z","shell.execute_reply.started":"2021-07-30T03:54:44.606098Z","shell.execute_reply":"2021-07-30T03:54:45.014996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"However, it is totally diffferent for target 2 since the values in 2020 are consistently bigger than in 2019, while the differences between 2019 and 2018 are similar. Therefore, the postpone of regular season actually increase the target 2. ","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(1, 2, figsize = (15,5), sharey = True)\n\naxs[0].plot(diff_2020['target2'].index, diff_2020['target2'], color='black')\naxs[0].axhline(y=0,linestyle='--',color='red')\naxs[0].set_title('Target 2: difference between 2020 and 2019')\naxs[1].plot(diff_2019['target2'].index, diff_2019['target2'])\naxs[1].axhline(y=0,linestyle='--',color='red')\naxs[1].set_title('Target 2: difference between 2019 and 2018')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:45.017212Z","iopub.execute_input":"2021-07-30T03:54:45.017528Z","iopub.status.idle":"2021-07-30T03:54:45.383207Z","shell.execute_reply.started":"2021-07-30T03:54:45.017496Z","shell.execute_reply":"2021-07-30T03:54:45.38245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Target 3 did not change much during 2020, except for a sharp decrease around March (the start of regular season).","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(1, 2, figsize = (15,5), sharey = True)\n\naxs[0].plot(diff_2020['target3'].index, diff_2020['target3'], color='black')\naxs[0].axhline(y=0,linestyle='--',color='red')\naxs[0].set_title('Target 3: difference between 2020 and 2019')\naxs[1].plot(diff_2019['target3'].index, diff_2019['target3'])\naxs[1].axhline(y=0,linestyle='--',color='red')\naxs[1].set_title('Target 3: difference between 2019 and 2018')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:45.384339Z","iopub.execute_input":"2021-07-30T03:54:45.384805Z","iopub.status.idle":"2021-07-30T03:54:45.745089Z","shell.execute_reply.started":"2021-07-30T03:54:45.38476Z","shell.execute_reply":"2021-07-30T03:54:45.74389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In 2020, target 4 is lower than in 2019, which may due to the influence of covid.","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(1, 2, figsize = (15,5), sharey = True)\n\naxs[0].plot(diff_2020['target4'].index, diff_2020['target4'], color='black')\naxs[0].axhline(y=0,linestyle='--',color='red')\naxs[0].set_title('Target 4: difference between 2020 and 2019')\naxs[1].plot(diff_2019['target4'].index, diff_2019['target4'])\naxs[1].axhline(y=0,linestyle='--',color='red')\naxs[1].set_title('Target 4: difference between 2019 and 2018')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:45.746616Z","iopub.execute_input":"2021-07-30T03:54:45.747041Z","iopub.status.idle":"2021-07-30T03:54:46.12258Z","shell.execute_reply.started":"2021-07-30T03:54:45.746999Z","shell.execute_reply":"2021-07-30T03:54:46.121592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Find Important Features","metadata":{}},{"cell_type":"markdown","source":"We have find the the target values are related with time. In this part, we are going to explore other features (features related to players, teams, and games, etc).","metadata":{}},{"cell_type":"markdown","source":"### Construct player related features","metadata":{}},{"cell_type":"code","source":"player_score = train_dict['playerBoxScores']","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:46.123753Z","iopub.execute_input":"2021-07-30T03:54:46.124035Z","iopub.status.idle":"2021-07-30T03:54:46.143279Z","shell.execute_reply.started":"2021-07-30T03:54:46.124009Z","shell.execute_reply":"2021-07-30T03:54:46.142558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I construct features according to the following page: [MLB stats GLOSSARY](http://www.mlb.com/glossary/). \n\nI choose 2 features from the \"Defense\" category:\n* \"FPCT\": Fielding percentage\n* \"Out\": including a strikeout, a groundout, a popout or a flyout.\n\n5 features from the \"Offense\" category:\n* \"HR\": home run. \n* \"IBB\": intentional walk.\n* \"TB\": total bases.\n* \"RBI\": runs batted in.\n* \"AVG\": batting average.\n\n5 features from the \"Pitching\" category:\n* \"SV_percnt\": save percentage.\n* \"HLD\": hold.\n* \"BS\": blown save.\n* \"IR\": inherited runner.\n* \"IP\": innings pitched.\n\n5 features from the \"Advanced\" category:\n* \"ISO\": isolated power.\n* \"BABIP\": batting average on balls in play.\n* \"RC\": runs created.\n* \"PA/SO\": plate appearances per strikeout.\n* \"K/BB\": strikeout-to-walk ratio.","metadata":{}},{"cell_type":"code","source":"perform_stats = pd.DataFrame()\n\n# For calculation\nperform_stats['AB'] = player_score['atBats']\nperform_stats['B2'] = player_score['doubles']\nperform_stats['B3'] = player_score['triples']\nperform_stats['H'] = player_score['hits']\nperform_stats['PA'] = player_score['plateAppearances']\nperform_stats['TB'] = player_score['totalBases']\nperform_stats['BB'] = player_score['baseOnBalls']\nperform_stats['SO'] = player_score['strikeOuts']\n\n# Defense\nperform_stats['FPCT'] = (player_score['putOuts'] + player_score['assists']) / player_score['chances']\nperform_stats['Out'] = player_score['putOuts'] + player_score['groundOuts'] + player_score['strikeOuts'] + player_score['flyOuts']\n\n# Offence\nperform_stats['HR'] = player_score['homeRuns']\nperform_stats['IBB'] = player_score['intentionalWalks']\nperform_stats['TB'] = player_score['totalBases']\nperform_stats['RBI'] = player_score['rbi']\nperform_stats['AVG'] = perform_stats['H']/perform_stats['AB']\n\n# Pitching\nperform_stats['SV_percnt'] = player_score['saves']/player_score['saveOpportunities']\nperform_stats['HLD'] = player_score['holds']\nperform_stats['BS'] = player_score['blownSaves']\nperform_stats['IR'] = player_score['inheritedRunners']\nperform_stats['IP'] = player_score['inningsPitched']\n\n# Advanced Offence\nperform_stats['ISO'] = (perform_stats['B2']+2*perform_stats['B3']+3*perform_stats['HR'])/perform_stats['AB']\nperform_stats['BABIP'] = (perform_stats['H'] - perform_stats['HR'])/(\n    perform_stats['AB']-perform_stats['SO']-perform_stats['HR']+player_score['sacFlies'])\nperform_stats['RC'] = perform_stats['TB']*(perform_stats['H']+perform_stats['BB'])/(\n    perform_stats['AB']+perform_stats['BB'])\nperform_stats['PA/SO'] = perform_stats['PA']/perform_stats['SO']\nperform_stats['K/BB'] = perform_stats['SO']/perform_stats['BB']","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:46.144319Z","iopub.execute_input":"2021-07-30T03:54:46.1447Z","iopub.status.idle":"2021-07-30T03:54:46.216519Z","shell.execute_reply.started":"2021-07-30T03:54:46.144671Z","shell.execute_reply":"2021-07-30T03:54:46.215772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target['date'] = target['date']\ntarget = target[target['date'].notna()]\nplayer_stats = perform_stats[['FPCT', 'Out', 'HR', 'IBB', 'TB', 'RBI', 'AVG', 'SV_percnt', 'HLD', 'BS', 'IR', 'IP', 'ISO', 'BABIP', 'RC', 'PA/SO', 'K/BB']]\nplayer_stats['date'], player_stats['playerId'] = player_score['date'], player_score['playerId']\n\nmerge_1 = target.merge(player_stats, on = ['date', 'playerId'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:46.217497Z","iopub.execute_input":"2021-07-30T03:54:46.217925Z","iopub.status.idle":"2021-07-30T03:54:47.247094Z","shell.execute_reply.started":"2021-07-30T03:54:46.217884Z","shell.execute_reply":"2021-07-30T03:54:47.24616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I then construct some similar features using the team scores. And I add an team specific measurement:\n* \"Pytha_WR\": pythagorean winning percentage, it determines the number of games that a team \"should\" have won.","metadata":{}},{"cell_type":"code","source":"team_score = train_dict['teamBoxScores']","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:47.248249Z","iopub.execute_input":"2021-07-30T03:54:47.248704Z","iopub.status.idle":"2021-07-30T03:54:47.253126Z","shell.execute_reply.started":"2021-07-30T03:54:47.248659Z","shell.execute_reply":"2021-07-30T03:54:47.251905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"team_stats = pd.DataFrame()\n\n# For fcalculation\nteam_stats['AB_team'] = team_score['atBats']\nteam_stats['B2_team'] = team_score['doubles']\nteam_stats['B3_team'] = team_score['triples']\nteam_stats['H_team'] = team_score['hits']\nteam_stats['PA_team'] = team_score['plateAppearances']\nteam_stats['BB_team'] = team_score['baseOnBalls']\nteam_stats['SO_team'] = team_score['strikeOuts']\n\n# Offence\nteam_stats['HR_team'] = team_score['homeRuns']\nteam_stats['IBB_team'] = team_score['intentionalWalks']\nteam_stats['TB_team'] = team_score['totalBases']\nteam_stats['RBI_team'] = team_score['rbi']\nteam_stats['AVG_team'] = team_stats['H_team']/team_stats['AB_team']\n\n# Pitching\nteam_stats['IR_team'] = team_score['inheritedRunners']\nteam_stats['IP_team'] = team_score['inningsPitched']\n\n# Advanced Offence\nteam_stats['ISO_team'] = (team_stats['B2_team']+2*team_stats['B3_team']+3*team_stats['HR_team'])/team_stats['AB_team']\nteam_stats['BABIP_team'] = (team_stats['H_team'] - team_stats['HR_team'])/(\n    team_stats['AB_team']-team_stats['SO_team']-team_stats['HR_team']+team_score['sacFlies'])\nteam_stats['RC_team'] = team_stats['TB_team']*(team_stats['H_team']+team_stats['BB_team'])/(\n    team_stats['AB_team']+team_stats['BB_team'])\nteam_stats['Pytha_WR'] = team_score['runsScored']**2/(team_score['runsScored']**2 + team_score['runsPitching']**2)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:47.2543Z","iopub.execute_input":"2021-07-30T03:54:47.254574Z","iopub.status.idle":"2021-07-30T03:54:47.287513Z","shell.execute_reply.started":"2021-07-30T03:54:47.254548Z","shell.execute_reply":"2021-07-30T03:54:47.286671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merge_1['teamId'] = player_score['teamId']\nteam_stats = team_stats[['HR_team', 'IBB_team', 'TB_team', 'RBI_team', 'AVG_team', 'IR_team', 'IP_team', 'ISO_team', 'BABIP_team', 'RC_team', 'Pytha_WR']]\nteam_stats['date'], team_stats['teamId'] = team_score['date'], team_score['teamId']\nmerge_2 = merge_1.merge(team_stats, on = ['date', 'teamId'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:47.288873Z","iopub.execute_input":"2021-07-30T03:54:47.28917Z","iopub.status.idle":"2021-07-30T03:54:48.481479Z","shell.execute_reply.started":"2021-07-30T03:54:47.289143Z","shell.execute_reply":"2021-07-30T03:54:48.478078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In addtion to the players and teams performance features, the \"team_rank\" features below describe the ranking and winnings in divisions and leagues.","metadata":{}},{"cell_type":"code","source":"team_rank = train_dict['standings'][['teamId', 'divisionRank', 'leagueRank', 'wildCardRank', 'divWins', 'alWins', 'nlWins', 'pct', 'homeWins', 'xWinLossPct', 'date']]","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:48.486834Z","iopub.execute_input":"2021-07-30T03:54:48.487163Z","iopub.status.idle":"2021-07-30T03:54:48.502356Z","shell.execute_reply.started":"2021-07-30T03:54:48.487133Z","shell.execute_reply":"2021-07-30T03:54:48.50097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merge_3 = merge_2.merge(team_rank, on = ['date', 'teamId'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:48.50574Z","iopub.execute_input":"2021-07-30T03:54:48.506199Z","iopub.status.idle":"2021-07-30T03:54:49.870194Z","shell.execute_reply.started":"2021-07-30T03:54:48.506151Z","shell.execute_reply":"2021-07-30T03:54:49.869155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The feature below shows whether a player has be transacted or not.","metadata":{}},{"cell_type":"code","source":"transaction = train_dict['transactions'][['playerId', 'date', 'typeCode']]\ntransaction['transacted'] = 1\n\nmerge_4 = merge_3.merge(transaction, on = ['date', 'playerId'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:49.874641Z","iopub.execute_input":"2021-07-30T03:54:49.874959Z","iopub.status.idle":"2021-07-30T03:54:51.664531Z","shell.execute_reply.started":"2021-07-30T03:54:49.87493Z","shell.execute_reply":"2021-07-30T03:54:51.663481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The \"award_current\" features indicates whether a player has received an award after 2018 or not.","metadata":{}},{"cell_type":"code","source":"awards_current = train_dict['awards'][['date', 'playerId']]\nawards_current['awarded_recnt'] = 1\nmerge_5 = merge_4.merge(awards_current, on = ['date', 'playerId',], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:51.665972Z","iopub.execute_input":"2021-07-30T03:54:51.666286Z","iopub.status.idle":"2021-07-30T03:54:53.103001Z","shell.execute_reply.started":"2021-07-30T03:54:51.666243Z","shell.execute_reply":"2021-07-30T03:54:53.101863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I also include the number of players' twitter followers and teams' twitter followers as features in the model.","metadata":{}},{"cell_type":"code","source":"player_twit = train_dict['playerTwitterFollowers'][['date', 'playerId', 'numberOfFollowers']]\n\nmerge_6 = merge_5.merge(player_twit, on = ['date', 'playerId'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:53.104059Z","iopub.execute_input":"2021-07-30T03:54:53.104342Z","iopub.status.idle":"2021-07-30T03:54:54.548729Z","shell.execute_reply.started":"2021-07-30T03:54:53.104313Z","shell.execute_reply":"2021-07-30T03:54:54.547778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"team_twit = train_dict['teamTwitterFollowers'][['date', 'teamId', 'numberOfFollowers']]\nteam_twit = team_twit.rename(columns = {\"numberOfFollowers\": \"team_followers\"})\n\nmerge_7 = merge_6.merge(team_twit, on = ['date', 'teamId'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:54.550039Z","iopub.execute_input":"2021-07-30T03:54:54.550342Z","iopub.status.idle":"2021-07-30T03:54:55.923947Z","shell.execute_reply.started":"2021-07-30T03:54:54.550313Z","shell.execute_reply":"2021-07-30T03:54:55.922949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The \"rosters\" feature shows a player's status (for example, injured or active) at a certain time.","metadata":{}},{"cell_type":"code","source":"rosters = train_dict['rosters'][['playerId', 'date', 'status']]\nmerge_8 = merge_7.merge(rosters, on = ['playerId', 'date'], how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:55.924967Z","iopub.execute_input":"2021-07-30T03:54:55.925263Z","iopub.status.idle":"2021-07-30T03:54:57.889684Z","shell.execute_reply.started":"2021-07-30T03:54:55.925235Z","shell.execute_reply":"2021-07-30T03:54:57.88864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prepare data for random forest\n\nIn this part, I fill the NAN values with -99, which is not in the range of the dataset. And deal with inifinite values and make sure all the features are in correct format for the future modelling procedure.","metadata":{}},{"cell_type":"code","source":"df = merge_8.drop(['engagementMetricsDate'], axis = 1)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:57.89109Z","iopub.execute_input":"2021-07-30T03:54:57.891405Z","iopub.status.idle":"2021-07-30T03:54:59.418366Z","shell.execute_reply.started":"2021-07-30T03:54:57.891374Z","shell.execute_reply":"2021-07-30T03:54:59.416324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['pct'] = df['pct'].astype('float')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:59.420344Z","iopub.execute_input":"2021-07-30T03:54:59.420882Z","iopub.status.idle":"2021-07-30T03:54:59.750689Z","shell.execute_reply.started":"2021-07-30T03:54:59.420826Z","shell.execute_reply":"2021-07-30T03:54:59.749749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"object_encode = df.select_dtypes(include=['object'])\n\ndef label_encode(df, column):\n    func = {c: i for i, c in enumerate(df[column].unique()) if not pd.isna(c)}\n    df[column] = df[column].map(func)\n\nfor col in object_encode.columns:\n    label_encode(object_encode, col)\ndf[object_encode.columns] = object_encode","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:54:59.751665Z","iopub.execute_input":"2021-07-30T03:54:59.752Z","iopub.status.idle":"2021-07-30T03:55:05.751689Z","shell.execute_reply.started":"2021-07-30T03:54:59.75197Z","shell.execute_reply":"2021-07-30T03:55:05.750637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.replace(np.inf, 0, inplace=True)\ndf = df.fillna(-99)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:05.753083Z","iopub.execute_input":"2021-07-30T03:55:05.753407Z","iopub.status.idle":"2021-07-30T03:55:07.690233Z","shell.execute_reply.started":"2021-07-30T03:55:05.753375Z","shell.execute_reply":"2021-07-30T03:55:07.689186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To investigate how the different time periods affect fans engagement, I break down the date into \"year\", \"month\" and \"day\".","metadata":{}},{"cell_type":"code","source":"df['date'] = pd.to_datetime(df['date'], format = \"%Y%m%d\")\ndf['year'] = df['date'].dt.year\ndf['month'] = df['date'].dt.month\ndf['day'] = df['date'].dt.day","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:07.691755Z","iopub.execute_input":"2021-07-30T03:55:07.692202Z","iopub.status.idle":"2021-07-30T03:55:08.449812Z","shell.execute_reply.started":"2021-07-30T03:55:07.692157Z","shell.execute_reply":"2021-07-30T03:55:08.448845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df.set_index(['playerId', 'date'], drop = True)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:08.450945Z","iopub.execute_input":"2021-07-30T03:55:08.451228Z","iopub.status.idle":"2021-07-30T03:55:09.008336Z","shell.execute_reply.started":"2021-07-30T03:55:08.451202Z","shell.execute_reply":"2021-07-30T03:55:09.007376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Run Random Forest Model and Extract Feature Importance","metadata":{}},{"cell_type":"markdown","source":"It is an ensemble learning method based on decision trees and the feature importances are calculated using Gini importance. The hyperparameters I use below are selected from random search.","metadata":{}},{"cell_type":"code","source":"regr = RandomForestRegressor(\n    max_depth=20, \n    max_features = 'sqrt', \n    min_samples_split = 6, \n    n_estimators = 200, \n    random_state=0)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:09.00972Z","iopub.execute_input":"2021-07-30T03:55:09.010114Z","iopub.status.idle":"2021-07-30T03:55:09.014606Z","shell.execute_reply.started":"2021-07-30T03:55:09.010081Z","shell.execute_reply":"2021-07-30T03:55:09.0139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = df.drop(['target1', 'target2', 'target3', 'target4'], axis = 1)\ny = df[['target1', 'target2', 'target3', 'target4']]","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:09.015757Z","iopub.execute_input":"2021-07-30T03:55:09.016167Z","iopub.status.idle":"2021-07-30T03:55:09.364273Z","shell.execute_reply.started":"2021-07-30T03:55:09.016138Z","shell.execute_reply":"2021-07-30T03:55:09.363526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nfeature_imp = pd.DataFrame(index = X.columns)\nfor i in y.columns:\n    if os.path.isfile(\"../input/target-models/\" + i + \"_model.sav\"):\n        with open(\"../input/target-models/\" + i + \"_model.sav\", 'rb') as fin:\n            regr = pickle.load(fin)\n            feature_imp[i] = regr.feature_importances_\n    else:\n        regr = regr.fit(X, y[i])\n        feature_imp[i] = regr.feature_importances_\n        filename = i+'_model.sav'\n        pickle.dump(regr, open('../input/target-models'+ filename, 'wb'))","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:09.365314Z","iopub.execute_input":"2021-07-30T03:55:09.365729Z","iopub.status.idle":"2021-07-30T03:55:20.458512Z","shell.execute_reply.started":"2021-07-30T03:55:09.365698Z","shell.execute_reply":"2021-07-30T03:55:20.457481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Before I start to look into the importance of the features, I put the features into 5 categories: \n\n* The \"player performance\" includes features of a players performance in a game.\n* Other player related features include transaction, twitter followers and players' status.\n* The \"team performance\" category include teams' performance in games.\n* Other team related features include team ranking in division and league, team twitter statistics and team winning percentages.\n* The \"time features\" include \"day\", \"month\" and \"year\".","metadata":{}},{"cell_type":"code","source":"player_perform = ['FPCT', 'Out', 'HR', 'IBB', 'TB', 'RBI', 'AVG', 'SV_percnt', 'HLD', 'BS', 'IR', 'IP', 'ISO', 'BABIP', 'RC', 'PA/SO', 'K/BB']\nteam_perform = ['teamId', 'HR_team', 'IBB_team', 'TB_team', 'RBI_team', 'AVG_team', 'IR_team', 'IP_team', 'ISO_team', 'BABIP_team', 'RC_team', 'Pytha_WR']\nteam_features = ['divisionRank', 'leagueRank', 'wildCardRank', 'divWins', 'alWins', 'nlWins', 'pct', 'homeWins', 'xWinLossPct', 'team_followers']\nplayer_features = ['typeCode', 'transacted', 'numberOfFollowers', 'status', 'awarded_recnt']\ntime_features = ['year', 'month','day']","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:20.459817Z","iopub.execute_input":"2021-07-30T03:55:20.460118Z","iopub.status.idle":"2021-07-30T03:55:20.467441Z","shell.execute_reply.started":"2021-07-30T03:55:20.460088Z","shell.execute_reply":"2021-07-30T03:55:20.46581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_imp['color'] = ''\nfor i in feature_imp.index:\n    if i in player_perform:\n        feature_imp.loc[i, 'color'] = 'r'\n    elif i in player_features:\n        feature_imp.loc[i, 'color'] = 'y'\n    elif i in team_perform:\n        feature_imp.loc[i, 'color'] = 'g'\n    elif i in team_features:\n        feature_imp.loc[i, 'color'] = 'b'\n    else:\n        feature_imp.loc[i, 'color'] = 'cyan'","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:20.468837Z","iopub.execute_input":"2021-07-30T03:55:20.469166Z","iopub.status.idle":"2021-07-30T03:55:20.494043Z","shell.execute_reply.started":"2021-07-30T03:55:20.469135Z","shell.execute_reply":"2021-07-30T03:55:20.493026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y1_imp = feature_imp[['target1', 'color']].sort_values(by=['target1'], ascending = True)\ny2_imp = feature_imp[['target2', 'color']].sort_values(by=['target2'], ascending = True)\ny3_imp = feature_imp[['target3', 'color']].sort_values(by=['target3'], ascending = True)\ny4_imp = feature_imp[['target4', 'color']].sort_values(by=['target4'], ascending = True)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:20.495436Z","iopub.execute_input":"2021-07-30T03:55:20.495718Z","iopub.status.idle":"2021-07-30T03:55:20.508312Z","shell.execute_reply.started":"2021-07-30T03:55:20.495691Z","shell.execute_reply":"2021-07-30T03:55:20.50701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the 4 feature importance below, we can see that all the features are related to time features (the cyan bars) and player performance (the red bars\n). \n\nIn addition, the players' performance (red bar), status and twitter followers (yellow bar) are the most important for all the target measurements. \n\nHowever, team performance (green bar) and rankings (blue) in a season do not have much influence.","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(2, 2, figsize = (24,25), sharex = True)\naxs[0, 0].barh(y1_imp.index, y1_imp['target1'], color = y1_imp.color.values)\naxs[0, 0].set_title('feature importance for y1')\naxs[0, 1].barh(y2_imp.index, y2_imp['target2'], color = y2_imp.color.values)\naxs[0, 1].set_title('feature importance for y2')\naxs[1, 0].barh(y3_imp.index, y3_imp['target3'], color = y3_imp.color.values)\naxs[1, 0].set_title('feature importance for y3')\naxs[1, 1].barh(y4_imp.index, y4_imp['target4'], color = y4_imp.color.values)\naxs[1, 1].set_title('feature importance for y4')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:20.509603Z","iopub.execute_input":"2021-07-30T03:55:20.509935Z","iopub.status.idle":"2021-07-30T03:55:23.165324Z","shell.execute_reply.started":"2021-07-30T03:55:20.509906Z","shell.execute_reply":"2021-07-30T03:55:23.164346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If I enlarge the above 4 pictures and focus on the first 10 features, we can see something in common for the 4 measurements:\n* time features: \"day\" and \"month\" are always the most important for the 4 measurements;\n* player performances are also important factors.\n\nHowever, there are differences among the four measurements:\n* For target 1, player performances are the second most important features.\n\n* For target 2, number of team twitter followers has the most influence and the effect is much bigger than time features and player performances. Also, target 2 is affected by the combination of team expected winning percentage, player status, time and players' performances.\n\n* For target 3 is similar with target 2, except for time features, team twitter followers has some influence on it but not as big as it has for target 2. And the award a player received will also influence the values of target 3. \n\n* For target 4, time, players' award and tatus and also performances are important. And so does team twitter followers.","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(2, 2, figsize = (16,12), sharex = True)\naxs[0, 0].barh(y1_imp[-10:].index, y1_imp['target1'][-10:], color = y1_imp[-10:].color.values)\naxs[0, 0].set_title('feature importance for y1')\naxs[0, 1].barh(y2_imp[-10:].index, y2_imp['target2'][-10:], color = y2_imp[-10:].color.values)\naxs[0, 1].set_title('feature importance for y2')\naxs[1, 0].barh(y3_imp[-10:].index, y3_imp['target3'][-10:], color = y3_imp[-10:].color.values)\naxs[1, 0].set_title('feature importance for y3')\naxs[1, 1].barh(y4_imp[-10:].index, y4_imp['target4'][-10:], color = y4_imp[-10:].color.values)\naxs[1, 1].set_title('feature importance for y4')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:23.166547Z","iopub.execute_input":"2021-07-30T03:55:23.16687Z","iopub.status.idle":"2021-07-30T03:55:23.893988Z","shell.execute_reply.started":"2021-07-30T03:55:23.166842Z","shell.execute_reply":"2021-07-30T03:55:23.892751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If we look at the percentage of different feature categories in a whole, we can see that time is always the most important. Except for that, target 1 is affected a lot by players' performance in a game and target 2 is heavily affected by team related features such as twitter followers, team rankings and winning percentage, instead of team performances. ","metadata":{}},{"cell_type":"code","source":"grouped_feature = pd.DataFrame(columns = ['player_perform', 'player_features', 'team_perform', 'team_features', 'time_features'])\nfeature_imp = feature_imp.drop(['color'], axis = 1)\n\ngrouped_feature['player_perform'] = feature_imp.T[player_perform].mean(axis = 1)\ngrouped_feature['player_features'] = feature_imp.T[player_features].mean(axis = 1)\ngrouped_feature['team_perform'] = feature_imp.T[team_perform].mean(axis = 1)\ngrouped_feature['team_features'] = feature_imp.T[team_features].mean(axis = 1)\ngrouped_feature['time_features'] = feature_imp.T[time_features].mean(axis = 1)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:23.895637Z","iopub.execute_input":"2021-07-30T03:55:23.896099Z","iopub.status.idle":"2021-07-30T03:55:23.917241Z","shell.execute_reply.started":"2021-07-30T03:55:23.896056Z","shell.execute_reply":"2021-07-30T03:55:23.915826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"stacked_data = grouped_feature.apply(lambda x: x*100/sum(x), axis=1)\nstacked_data\n\nstacked_data.plot(kind=\"barh\", stacked=True, figsize = (12,4))\nplt.title(\"Feature importance in percentages for different targets\")\nplt.xlabel(\"Percentage\")\nplt.ylabel(\"Target measurements\")","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:23.919013Z","iopub.execute_input":"2021-07-30T03:55:23.919479Z","iopub.status.idle":"2021-07-30T03:55:24.21829Z","shell.execute_reply.started":"2021-07-30T03:55:23.919425Z","shell.execute_reply":"2021-07-30T03:55:24.217212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Among the player performance, we can see from the below bar plots that the defence scores are the most important and the offence scores ranks the second. ","metadata":{}},{"cell_type":"code","source":"pf = feature_imp.T[player_perform]\n\ndefence = ['FPCT', 'Out']\noffence = ['HR', 'IBB', 'TB', 'RBI', 'AVG']\npitching = ['SV_percnt', 'HLD', 'BS', 'IR', 'IP']\nadvanced = ['ISO', 'BABIP', 'RC', 'PA/SO', 'K/BB']\n\npf['defence'] = pf[defence].mean(axis = 1)\npf['offence'] = pf[offence].mean(axis = 1)\npf['pitching'] = pf[pitching].mean(axis = 1)\npf['advanced'] = pf[advanced].mean(axis = 1)\n\npf = pf.drop(defence+offence+pitching+advanced, axis = 1).T\n\npf['mean'] = pf.mean(axis = 1)\npf = pf.sort_values(by = 'mean', ascending = False).drop(['mean'], axis = 1)","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:24.219687Z","iopub.execute_input":"2021-07-30T03:55:24.220053Z","iopub.status.idle":"2021-07-30T03:55:24.242141Z","shell.execute_reply.started":"2021-07-30T03:55:24.220019Z","shell.execute_reply":"2021-07-30T03:55:24.241028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pf.plot(kind = 'bar')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:24.243337Z","iopub.execute_input":"2021-07-30T03:55:24.243633Z","iopub.status.idle":"2021-07-30T03:55:24.492458Z","shell.execute_reply.started":"2021-07-30T03:55:24.243604Z","shell.execute_reply":"2021-07-30T03:55:24.491442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Distribution of Time features","metadata":{}},{"cell_type":"markdown","source":"Since time features are important for all the measurements, I plot their difference among 2061 players to investigate their distributions.\n\nIn this part, I run randon forest model on different players and extract the feature importance. Since the model file is too large, I upload the results I obtained to kaggle, not the models.\n","metadata":{}},{"cell_type":"code","source":"feature_imp_y1 = pd.read_csv('../input/feature-imp/features_y1.csv', index_col=[0])\nfeature_imp_y2 = pd.read_csv('../input/feature-imp/features_y2.csv', index_col=[0])\nfeature_imp_y3 = pd.read_csv('../input/feature-imp/features_y3.csv', index_col=[0])\nfeature_imp_y4 = pd.read_csv('../input/feature-imp/features_y4.csv', index_col=[0])","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:24.493785Z","iopub.execute_input":"2021-07-30T03:55:24.494366Z","iopub.status.idle":"2021-07-30T03:55:25.1701Z","shell.execute_reply.started":"2021-07-30T03:55:24.494322Z","shell.execute_reply":"2021-07-30T03:55:25.169118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The plots below shows the distribution of the three time features for different target values. \n\n* The first row is the importance distribution for \"year\". For most players, the influence of \"year\" is under 0.02. The influence is slightly higher on average for target 2.\n\n* The second row shows the importance of feature \"month\". The effect of \"month\" is much more bigger than \"year\" since the distribution is centered around 0.2-0.3. As the plot for target 4 is leaning to the right, we can conclude that \"month\" has more influence on target 4.\n\n* The feature \"day\" shows a different distribution among different target values. For target 1, the distribution is flat and ranges from 0.1 to 0.6. which means the influence is very different for various players; for target 2, 3 and 4, the distribution is more concentrated around 0.3-0.4.","metadata":{}},{"cell_type":"code","source":"warnings.filterwarnings(\"ignore\", category=FutureWarning)\nfig, axes = plt.subplots(len(time_features), 4, figsize = (16,6), sharey = True, sharex = True)\nfea_list = [feature_imp_y1, feature_imp_y2, feature_imp_y3, feature_imp_y4]\nname_list = ['1', '2', '3', '4']\nfor i,j in enumerate(time_features):\n    for k in range(4):\n        df_plot = fea_list[k]\n        axes[i, k] = sns.distplot(df_plot.T[j], ax = axes[i,k])\n        axes[i, k].set_ylabel(j)\n        axes[i, k].set_xlabel('')\n        if i == 0:\n            axes[i, k].set_title('target'+ ' ' + name_list[k])","metadata":{"execution":{"iopub.status.busy":"2021-07-30T03:55:25.171367Z","iopub.execute_input":"2021-07-30T03:55:25.171643Z","iopub.status.idle":"2021-07-30T03:55:27.696272Z","shell.execute_reply.started":"2021-07-30T03:55:25.171616Z","shell.execute_reply":"2021-07-30T03:55:27.695114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To conclude, we find that:\n\n* The 4 target values have very different trend. \n\n* Target 4 has shown a cyclic feature while other values do not.\n\n* Time features and player performance related features are important for all measurements.\n\n* Among the player performance measurement, defence and offence scores are the most influential ones.\n\n* Team twitter followers has a big influence on target 2 but not on other target values.\n\n* Time feature influent players in a different way: \"day\" affect target 3 and 4 more than target 1; its influence on target 1 is very different among players.","metadata":{}}]}