{"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":"# Introduction","metadata":{}},{"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\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":{"execution":{"iopub.status.busy":"2022-01-06T21:29:51.690207Z","iopub.execute_input":"2022-01-06T21:29:51.690768Z","iopub.status.idle":"2022-01-06T21:29:51.701839Z","shell.execute_reply.started":"2022-01-06T21:29:51.690713Z","shell.execute_reply":"2022-01-06T21:29:51.701350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The 2022 Big Data Bowl data contains Next Gen Stats player tracking, play, game, player, and PFF scouting data for all 2018-2020 Special Teams plays. Here, you'll find a summary of each data set in the 2022 Data Bowl, a list of key variables to join on, and a description of each variable.\n\nThis notebook analyzes data on punt plays to show various strategies The code utilizes the provided game data, play data, and scouting data.","metadata":{}},{"cell_type":"markdown","source":"This notebook was created by data science students as a project to gain experience in real-world data science applications. Please feel free to provide suggestions and comments to help improve our knowledge.","metadata":{}},{"cell_type":"code","source":"#Import some useful, common python libraries\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly.express as px\nfrom datetime import datetime\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":1.533671,"end_time":"2021-12-11T19:06:02.158611","exception":false,"start_time":"2021-12-11T19:06:00.62494","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-06T21:29:51.705646Z","iopub.execute_input":"2022-01-06T21:29:51.706079Z","iopub.status.idle":"2022-01-06T21:29:52.622878Z","shell.execute_reply.started":"2022-01-06T21:29:51.706024Z","shell.execute_reply":"2022-01-06T21:29:52.621929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Load the datasets from the kaggle page\n\n# Date/Time/Etc of games and who played\ngames = pd.read_csv('../input/nfl-big-data-bowl-2022/games.csv')\n\n# Info about a specific play\nplays = pd.read_csv('../input/nfl-big-data-bowl-2022/plays.csv')\n\n# Play-level scouting info for each game\nscouting = pd.read_csv('../input/nfl-big-data-bowl-2022/PFFScoutingData.csv')","metadata":{"_kg_hide-input":true,"papermill":{"duration":0.202439,"end_time":"2021-12-11T19:06:02.701781","exception":false,"start_time":"2021-12-11T19:06:02.499342","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-06T21:29:52.624067Z","iopub.execute_input":"2022-01-06T21:29:52.624283Z","iopub.status.idle":"2022-01-06T21:29:52.752817Z","shell.execute_reply.started":"2022-01-06T21:29:52.624257Z","shell.execute_reply":"2022-01-06T21:29:52.752011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Cleaning the Data","metadata":{}},{"cell_type":"markdown","source":"The \"scouting\" and \"plays\" datasets are similar in content and size, so they were merged. This gives us a greater amount of information in a more concise manner.","metadata":{}},{"cell_type":"code","source":"print(\"Scouting data shape:\",scouting.shape)\nprint(\"Play data shape:\", plays.shape)\nmerged_df = pd.merge(scouting, plays, on=['gameId', 'playId'])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:52.754701Z","iopub.execute_input":"2022-01-06T21:29:52.754898Z","iopub.status.idle":"2022-01-06T21:29:52.797746Z","shell.execute_reply.started":"2022-01-06T21:29:52.754874Z","shell.execute_reply":"2022-01-06T21:29:52.796937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_df = merged_df.loc[merged_df[\"specialTeamsPlayType\"] == \"Punt\"]\nmerged_df.reset_index(inplace=True,drop=True)\nmerged_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:52.799602Z","iopub.execute_input":"2022-01-06T21:29:52.800047Z","iopub.status.idle":"2022-01-06T21:29:52.843464Z","shell.execute_reply.started":"2022-01-06T21:29:52.800003Z","shell.execute_reply":"2022-01-06T21:29:52.842893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we check for the number of unique values for each column in the dataframe. Because the goal is to determine how these values affects the punt result, if there is only 1 unique value within the column then that feature is not helpful and therefore dropped. For example, the \"down\" column only contains 1 value, meaning that punts will only occur during 1 specific down (in this instance, punts only occur in the 4th down). This will not help in determining a strategy, so it will be dropped.\n\nIf a column contains no unique values, it indicates that the feature does not apply to the play. For example, Kickoff Formations do not exist for punt plays, so it has a value of 0 and will be dropped.","metadata":{}},{"cell_type":"code","source":"merged_df.nunique()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:52.844420Z","iopub.execute_input":"2022-01-06T21:29:52.844720Z","iopub.status.idle":"2022-01-06T21:29:52.869831Z","shell.execute_reply.started":"2022-01-06T21:29:52.844694Z","shell.execute_reply":"2022-01-06T21:29:52.869286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Once the columns are dropped, we can see the remaining columns in our dataframe.","metadata":{}},{"cell_type":"code","source":"columnsToDrop = ['kickoffReturnFormation','down','specialTeamsPlayType','kickerId','kickBlockerId',\n                 'penaltyJerseyNumbers','playDescription']\n\nstrategy_df = merged_df.drop(columns=columnsToDrop)\nstrategy_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:52.870766Z","iopub.execute_input":"2022-01-06T21:29:52.871072Z","iopub.status.idle":"2022-01-06T21:29:52.894278Z","shell.execute_reply.started":"2022-01-06T21:29:52.871046Z","shell.execute_reply":"2022-01-06T21:29:52.893134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next, several of the existing columns are edited so the data is in a format that will be easier to use in our model later.","metadata":{}},{"cell_type":"markdown","source":"A new column called \"tacklers\" is created to represent the total number of tacklers involved with the attempted tackle on the play. This is done by summing the counts of players from the \"missedTackler\", \"assistTackler\", and \"tackler\" columns, and will replace those features in the dataframe. This was done to determine if the number of players involved would affect the play result.","metadata":{}},{"cell_type":"code","source":"# Replaces \"missedTackler\", \"assistTackler\", and \"tackler\" columns with one \"tacklers\" column that contains\n# the total number of tacklers involved in the play.\n\ndef tacklers(row):\n    tacklers = 0\n    if pd.notnull(row['missedTackler']):\n        tacklers = tacklers + row['missedTackler'].count(\";\") + 1\n    if pd.notnull(row['tackler']):\n         tacklers = tacklers + row['tackler'].count(\";\") + 1\n    if pd.notnull(row['assistTackler']):\n        tacklers = tacklers + row['assistTackler'].count(\";\") + 1\n    return tacklers\n        \nstrategy_df['tacklers'] = strategy_df.apply(lambda row: tacklers(row), axis=1)\nstrategy_df.drop(columns=['tackler','assistTackler','missedTackler'],inplace=True)\nstrategy_df[['tacklers','specialTeamsResult']].head(10)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:52.895738Z","iopub.execute_input":"2022-01-06T21:29:52.896163Z","iopub.status.idle":"2022-01-06T21:29:53.060911Z","shell.execute_reply.started":"2022-01-06T21:29:52.896122Z","shell.execute_reply":"2022-01-06T21:29:53.060049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A similar method was used for \"gunners\", \"puntRushers\", \"specialTeamsSafeties\", and \"vises\" - the values for these features were replaced with an integer representing the total number of players for each position associated with the play.","metadata":{}},{"cell_type":"code","source":"# Replaces the values for \"gunners\", \"puntRushers\", \"specialTeamsSafteties\", and \"vises\" with the number of players\n# for each respective position involved in the play.\ndef positionPlayers(row):\n    players = 0\n    if pd.notnull(row):\n        players = players + row.count(\";\") + 1\n    return players\n\nstrategy_df['gunners'] = strategy_df['gunners'].apply(lambda row: positionPlayers(row))\nstrategy_df['puntRushers'] = strategy_df['puntRushers'].apply(lambda row: positionPlayers(row))\nstrategy_df['specialTeamsSafeties'] = strategy_df['specialTeamsSafeties'].apply(lambda row: positionPlayers(row))\nstrategy_df['vises'] = strategy_df['vises'].apply(lambda row: positionPlayers(row))\nstrategy_df[['gunners','puntRushers','specialTeamsSafeties','vises']].head(10)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:53.062723Z","iopub.execute_input":"2022-01-06T21:29:53.063023Z","iopub.status.idle":"2022-01-06T21:29:53.107833Z","shell.execute_reply.started":"2022-01-06T21:29:53.062983Z","shell.execute_reply":"2022-01-06T21:29:53.107289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next, two additional columns are created to provide better contextual information for each play. \n\nThe new \"yardsToEndzone\" column replaces the previous \"absoluteYardlineNumber\" and \"yardlineNumber\" to represent the yards to go to the possession team's respective end zone. This gives a better indication of the remaining distance that needs to be closed in the following plays.\n\nThe new \"pointDifference\" column replaces the \"preSnapVisitorScore\" and \"preSnapHomeScore\" to indicate the magnitude of points that the possession team is winning or losing compared to the opposing team. While the pre-snap scores are useful, it does not indicate whether the possession team is the home team or visiting team. This feature may be important in determining whether there is a change in strategy based on the team scores.","metadata":{}},{"cell_type":"code","source":"# Based on whether the possession team is the home team or visiting team, this function adds \n# additional columns to the dataset listing the total yards until the opposite endzone, and the \n# magnitude of points above/below the opposing team's score.\n\ndef winOrLose(row):\n    points = 0\n    yards = 0\n    if  games.loc[games['gameId'] == row['gameId'], 'homeTeamAbbr'].item() == row['possessionTeam']:\n        yards = 120 - 10 - row['absoluteYardlineNumber']\n        points = row['preSnapHomeScore'] - row['preSnapVisitorScore']\n        return yards, points\n    else:\n        row['possessionTeam'] = 'Visitor'\n        yards = row['absoluteYardlineNumber'] - 10\n        points = row['preSnapVisitorScore'] - row['preSnapHomeScore']\n        return yards, points\n    return 'Something went wrong'\nvalues = strategy_df.apply(lambda row: winOrLose(row), axis=1)\nstrategy_df['yardsToEndzone'] = [values[i][0] for i in range(0, strategy_df.shape[0])]\nstrategy_df['pointDifference'] = [values[i][1] for i in range(0, strategy_df.shape[0])]\nstrategy_df.drop(columns=['preSnapHomeScore','preSnapVisitorScore','absoluteYardlineNumber', 'yardlineNumber'], inplace=True)\nstrategy_df[['yardsToEndzone','pointDifference']].head(10)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:53.108797Z","iopub.execute_input":"2022-01-06T21:29:53.109007Z","iopub.status.idle":"2022-01-06T21:29:54.940970Z","shell.execute_reply.started":"2022-01-06T21:29:53.108981Z","shell.execute_reply":"2022-01-06T21:29:54.939968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The time remaining on the game clock may be an important feature when determining a punt strategy. The time format exists as a string, so here it is converted into a numeric value representing the number of seconds left on the clock.","metadata":{}},{"cell_type":"code","source":"strategy_df['gameClock'] = pd.to_datetime(strategy_df['gameClock'], format='%M:%S:%f').dt.time\nstrategy_df['gameClock'] = strategy_df['gameClock'].apply(lambda x: (x.minute*60 + x.second))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:54.942084Z","iopub.execute_input":"2022-01-06T21:29:54.942325Z","iopub.status.idle":"2022-01-06T21:29:54.969889Z","shell.execute_reply.started":"2022-01-06T21:29:54.942298Z","shell.execute_reply":"2022-01-06T21:29:54.968988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"strategy_df[['gameClock','quarter']].head(10)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:54.971277Z","iopub.execute_input":"2022-01-06T21:29:54.971841Z","iopub.status.idle":"2022-01-06T21:29:54.991563Z","shell.execute_reply.started":"2022-01-06T21:29:54.971792Z","shell.execute_reply":"2022-01-06T21:29:54.990988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we check for numerical columns with a null values. In this case, the null values for several columns representing time or distance are filled with \"0\" to indicate that the particular value does not exist for the corresponding play.","metadata":{}},{"cell_type":"code","source":"strategy_df.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:54.993889Z","iopub.execute_input":"2022-01-06T21:29:54.994223Z","iopub.status.idle":"2022-01-06T21:29:55.005655Z","shell.execute_reply.started":"2022-01-06T21:29:54.994194Z","shell.execute_reply":"2022-01-06T21:29:55.004897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"strategy_df['penaltyYards'].fillna(0, inplace=True)\nstrategy_df['kickLength'].fillna(0, inplace=True)\nstrategy_df['hangTime'].fillna(0, inplace=True)\nstrategy_df['operationTime'].fillna(0, inplace=True)\nstrategy_df['snapTime'].fillna(0, inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.006859Z","iopub.execute_input":"2022-01-06T21:29:55.007097Z","iopub.status.idle":"2022-01-06T21:29:55.013590Z","shell.execute_reply.started":"2022-01-06T21:29:55.007069Z","shell.execute_reply":"2022-01-06T21:29:55.012790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualizations","metadata":{}},{"cell_type":"markdown","source":"Next, we visualize some of the features within the dataframe. \n\nFirst, we use the new \"yardsToEndzone\" column to see whether punt plays occur at specific distances.","metadata":{}},{"cell_type":"code","source":"puntLocation = strategy_df.groupby(['yardsToEndzone']).nunique().reset_index()[['yardsToEndzone','playId']]\nfig = px.bar(puntLocation, \n             x='yardsToEndzone', \n             y='playId',\n             labels={'yardsToEndzone':'Yards To Endzone',\n                   'playId':'Number of Punts Attempted'}\n            )\nfig.update_layout(title_text='Number of Punts Attempted by Distance to Endzone')\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.014741Z","iopub.execute_input":"2022-01-06T21:29:55.015299Z","iopub.status.idle":"2022-01-06T21:29:55.424303Z","shell.execute_reply.started":"2022-01-06T21:29:55.015260Z","shell.execute_reply":"2022-01-06T21:29:55.423540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the graph above, we see that there is a wide distribution of punts occurring at different yardlines. Therefore, there is not a strong indication for choosing to make a punt play based on distance to go to the endzone.","metadata":{}},{"cell_type":"markdown","source":"Below we see the distribution of results following a punt play. The most common result is a return, followed by a fair catch. ","metadata":{}},{"cell_type":"code","source":"puntResult = strategy_df.groupby(['specialTeamsResult']).nunique().reset_index()[['specialTeamsResult','playId']]\n\nfig = px.bar(puntResult, \n             x='specialTeamsResult', \n             y='playId',\n             labels={'specialTeamsResult':'Result of punts',\n                   'playId':'Number of plays'}\n            )\nfig.update_layout(title_text='Number of plays per punt result')\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.425417Z","iopub.execute_input":"2022-01-06T21:29:55.425621Z","iopub.status.idle":"2022-01-06T21:29:55.514625Z","shell.execute_reply.started":"2022-01-06T21:29:55.425594Z","shell.execute_reply":"2022-01-06T21:29:55.514072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The averages below based on punt result type show an interesting depcition of usefulness in gaining yards. On first thought, it would be fair to assume that a punt return would garner a lot more yards than a fair catch because the punt returner has the opportunity to run the ball and gain more yards. However, we find in this graph that there is no substantial difference in yardage gained, which means that in a lot of cases it might be more efficient, in terms of energy costs and injury, to call a fair catch.","metadata":{}},{"cell_type":"code","source":"means = strategy_df.groupby('specialTeamsResult')['playResult'].mean().reset_index()[['specialTeamsResult','playResult']]\nfig = px.bar(means,\n             x='specialTeamsResult', \n             y='playResult',\n             labels={'specialTeamsResult':'Punt Results', 'playResult': 'Yard Results'})\nfig.update_layout(title_text='Number of yards gained/lost per punt result')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.515587Z","iopub.execute_input":"2022-01-06T21:29:55.515885Z","iopub.status.idle":"2022-01-06T21:29:55.572471Z","shell.execute_reply.started":"2022-01-06T21:29:55.515860Z","shell.execute_reply":"2022-01-06T21:29:55.571463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Building a Basic Model","metadata":{}},{"cell_type":"markdown","source":"Lastly, we build a simple model using our cleaned data to determine if punt results can be predicted based on exising features.\n\nThis portion highlights some more nuanced information about the game in question, which could help determine the more successful plays and trends upon review. Studying these makes discerning whether or not a team is winning a possibility earlier in the game.","metadata":{}},{"cell_type":"code","source":"from sklearn import svm\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.model_selection import train_test_split\nfrom sklearn import metrics","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.573569Z","iopub.execute_input":"2022-01-06T21:29:55.574213Z","iopub.status.idle":"2022-01-06T21:29:55.668079Z","shell.execute_reply.started":"2022-01-06T21:29:55.574180Z","shell.execute_reply":"2022-01-06T21:29:55.667383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_strat = strategy_df.copy()\npunt_strat.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.669358Z","iopub.execute_input":"2022-01-06T21:29:55.669566Z","iopub.status.idle":"2022-01-06T21:29:55.688376Z","shell.execute_reply.started":"2022-01-06T21:29:55.669542Z","shell.execute_reply":"2022-01-06T21:29:55.687570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The datagrame X is created to contain the features we want to use when training our model. Dummy variables are created for the categorical variables, such as the kick type. ","metadata":{}},{"cell_type":"code","source":"X = punt_strat[['snapDetail','snapTime','hangTime','operationTime',\n                'kickType','kickDirectionIntended','kickDirectionActual', 'returnDirectionIntended',\n                'returnDirectionActual','kickContactType','quarter','yardsToGo','gameClock', \n                'penaltyYards', 'kickLength','puntRushers','gunners','tacklers',\n                'specialTeamsSafeties', 'vises','yardsToEndzone','pointDifference']]\nX = pd.get_dummies(X)\nX.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.689889Z","iopub.execute_input":"2022-01-06T21:29:55.690595Z","iopub.status.idle":"2022-01-06T21:29:55.724464Z","shell.execute_reply.started":"2022-01-06T21:29:55.690552Z","shell.execute_reply":"2022-01-06T21:29:55.722618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Our target variable to predict is the special teams result for punts (Return, Fair Catch, Downed, Out of Bounds, Touchback, Muffed, Non-Special Teams Result, Blocked Punt) that are mapped to numerical values.","metadata":{}},{"cell_type":"code","source":"punt_strat['specialTeamsResult'] = punt_strat['specialTeamsResult'].map({\n    'Return':1, 'Fair Catch':2, 'Downed':3, 'Out of Bounds':4, 'Touchback':5, 'Muffed':6,\n    'Non-Special Teams Result':7, 'Blocked Punt':8})\n\ny1 = punt_strat['specialTeamsResult']","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.725696Z","iopub.execute_input":"2022-01-06T21:29:55.726566Z","iopub.status.idle":"2022-01-06T21:29:55.735390Z","shell.execute_reply.started":"2022-01-06T21:29:55.726521Z","shell.execute_reply":"2022-01-06T21:29:55.734800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, X_test, y_train, y_test = train_test_split(X, y1, test_size = 0.3)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.736967Z","iopub.execute_input":"2022-01-06T21:29:55.737289Z","iopub.status.idle":"2022-01-06T21:29:55.746822Z","shell.execute_reply.started":"2022-01-06T21:29:55.737250Z","shell.execute_reply":"2022-01-06T21:29:55.746085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This accuracy measurement below predicts the outcome of the punt, whether its a fair catch, a block punt, etc. This was calculated bsed on the game clock, how many yards a team has until they reach the end zone, the hang time of the punt, etc. This becomes an amazing tool from the standpoint of the defense in predicting what the offense may do next.","metadata":{}},{"cell_type":"code","source":"clf = RandomForestClassifier(n_estimators=100)\nclf.fit(X_train,y_train)\ny_pred = clf.predict(X_test)\n\nprint(\"Accuracy:\", metrics.accuracy_score(y_test, y_pred))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:55.748292Z","iopub.execute_input":"2022-01-06T21:29:55.748759Z","iopub.status.idle":"2022-01-06T21:29:56.361271Z","shell.execute_reply.started":"2022-01-06T21:29:55.748719Z","shell.execute_reply":"2022-01-06T21:29:56.360416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"These values below denote the importance of each feature in predicting the target response with the above accuracy.","metadata":{}},{"cell_type":"code","source":"feature_imp = pd.Series(clf.feature_importances_,index=X.columns).sort_values(ascending=False)\nfeature_imp","metadata":{"execution":{"iopub.status.busy":"2022-01-06T21:29:56.362751Z","iopub.execute_input":"2022-01-06T21:29:56.363215Z","iopub.status.idle":"2022-01-06T21:29:56.382852Z","shell.execute_reply.started":"2022-01-06T21:29:56.363177Z","shell.execute_reply":"2022-01-06T21:29:56.382007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In all, these functions account for variables that make football data complex being that they incorporate so many variables involved in making special team decisions. Therefore, following this analysis allows a team to be accurate, efficient, and calculated in various situaitons on a weekly basis, no matter what team they are facing in the future. This notebook provides the ability of predicting results and efficiently presenting data, but when accompanied by coaching expertise and player intuition, that concotion becomes a formula for sustainable football success. ","metadata":{}}]}