{"cells":[{"metadata":{"_uuid":"cb616933e433ae1a0b75f5ff259e4dbc783e2ccf"},"cell_type":"markdown","source":"**Reduce the Punt as Concussions are hard to predict**\n\nThis is mainly just the data manipulation the main bulk of the conclusions has been drawn in the PDF"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"_kg_hide-input":false,"_kg_hide-output":false},"cell_type":"code","source":"#Set up area\nfrom mpl_toolkits.mplot3d import Axes3D\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn import tree #tree search\nfrom sklearn import svm #Support Vector Machine search\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.svm import LinearSVC\nfrom sklearn.naive_bayes import GaussianNB #Gaussian Naive Bayesian Classifier\nfrom sklearn.metrics import accuracy_score #Accuracy against validation\nimport matplotlib.pyplot as plt # plotting\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.calibration import calibration_curve \nimport numpy as np # linear algebra\nimport os # accessing directory structure\nfrom sklearn import datasets\nimport re\nimport seaborn as sns\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"414a907bc76b90e0cc00addf154ba7a7a8865b34"},"cell_type":"code","source":"#Set up data frames\nplayer_df = pd.read_csv ('../input/NFL-Punt-Analytics-Competition/player_punt_data.csv')\nplay_player_role_df = pd.read_csv ('../input/NFL-Punt-Analytics-Competition/play_player_role_data.csv')\nvideo_review_df = pd.read_csv('../input/NFL-Punt-Analytics-Competition/video_review.csv')\nplay_info_df = pd.read_csv ('../input/NFL-Punt-Analytics-Competition/play_information.csv')\ngame_info_df = pd.read_csv ('../input/NFL-Punt-Analytics-Competition/game_data.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0a1a3539387b14178b6e40ab945e3f5e3697d0f1"},"cell_type":"code","source":"# Merge player info\nmaster_player_df = pd.merge(player_df, play_player_role_df,\n                          how='inner',\n                          on=['GSISID'])\n\n# Megre game info\nmaster_game_df = pd.merge(game_info_df, play_info_df,\n                          how='inner',\n                          on=['GameKey'])\n# Combine play and player information into one super table\nmaster_df = pd.merge(master_player_df, master_game_df,\n                          how='inner',\n                          on=['GameKey','PlayID'])\n\n#Merge the punt injuries data into the table\nmaster_injury_df = pd.merge(master_df, video_review_df,\n                          how='outer',\n                          on=['GameKey','PlayID','GSISID'])\nmaster_injury_df.head()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9f465b3e098b17743a106de7c62b7cceb32c55ed"},"cell_type":"code","source":"# Remove data I consider uncritical for getting the results\ndrop = ['Season_Year_x','Season_Type_x','Game_Date_x','Game_Site','Home_Team','Visit_Team','Stadium','GameWeather','OutdoorWeather','Season_Year_y','Season_Type_y','Game_Date_y','Week_y','Play_Type']\nmaster_injury_df.drop(columns=drop, inplace=True)\nmaster_injury_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"18332615166ff93621cfb28bec90d041feb33c22"},"cell_type":"code","source":"#Convert Testing columns to ints\n# Convert timestamp to int\nmaster_injury_df['Start_Time'] = master_injury_df['Start_Time'].str.replace(\":\",\"\").values.astype(int)\n\n#Convert Game_Clock to int\nmaster_injury_df['Game_Clock'] = master_injury_df['Game_Clock'].str.replace(\":\",\"\").values.astype(int)\n\n#Convert Temp to int\nmaster_injury_df['Temperature'] = master_injury_df['Temperature'].values.astype(int)\n\n#Convert Positions to ints\nmaster_injury_df.loc[master_injury_df.Position == 'SS' , 'Position'] = 1 \nmaster_injury_df.loc[master_injury_df.Position == 'OLB' , 'Position'] = 2 \nmaster_injury_df.loc[master_injury_df.Position == 'WR' , 'Position'] = 3\nmaster_injury_df.loc[master_injury_df.Position == 'FS' , 'Position'] = 4 \nmaster_injury_df.loc[master_injury_df.Position == 'CB' , 'Position'] = 5 \nmaster_injury_df.loc[master_injury_df.Position == 'RB' , 'Position'] = 6 \nmaster_injury_df.loc[master_injury_df.Position == 'NT' , 'Position'] = 7 \nmaster_injury_df.loc[master_injury_df.Position == 'LS' , 'Position'] = 8 \nmaster_injury_df.loc[master_injury_df.Position == 'ILB' , 'Position'] = 9 \nmaster_injury_df.loc[master_injury_df.Position == 'DE' , 'Position'] = 10 \nmaster_injury_df.loc[master_injury_df.Position == 'FB' , 'Position'] = 11\nmaster_injury_df.loc[master_injury_df.Position == 'TE' , 'Position'] = 12 \nmaster_injury_df.loc[master_injury_df.Position == 'DT' , 'Position'] = 13\nmaster_injury_df.loc[master_injury_df.Position == 'MLB' , 'Position'] = 14\nmaster_injury_df.loc[master_injury_df.Position == 'K' , 'Position'] = 15\nmaster_injury_df.loc[master_injury_df.Position == 'P' , 'Position'] = 16\nmaster_injury_df.loc[master_injury_df.Position == 'LB' , 'Position'] = 17\nmaster_injury_df.loc[master_injury_df.Position == 'S' , 'Position'] = 18\nmaster_injury_df.loc[master_injury_df.Position == 'C' , 'Position'] = 19\nmaster_injury_df.loc[master_injury_df.Position == 'T' , 'Position'] = 20\nmaster_injury_df.loc[master_injury_df.Position == 'QB' , 'Position'] = 21\nmaster_injury_df.loc[master_injury_df.Position == 'DE' , 'Position'] = 22\nmaster_injury_df.loc[master_injury_df.Position == 'DB' , 'Position'] = 23\nmaster_injury_df.loc[master_injury_df.Position == 'G' , 'Position'] = 24\n\nmaster_injury_df['Position'] = master_injury_df['Position'].values.astype(int)\n\n#Convert Roles to ints\nmaster_injury_df.loc[master_injury_df.Role == 'GL' , 'Role'] = 1 \nmaster_injury_df.loc[master_injury_df.Role == 'GLi' , 'Role'] = 2 \nmaster_injury_df.loc[master_injury_df.Role == 'GLo' , 'Role'] = 3\nmaster_injury_df.loc[master_injury_df.Role == 'GR' , 'Role'] = 4 \nmaster_injury_df.loc[master_injury_df.Role == 'GRi' , 'Role'] = 5 \nmaster_injury_df.loc[master_injury_df.Role == 'GRo' , 'Role'] = 6 \nmaster_injury_df.loc[master_injury_df.Role == 'P' , 'Role'] = 7 \nmaster_injury_df.loc[master_injury_df.Role == 'PC' , 'Role'] = 8 \nmaster_injury_df.loc[master_injury_df.Role == 'PDL1' , 'Role'] = 9 \nmaster_injury_df.loc[master_injury_df.Role == 'PDL2' , 'Role'] = 10 \nmaster_injury_df.loc[master_injury_df.Role == 'PDL3' , 'Role'] = 11\nmaster_injury_df.loc[master_injury_df.Role == 'PDL4' , 'Role'] = 12 \nmaster_injury_df.loc[master_injury_df.Role == 'PDL5' , 'Role'] = 13\nmaster_injury_df.loc[master_injury_df.Role == 'PDL6' , 'Role'] = 14\nmaster_injury_df.loc[master_injury_df.Role == 'PDM' , 'Role'] = 15\nmaster_injury_df.loc[master_injury_df.Role == 'PDR1' , 'Role'] = 16\nmaster_injury_df.loc[master_injury_df.Role == 'PDR2' , 'Role'] = 17\nmaster_injury_df.loc[master_injury_df.Role == 'PDR3' , 'Role'] = 18\nmaster_injury_df.loc[master_injury_df.Role == 'PDR4' , 'Role'] = 19\nmaster_injury_df.loc[master_injury_df.Role == 'PDR5' , 'Role'] = 20\nmaster_injury_df.loc[master_injury_df.Role == 'PDR6' , 'Role'] = 21\nmaster_injury_df.loc[master_injury_df.Role == 'PFB' , 'Role'] = 22\nmaster_injury_df.loc[master_injury_df.Role == 'PLG' , 'Role'] = 23\nmaster_injury_df.loc[master_injury_df.Role == 'PLL' , 'Role'] = 24\nmaster_injury_df.loc[master_injury_df.Role == 'PLL1' , 'Role'] = 25 \nmaster_injury_df.loc[master_injury_df.Role == 'PLL2' , 'Role'] = 26\nmaster_injury_df.loc[master_injury_df.Role == 'PLL3' , 'Role'] = 27\nmaster_injury_df.loc[master_injury_df.Role == 'PLM' , 'Role'] = 28\nmaster_injury_df.loc[master_injury_df.Role == 'PLM1' , 'Role'] = 29\nmaster_injury_df.loc[master_injury_df.Role == 'PLR' , 'Role'] = 30\nmaster_injury_df.loc[master_injury_df.Role == 'PLR1' , 'Role'] = 31\nmaster_injury_df.loc[master_injury_df.Role == 'PLR2' , 'Role'] = 32\nmaster_injury_df.loc[master_injury_df.Role == 'PLR3' , 'Role'] = 33 \nmaster_injury_df.loc[master_injury_df.Role == 'PLS' , 'Role'] = 34\nmaster_injury_df.loc[master_injury_df.Role == 'PLT' , 'Role'] = 35 \nmaster_injury_df.loc[master_injury_df.Role == 'PLW' , 'Role'] = 36\nmaster_injury_df.loc[master_injury_df.Role == 'PPL' , 'Role'] = 37\nmaster_injury_df.loc[master_injury_df.Role == 'PPLi' , 'Role'] = 38\nmaster_injury_df.loc[master_injury_df.Role == 'PPLo' , 'Role'] = 39\nmaster_injury_df.loc[master_injury_df.Role == 'PPR' , 'Role'] = 40\nmaster_injury_df.loc[master_injury_df.Role == 'PPRi' , 'Role'] = 41\nmaster_injury_df.loc[master_injury_df.Role == 'PPRo' , 'Role'] = 42\nmaster_injury_df.loc[master_injury_df.Role == 'PR' , 'Role'] = 43\nmaster_injury_df.loc[master_injury_df.Role == 'PRG' , 'Role'] = 44\nmaster_injury_df.loc[master_injury_df.Role == 'PRT' , 'Role'] = 45\nmaster_injury_df.loc[master_injury_df.Role == 'PRW' , 'Role'] = 46\nmaster_injury_df.loc[master_injury_df.Role == 'VL' , 'Role'] = 47\nmaster_injury_df.loc[master_injury_df.Role == 'VLi' , 'Role'] = 48\nmaster_injury_df.loc[master_injury_df.Role == 'VLo' , 'Role'] = 49\nmaster_injury_df.loc[master_injury_df.Role == 'VR' , 'Role'] = 50\nmaster_injury_df.loc[master_injury_df.Role == 'VRi' , 'Role'] = 51\nmaster_injury_df.loc[master_injury_df.Role == 'VRo' , 'Role'] = 52\n\n\nmaster_injury_df['Role'] = master_injury_df['Role'].values.astype(int)\n\n#Game Day number\nmaster_injury_df.loc[master_injury_df.Game_Day == 'Thursday' , 'Game_Day'] = 1 \nmaster_injury_df.loc[master_injury_df.Game_Day == 'Friday' , 'Game_Day'] = 2 \nmaster_injury_df.loc[master_injury_df.Game_Day == 'Saturday' , 'Game_Day'] = 3\nmaster_injury_df.loc[master_injury_df.Game_Day == 'Sunday' , 'Game_Day'] = 4 \nmaster_injury_df.loc[master_injury_df.Game_Day == 'Monday' , 'Game_Day'] = 5 \nmaster_injury_df.loc[master_injury_df.Game_Day == 'Tuesday' , 'Game_Day'] = 6 \nmaster_injury_df.loc[master_injury_df.Game_Day == 'Wednesday' , 'Game_Day'] = 7 \n\nmaster_injury_df['Game_Day'] = master_injury_df['Game_Day'].values.astype(int)\n\n#Name Field Types ints\nmaster_injury_df.loc[master_injury_df.Turf == '', 'Turf'] = 1 \nmaster_injury_df.loc[master_injury_df.Turf == 'A-Turf Titan', 'Turf'] = 2 \nmaster_injury_df.loc[master_injury_df.Turf == 'Artifical', 'Turf'] = 3\nmaster_injury_df.loc[master_injury_df.Turf == 'Artificial', 'Turf'] = 3\nmaster_injury_df.loc[master_injury_df.Turf == 'AstroTurf GameDay Grass 3D' , 'Turf'] = 4 \nmaster_injury_df.loc[master_injury_df.Turf == 'DD GrassMaster' , 'Turf'] = 5 \nmaster_injury_df.loc[master_injury_df.Turf == 'Field turf' , 'Turf'] = 6 \nmaster_injury_df.loc[master_injury_df.Turf == 'Field Turf' , 'Turf'] = 6 \nmaster_injury_df.loc[master_injury_df.Turf == 'FieldTurf' , 'Turf'] = 6 \nmaster_injury_df.loc[master_injury_df.Turf == 'FieldTurf 360' , 'Turf'] = 7 \nmaster_injury_df.loc[master_injury_df.Turf == 'FieldTurf360' , 'Turf'] = 7 \nmaster_injury_df.loc[master_injury_df.Turf == 'grass' , 'Turf'] = 8\nmaster_injury_df.loc[master_injury_df.Turf == 'Grass' , 'Turf'] = 8 \nmaster_injury_df.loc[master_injury_df.Turf == 'Natrual Grass' , 'Turf'] = 9 \nmaster_injury_df.loc[master_injury_df.Turf == 'Natural Grass' , 'Turf'] = 9 \nmaster_injury_df.loc[master_injury_df.Turf == 'Natural grass' , 'Turf'] = 9\nmaster_injury_df.loc[master_injury_df.Turf == 'Naturall Grass' , 'Turf'] = 9\nmaster_injury_df.loc[master_injury_df.Turf == 'Natural Grass ' , 'Turf'] = 9\nmaster_injury_df.loc[master_injury_df.Turf == 'Natural' , 'Turf'] = 10 \nmaster_injury_df.loc[master_injury_df.Turf == 'Synthetic' , 'Turf'] = 12 \nmaster_injury_df.loc[master_injury_df.Turf == 'Turf' , 'Turf'] = 13\nmaster_injury_df.loc[master_injury_df.Turf == 'UBU Speed Series S5-M' , 'Turf'] = 14\nmaster_injury_df.loc[master_injury_df.Turf == 'UBU Speed Series-S5-M' , 'Turf'] = 14\nmaster_injury_df.loc[master_injury_df.Turf == 'UBU Sports Speed S5-M' , 'Turf'] = 15\nmaster_injury_df['Turf'] = pd.to_numeric(master_injury_df['Turf'], errors='0')\n                     \nmaster_injury_df['Turf'] = master_injury_df['Turf'].values.astype(int)\n\n\n\n\nmaster_injury_df.head()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fb20cefc1a47063a6f13fb2af2ec1798e0da9db2"},"cell_type":"code","source":"#Greate a colum to identify concussion plays, this is not a clean way\nmaster_injury_df.loc[master_injury_df.Turnover_Related != 'No' , 'Concussion'] = 'No' \nmaster_injury_df.loc[master_injury_df.Turnover_Related == 'No', 'Concussion'] = 'Yes' \n\nmaster_injury_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"09038f73807189ef00de5356c62c055db09513f1"},"cell_type":"code","source":"train, test = train_test_split(master_injury_df, test_size=0.2)\ntestlen = len(test)\nprint(testlen)\n\ntrainlen = len(train)\nprint(trainlen)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"90a53f7334310e790e2aecd3e906ca1b51997513"},"cell_type":"code","source":"#Set training data\nXtrain = train[['Start_Time', 'Week_x','Position','Role','Game_Day','Temperature','Game_Clock','Turf']].values\nYtrain = train['Concussion']\n\nXtest = test[['Start_Time', 'Week_x','Position','Role','Game_Day','Temperature','Game_Clock','Turf']].values\nYtest = test['Concussion']\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a3411f060e681705d4d867e1e28b5a5e343c457c"},"cell_type":"code","source":"#Set Classifiers\nclfgnb = GaussianNB()\nclfsvm = svm.SVC()\nclftree = tree.DecisionTreeClassifier()\nlr = LogisticRegression(solver='lbfgs')\nsvc = LinearSVC(C=1.0)\nrfc = RandomForestClassifier(n_estimators=100)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"22ed9a517757b69ee489475acd61e3b73a69328c"},"cell_type":"code","source":"plt.figure(figsize=(10, 10))\nax1 = plt.subplot2grid((3, 1), (0, 0), rowspan=2)\nax2 = plt.subplot2grid((3, 1), (2, 0))\n\nax1.plot([0, 1], [0, 1], \"k:\", label=\"Perfectly calibrated\")\nfor clf, name in [\n                  (clfgnb, 'Naive Bayes'),\n                    (clfsvm, 'SVM'),\n                    (clftree, 'Decision Tree'),\n                    (lr, 'Logistic'),\n                  (svc, 'Support Vector Classification'),\n                  (rfc, 'Random Forest')]:\n    clf.fit(Xtrain, Ytrain)\n    if hasattr(clf, \"predict_proba\"):\n        prob_pos = clf.predict_proba(Xtest)[:, 1]\n    else:  # use decision function\n        prob_pos = clf.decision_function(Xtest)\n        prob_pos = \\\n            (prob_pos - prob_pos.min()) / (prob_pos.max() - prob_pos.min())\n    fraction_of_positives, mean_predicted_value = \\\n        calibration_curve(Ytest, prob_pos, n_bins=10)\n\n    ax1.plot(mean_predicted_value, fraction_of_positives, \"s-\",\n             label=\"%s\" % (name, ))\n\n    ax2.hist(prob_pos, range=(0, 1), bins=10, label=name,\n             histtype=\"step\", lw=2)\n\nax1.set_ylabel(\"Fraction of positives\")\nax1.set_ylim([-0.05, 1.05])\nax1.legend(loc=\"lower right\")\nax1.set_title('Calibration plots  (reliability curve)')\n\nax2.set_xlabel(\"Mean predicted value\")\nax2.set_ylabel(\"Count\")\nax2.legend(loc=\"upper center\", ncol=2)\n\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3b32134212ec64939c28ff8e67741b1ef4fb5c0d"},"cell_type":"markdown","source":"**Classifier Conclusions**\n\nMy attempts to build a classifier shows its very hard to determine if someone will get a concussion from preplay information such as the person's position at the start of the play, field conditions or time of game.  Though using further analysis of next gen data you may be able to work out if someone is about to suffer a concussion this is to late to change the situation of a play in football.  My conclusion from this is one individual change to aspect of punts or playing conditions is unlikely to reduce the likelihood of concussion. Similar in the way that changing multiple factors of kickoff was required to reduce the rate of concussions. This makes it a challenge to break apart what aspects of the play you need to adjust and one I think is hard to meet. \n\nAs I was unable to predict which plays were likely to result in concussion, it makes it very hard to target which aspects of the play I should alter. Therefore I believe rather than trying to make punts safer, the best way to reduce concussions from punts is to attempt to reduce the number of punts. I want to look at this below. \n"},{"metadata":{"trusted":true,"_uuid":"f4612dbbf19bfbc89fd9b95fea1695d3e82caf14"},"cell_type":"code","source":"#Set the next gen stat files forked from https://www.kaggle.com/hallayang/nfl-punt-analytics-proposal\n\nngs_files = ['../input/NFL-Punt-Analytics-Competition/NGS-2016-pre.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2016-reg-wk1-6.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2016-reg-wk7-12.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2016-reg-wk13-17.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2016-post.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2017-pre.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2017-reg-wk1-6.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2017-reg-wk7-12.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2017-reg-wk13-17.csv',\n             '../input/NFL-Punt-Analytics-Competition/NGS-2017-post.csv']\n\npuntfiles_df = pd.read_csv ('../input/punt-avg/NFLpunt.csv')\nplayfile_df = pd.read_csv ('../input/playsavg/plays.csv')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"da80215bd065df91fd87bd376f64b4c9950c91d4"},"cell_type":"code","source":"#Work out return length, fair catch and if there was an injury forked from https://www.kaggle.com/hallayang/nfl-punt-analytics-proposal\n\nplays_df = pd.read_csv('../input/NFL-Punt-Analytics-Competition/play_information.csv')\n\ndef get_return_yards(s):\n    m = re.search('for ([0-9]+) yards', s)\n    if m:\n        return int(m.group(1))\n    elif re.search('for no gain', s):\n        return 0\n    else:\n        return np.nan\n\nplays_df['Return'] = plays_df['PlayDescription'].map(\n        lambda x: get_return_yards(x))\n\nvideo_review = pd.read_csv('../input/NFL-Punt-Analytics-Competition/video_review.csv')\nvideo_review = video_review.rename(columns={'GSISID': 'InjuredGSISID'})\n\nplays_df= plays_df.merge(video_review, how='left',\n                         on=['Season_Year', 'GameKey', 'PlayID'])\n\nplays_df['InjuryOnPlay'] = 0\nplays_df.loc[plays_df['InjuredGSISID'].notnull(), 'InjuryOnPlay'] = 1\n\nplays_df = plays_df[['Season_Year', 'GameKey', 'PlayID', 'Return', 'InjuryOnPlay']]\n\nngs_df = []\nfor filename in ngs_files:\n    df = pd.read_csv(filename, parse_dates=['Time'])\n    df = df.loc[df['Event'].isin(['fair_catch', 'punt_received'])]\n    df = pd.concat([df, pd.get_dummies(df['Event'])], axis=1)\n    df = df.groupby(['Season_Year', 'GameKey', 'PlayID'])[['fair_catch', 'punt_received']].max()\n    ngs_df.append(df.reset_index())\nngs_df = pd.concat(ngs_df)\n\nplays_df = plays_df.merge(ngs_df, on=['Season_Year', 'GameKey', 'PlayID'])\n\nplays_df.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0faa6000d42052318cfaca346b098a712e11a93b"},"cell_type":"markdown","source":"[USA Today Reports](https://eu.usatoday.com/story/sports/nfl/2018/01/26/nfl-concussions-2017-season-study-history/1070344001/) that there was a total of 281 concussions total in the NFL in 2017\n\n\n[Fortune reports](http://fortune.com/2017/01/29/nfl-concussions-2016/) that there was a total of 244  concussions total in the NFL in 2016\n\n[Avg Plays per game](https://www.teamrankings.com/nfl/stat/plays-per-game)"},{"metadata":{"trusted":true,"_uuid":"756bceae21676580a962524c9aa472e73172a868"},"cell_type":"code","source":"#Working out the concusion rate per 1000 non punt plays\n\nTotconc = (281 + 244)\n\nnonpuntconc = Totconc - len(video_review_df.index)\n\nplayfile_df['Average 16/17']= playfile_df['2017'] + playfile_df['2016']\n\navgtotplay = (playfile_df['Average 16/17'].sum())*64\n\ninjury_per_1000_non_punt = ((nonpuntconc/avgtotplay)*1000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a2d5cf0c32560da52ce636e934af5a6ae42ab0b4"},"cell_type":"code","source":"#Visulise concission rates forked from https://www.kaggle.com/hallayang/nfl-punt-analytics-proposal\n\ninjury_per_1000_fair_catch = 1000 * plays_df.loc[plays_df['fair_catch']==1,\n                                          'InjuryOnPlay'].mean()\ninjury_per_1000_punt_received = 1000 * plays_df.loc[plays_df['punt_received']==1,\n                                           'InjuryOnPlay'].mean()\nfig = plt.figure()\nax = plt.subplot2grid((1, 1), (0, 0))\nplt.bar([0, 1, 2], [injury_per_1000_fair_catch, injury_per_1000_punt_received,injury_per_1000_non_punt])\nax.set_xticks([0, 1, 2])\nax.set_xticklabels(['Fair Catch', 'Punt Received','Non Punt Plays'])\nplt.text(0, injury_per_1000_fair_catch+0.2, '{:.1f}'.format(injury_per_1000_fair_catch))\nplt.text(1, injury_per_1000_punt_received+0.2, '{:.1f}'.format(injury_per_1000_punt_received))\nplt.text(2, injury_per_1000_non_punt+0.2, '{:.1f}'.format(injury_per_1000_non_punt))\nplt.title(\"Concussion Rate\")\nplt.ylabel(\"Injuries per 1000 Events\")\nsns.despine(top=True, right=True)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a100e54e5f2b6974c63c1a69585ca320bfbd2402"},"cell_type":"markdown","source":""},{"metadata":{"trusted":true,"_uuid":"ade18c24cff629ecfa1872b3b465d379c0654cc6"},"cell_type":"code","source":"#Visulise return lengths forked from https://www.kaggle.com/hallayang/nfl-punt-analytics-proposal\n\n\nx_groups = ['0-3 yds', '3-5 yds', '5-7 yds', '7-9 yds',\n            '9-12 yds', '12-15 yds', '15-20 yds', '20+ yds']\nrec = plays_df.loc[(plays_df['punt_received']==1) \n                   &(plays_df['Return'].notnull())]\n\ny_groups = [sum(rec['Return']<=3) / len(rec),\n            sum((rec['Return']>3) & (rec['Return']<=5)) / len(rec),\n            sum((rec['Return']>5) & (rec['Return']<=7)) / len(rec),\n            sum((rec['Return']>7) & (rec['Return']<=9)) / len(rec),\n            sum((rec['Return']>9) & (rec['Return']<=12)) / len(rec),\n            sum((rec['Return']>12) & (rec['Return']<=15)) / len(rec),\n            sum((rec['Return']>15) & (rec['Return']<=20))/ len(rec),\n            sum(rec['Return']>20) / len(rec)]\n\ny_bottoms = [0,\n             sum(rec['Return']<=3) / len(rec),\n             sum(rec['Return']<=5) / len(rec),\n             sum(rec['Return']<=7) / len(rec),\n             sum(rec['Return']<=9) / len(rec),\n             sum(rec['Return']<=12) / len(rec),\n             sum(rec['Return']<=15) / len(rec),\n             sum(rec['Return']<=20) / len(rec)]\n\nfig = plt.figure(figsize=(8.5,4.5))\nax = plt.subplot2grid((1, 1), (0, 0))\nplt.bar(range(len(x_groups)), y_groups, bottom=y_bottoms)\nax.set_xticks(range(len(x_groups)))\nax.set_xticklabels(x_groups)\nax.set_yticks([0, 0.2, 0.4, 0.6, 0.8, 1.0])\nax.set_yticklabels(['0%', '20%', '40%', '60%', '80%', '100%'])\nfor i in range(len(x_groups)):\n    plt.text(i-0.2, y_bottoms[i]+y_groups[i]+0.02, '{:.0f}%'.format(100*y_groups[i]))\nsns.despine(top=True, right=True)\nplt.title(\"Distribution of Punt Returns by Length\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b095acf6afbe093d639323ca35dc6aeaf0195340"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"dc2263df3145b81ac420d4b2b25bff991dfe9fb4"},"cell_type":"markdown","source":"[Average Punt length of 2018](http://www.espn.com/nfl/statistics/team/_/stat/punting/sort/grossAvgPuntYards/seasontype/2)"},{"metadata":{"trusted":true,"_uuid":"f18dbb2926e25cf9db8e2f9bb08cd0b67b5bff8d","_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"#Work out average of average punt length of 2018 data source is http://www.espn.com/nfl/statistics/team/_/stat/punting/sort/grossAvgPuntYards/seasontype/2\n\n(puntfiles_df['AVG']).plot.bar()\npuntfiles_df['AVG'].mean()\n\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2e6a5c2e2341b3c8e7f1f1c685f2977b8092a0c7"},"cell_type":"markdown","source":"**Punt Conclusions**\n\nFrom looking at punt concussion data returning the punt is clearly the most dangerous aspect of the play so if you can encourage punt plays where they are returned you will reduce concussion rates. As per the diagram above you can see that fair catches concussion rates align very closely with concussion rates of non punt plays. \n\nIf strictly you wanted to increase the safety of the game whilst keeping it in the same balance you could simply offer additional 5yds from the spot of the fair catch. This would be in line with the average return distance and likely encourage fair catches. \n\nThis addition of Yds for making no play though runs counter to a lot of other aims in football to make the game exciting. Therefore I would suggest the option of if a 4th down attempt is failed within a teams own half the ball is turned over 20 Yds further down field from the spot. This is significantly shorter than the average punt length. But would encourage teams to go for it on 4th down increasing excitement, without the increased risk of injuries punts bring.\n"}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}