{"cells":[{"metadata":{},"cell_type":"markdown","source":"# 2020 NCAA Men's and Women's Exploratory Data Analysis\n\n<a href=\"https://en.wikipedia.org/wiki/March_Madness_(disambiguation)\">March Madness</a>  is the collegiate men's and women's basketball tournaments in US, held by NCAA (National Collegiate Athletic Association).\n\nWe will build a prediction model to **predict which team wins for all combination of possible matchup**. Large amount of historical data about college basketball games and teams are provided.\n\nThis is 2 stage competition:\n - **Stage 1** - You should submit predicted probabilities for every possible matchup in the past 5 NCAA® tournaments (seasons 2015-2019).\n - **Stage 2** - You should submit predicted probabilities for every possible matchup before the 2020 tournament begins.\n \nI will also demonstrate how to get **logloss=0 score for stage1**.","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"import gc\nimport os\nfrom pathlib import Path\nimport random\nimport sys\n\nfrom tqdm.notebook import tqdm\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom IPython.core.display import display, HTML\n\n# --- plotly ---\nfrom plotly import tools, subplots\nimport plotly.offline as py\npy.init_notebook_mode(connected=True)\nimport plotly.graph_objs as go\nimport plotly.express as px\nimport plotly.figure_factory as ff\n\n# --- models ---\nfrom sklearn import preprocessing\nfrom sklearn.model_selection import KFold\nimport lightgbm as lgb\nimport xgboost as xgb\nimport catboost as cb\n\n# --- setup ---\npd.set_option('max_columns', 50)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"At first, let's see what kind of files are provided as data, we can see 26 files are provided for this competition, so many,,,!!<br/>\nYeah you can see [Data description page](https://www.kaggle.com/c/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/data) that it is so long!! I will look into all files in this notebook.","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Input data files are available in the \"../input/\" directory.\nimport os\n\nfile_count = 0\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    filenames.sort()\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n        file_count += 1\nprint(f'Total {file_count} files!')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"datadir = Path('/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament')\nstage1dir = datadir/'MDataFiles_Stage1'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's see data one by one carefully. I will follow the order written in the [Data Description](https://www.kaggle.com/c/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/data) page.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"markdown","source":"Before begin, **Special note about \"Season\" numbers**: The college basketball season starts from November until March, which spans two calendar years. And the season year is referenced as the year that **the season ends in**, not the year that it starts in.<br/>\nFor example, **\"season 2020\" means 2019-2020**.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Data Section 1 - The Basics\n\nThis section provides everything you need to build a simple prediction model and submit predictions.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Teams data\n\nTeams name and their 4-digit id are provided. In total 367 teams participated since 1985, although 2020 game is held with 68 teams.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"teams_df = pd.read_csv(stage1dir/'MTeams.csv')\n\nprint('teams_df', teams_df.shape)\nteams_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Teams first participation year `FirstD1Season` and lasat participation year `FirstD1Season` are provided. Because March Madness games are for Division-I game, each team might appear/disappear in each year.\n\nBelow gantt chart visualizes each team's first/last participation status, note that it won't handle \"missing participation\" in intermediate years.","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"tmp_df = teams_df[['TeamName', 'FirstD1Season', 'LastD1Season']].copy()\ntmp_df.columns = ['Task', 'Start', 'Finish']\n\n# Only plot first 20 teams\nfig = ff.create_gantt(tmp_df.iloc[:20])\npy.plot(fig, filename='gannt.html')\n# fig.show()  # It causes kaggle kernel error when committed somehow...","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Seasons data\n\n**DayZero**: All game dates have been aligned upon a common scale so that (each year) the Monday championship game of the men's tournament is on **`DayNum=154`**.\n\n**RegionW, RegionX, Region Y, Region Z**: Tournament proceeds with deviding US in 4 regions, but this division changes in year. These RegionW, X, Y, Z column represents 4 regions of each year. Note that RegionW & X, Y & Z have matchup in semifinals. Winner of WX and YZ regions have the final championship matchup.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"seasons_df = pd.read_csv(stage1dir/'MSeasons.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(seasons_df.shape)\nseasons_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Tournament seeds data\n\n`Seed` column string consists of **Region (W, X, Y, Z) + seed number (01 ~ 16)**. Seed number 01 is considered as most \"strong\". For play-in games, which occurs before main tournament, fourth character (**a or b**) is added.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tourney_seeds_df = pd.read_csv(stage1dir/'MNCAATourneySeeds.csv')\ntourney_seeds_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Regular Season Results data & Tournament Results data\n\nFor each year, we have **regular season** at first, and only 68 teams survive for **NCAA tournament, also called March Madness** (In parallel, some teams who cannot proceed March Madness participates **Secondary tournament**). The game result of these 3 are stored in separated files.\n\n\"Compact results\" data stores important information for win/lose, while \"Detailed results\" data (explained later) stores much precise information. Let's see Compact results data here.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"regular_season_results_df = pd.read_csv(stage1dir/'MRegularSeasonCompactResults.csv')\ntournament_results_df = pd.read_csv(stage1dir/'MNCAATourneyCompactResults.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Both files are same format, stores matchup date, winner/loser's team id & score.<br/>\n\nWe can see winner team (starts with \"W\") and lost team (starts with \"L\") from this data.\n\n`WScore` and `LScore` is the winner-loser score at the end of game.\n\n`WLoc` stores the \"location\" of winning team, either `[\"H\", \"A\", \"N\"]`.<br/>\n\"H\" is home, \"A\" is Away (visiting to opponent's site), \"N\" is neutral court.\n\n`NumOT` is number of overtime periods (when the score is same after 4-period of game, we continue the game with overtime period in basketball.)","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"The 4 columns, **Season, DayNum, WTeamID abd LTeamID** uniquely identifies the game. This fact is very important when you want to merge information of other files.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"regular_season_results_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"For tournament, All games will show up as neutral site (so WLoc is always Neutral).\n\nNCAA tournament schedule is consistent and the day of Round 1, 2, 3, 4, 5 (semifinals), 6 (national championship) are decided. Please refer [data description](https://www.kaggle.com/c/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/data) for details.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tournament_results_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Number of regular season's game is much more than tournament, since many teams matchups, as expected.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"print('regular season', regular_season_results_df.shape, 'tournament', tournament_results_df.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Sample submission\n\nIt stores the matchup to predict for submission. In Stage 1, it seems we need to predict matchup from 2015 until 2019.\n\n> During Stage 1, you are asked to make predictions for all possible matchups from the past five NCAA® tournaments (seasons 2015, 2016, 2017, 2018, 2019).\n> When there are 68 teams in the tournament, there are 68*67/2=2,278 predictions to make for that year, so a Stage 1 submission file will have 2,278*5=11,390 data rows.\n\n> ID - this is a 14-character string of the format SSSS_XXXX_YYYY, where SSSS is the four digit season number, XXXX is the four-digit TeamID of the lower-ID team, and YYYY is the four-digit TeamID of the higher-ID team.\n> Pred - this contains the predicted winning percentage for the first team identified in the ID field, the one represented above by XXXX.\n\n\nWe already saw that 2015-2019 matchup result is provided, which means **we have a ground truth answer of stage1**. I think it is easy to get `logloss=0` score on the leaderboard during stage 1. See bottom \"Create stage 1 submission file with ground truth data\" for details.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission = pd.read_csv(datadir/'MSampleSubmissionStage1_2020.csv')\nsample_submission","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Note: so what should we do for this competition? stage1 is only for testing your model, stage2 is the main term of this competition where you need to predict future 2020 matchup results.<br/>\nWe can virtually test this by trainining the prediction model using data until season XXXX and test with season XXXX + 1, where XXXX = 2015, 2016, 2017, 2018 etc.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Data Section 2 - Team Box Scores\n\n## Detailed results\n\nThis section provides game-by-game stats at a team level (free throws attempted, defensive rebounds, turnovers, etc.) for all regular season, conference tournament, and NCAA® tournament games since the 2002-03 season.\n\nTeam Box Scores are provided in \"Detailed Results\" files rather than \"Compact Results\" files.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Compact results are collected from 1985, but details results are collected since 2003, so the number of rows in the data are different.\n\nBut 8 columns (Season, DayNum, WTeamID, WScore, LTeamID, LScore, WLoc, and NumOT) are exactly same value with CompactResults file.\nAdditional columns stores more precise information:\n\n - WFGM - field goals made (by the winning team)\n - WFGA - field goals attempted (by the winning team)\n - WFGM3 - three pointers made (by the winning team)\n - WFGA3 - three pointers attempted (by the winning team)\n - WFTM - free throws made (by the winning team)\n - WFTA - free throws attempted (by the winning team)\n - WOR - offensive rebounds (pulled by the winning team)\n - WDR - defensive rebounds (pulled by the winning team)\n - WAst - assists (by the winning team)\n - WTO - turnovers committed (by the winning team)\n - WStl - steals (accomplished by the winning team)\n - WBlk - blocks (accomplished by the winning team)\n - WPF - personal fouls committed (by the winning team)\n \n same set of stats from the perspective of the losing team starting with \"L\".","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"regular_season_detailed_results_df = pd.read_csv(stage1dir/'MRegularSeasonDetailedResults.csv')\ntournament_detailed_results_df = pd.read_csv(stage1dir/'MNCAATourneyDetailedResults.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"For example in top row WFGM=27, WFGM3=3, WFTM=11 and WScore=68.\n\nThis means (27-3)=24 goals with 2 points shot, 3 goals with 3 points shot, and 11 goals with 1 point free throw shot.<br/>\nIn total `24 * 2 + 3 * 3 + 11 * 1 = 68`.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"regular_season_detailed_results_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tournament_detailed_results_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Number of rows is smaller than CompactResults data, since detailed information is provided since 2003. ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"print('regular', regular_season_detailed_results_df.shape, 'tournament', tournament_detailed_results_df.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Section 3 - Geography\n\nThis section provides city locations of all regular season, conference tournament, and NCAA® tournament games since the 2010 season","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"cities_df = pd.read_csv(stage1dir/'Cities.csv')\nmgame_cities_df = pd.read_csv(stage1dir/'MGameCities.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## City information\n\nCity information and Conference information can be used for both men's and women's contest.\n\nCity data stores **city id**, **city name** and **US state** location.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"cities_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Game city\n\nThe first 4 columns (**Season, DayNum, WTeamID and LTeamID**) are enough information to uniquely identify the game.\n\n**CRType** - `[\"Regular\", \"NCAA\", \"Secondary\"]`, the game is found in the specified file. \"Regular\" is Regular season, \"NCAA\" is tournament, \"Secondary\" is secondary tournament respectively<br/>\n**CityID** - See above `Cities.csv` to know the location.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"mgame_cities_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Section 4 - Public Rankings\nThis section provides weekly team rankings for dozens of top rating systems - Pomeroy, Sagarin, RPI, ESPN, etc., since the 2002-2003 season.\n\nThe information was gathered by Kenneth Massey and provided on his [College Basketball Ranking Composite page](https://www.masseyratings.com/cb/compare.htm).","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"massey_df = pd.read_csv(stage1dir/'MMasseyOrdinals.csv')\nmassey_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"SystemName represents the rating calculation method, it seems there are many types of ranking system. Basically we should only compare the rating in the same calculation method.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"massey_df['SystemName'].unique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\nRanking is meaningful only when we compare **same day (Season & RankingDayNum)** and **same system (SystemName)**.\n\nBelow example shows \"SEL\" ranking of DayNum=35 in 2003.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp_df = massey_df[(massey_df['Season'] == 2003) & (massey_df['RankingDayNum'] == 35) & (massey_df['SystemName'] == 'SEL')][['TeamID', 'OrdinalRank']]\n# Only shows first 20 teams.\ntmp_df.sort_values('OrdinalRank').iloc[:20].plot(kind='barh', x='TeamID', y='OrdinalRank')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Section 5 - Play-by-play\nThis section provides play-by-play event logs for more than 99.5% of each year's regular season, NCAA® tournament, and secondary tournament games since the 2014-15 season - including plays by individual players.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Events data\n\nThis file stores the most precise information for each game, player's each action during the game.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"event2015_df = pd.read_csv(datadir/'MEvents2015.csv')\n# event2016_df = pd.read_csv(datadir/'MEvents2016.csv')\n# event2017_df = pd.read_csv(datadir/'MEvents2017.csv')\n# event2018_df = pd.read_csv(datadir/'MEvents2018.csv')\n# event2019_df = pd.read_csv(datadir/'MEvents2019.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"4 columns (Season, DayNum, WTeamID, LTeamID) specify game id. Same game event should have same value for these columns.\n\nBelow 5 rows can be read as follows.\n\nEventID 1: Team 1103 Player 100 attemped to try 3 points shoot, which was missed.<br/>\nEventID 2: Team 1420 Player 11784 get re-bound, defence got the boal, offence-defence changed.<br/>\n\nEventID 3: Team 1420 Player 11789 attemped to try 2 points DUNK shoot! which was made.<br/>\nEventID 4: Team 1420 Player 11803 assited that dunk.<br/>\n\nEventID 5: Team 1103 Player 87 attempted 2 points shoot, which was made.<br/>","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"event2015_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Event Types and Subtypes:\n\n - **assist** - an assist was credited on a made shot\n - **block** - a blocked shot was recorded\n - **steal** - a steal was recorded\n - **sub** - a substitution occurred, with one of the following subtypes: in=player entered the game; out=player exited the game; start=player started the game\n - **timeout** - a timeout was called, with one of the following subtypes: unk=unknown type of timeout; comm=commercial timeout; full=full timeout; short= short timeout\n - **turnover** - a turnover was recorded, with one of the following subtypes: unk=unknown type of turnover; 10sec=10 second violation; 3sec=3 second violation; 5sec=5 second violation; bpass=bad pass turnover; dribb=dribbling turnover; lanev=lane violation; lostb=lost ball; offen=offensive turnover (?); offgt=offensive goaltending; other=other type of turnover; shotc=shot clock violation; trav=travelling\n - **foul** - a foul was committed, with one of the following subtypes: unk=unknown type of foul; admT=administrative technical; benT=bench technical; coaT=coach technical; off=offensive foul; pers=personal foul; tech=technical foul\n - **fouled** - a player was fouled\n - **reb** - a rebound was recorded, with one of the following subtypes: deadb=a deadball rebound; def=a defensive rebound; defdb=a defensive deadball rebound; off=an offensive rebound; offdb=an offensive deadball rebound\n - **made1, miss1** - a one-point free throw was made or missed, with one of the following subtypes: 1of1=the only free throw of the trip to the line; 1of2=the first of two free throw attempts; 2of2=the second of two free throw attempts; 1of3=the first of three free throw attempts; 2of3=the second of three free throw attempts; 3of3=the third of three free throw attempts; unk=unknown what the free throw sequence is\n - **made2, miss2** - a two-point field goal was made or missed, with one of the following subtypes: unk=unknown type of two-point shot; dunk=dunk; lay=layup; tip=tip-in; jump=jump shot; alley=alley-oop; drive=driving layup; hook=hook shot; stepb=step-back jump shot; pullu=pull-up jump shot; turna=turn-around jump shot; wrong=wrong basket\n - **made3, miss3** - a three-point field goal was made or missed, with one of the following subtypes: unk=unknown type of three-point shot; jump=jump shot; stepb=step-back jump shot; pullu=pull-up jump shot; turna=turn-around jump shot; wrong=wrong basket\n - **jumpb** - a jumpball was called or resolved, with one of the following subtypes: start=start period; block=block tie-up; heldb=held ball; lodge=lodged ball; lost=jump ball lost; outof=out of bounds; outrb=out of bounds rebound; won=jump ball won\n - **X, Y** - for games where it is available, this describes an X/Y position on the court where the lower-left corner of the court is (0,0), the upper-right corner of the court is (100,100), and so on. The X/Y position is provided for fouls, turnovers, and field-goal attempts (either 2-point or 3-point).\n - **Area** - for events where an X/Y position is provided, this position is more generally categorized into one of 13 \"areas\" of the court, as follows: 1=under basket; 2=in the paint; 3=inside right wing; 4=inside right; 5=inside center; 6=inside left; 7=inside left wing; 8=outside right wing; 9=outside right; 10=outside center; 11=outside left; 12=outside left wing; 13=backcourt","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Players data\n\nPlayer's **id**, **name**, and their **team** information is stored.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"players_df = pd.read_csv(datadir/'MPlayers.csv')\nplayers_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Section 6 - Supplements\n\nThis section contains additional supporting information, including coaches, conference affiliations, alternative team name spellings, bracket structure, and game results for NIT and other postseason tournaments.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Coach data\n\ncoach information stores the name of the head coach of each team, and his/her duration of the team. Often 1 coach plays the role and thus `FirstDayNum=0` and `LastDayNum=154` but sometimes multiple coach exists within 1 year for 1 team.\n\nFor example, `tom_pugliese` and `mark_slonaker` was the head coach of Team ID 1209 in Season 1985.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"team_coaches_df = pd.read_csv(stage1dir/'MTeamCoaches.csv')\n\nprint('team_coaches_df', team_coaches_df.shape)\nteam_coaches_df.iloc[80:85]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Conference data\n\n`Conferences.csv` is common between Men's and Women's competition, which stores conference **abbreviation name** and its **full name**.<br/>","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"conferences_df = pd.read_csv(stage1dir/'Conferences.csv')\nteam_conferences_df = pd.read_csv(stage1dir/'MTeamConferences.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conferences_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"`MTeamConferences.csv` stores each team's conference information. Conference place for the team may change in time, so this data contains \"Season\" column to indicate the year.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"team_conferences_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"For example, TeamID 1102 (=Air Force) changed its conference from `wac` (Western Athletic Conference) to `mwc` (Mountain West Conference) in 2000.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"team_conferences_df[team_conferences_df['TeamID'] == 1102]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"`MConferenceTourneyGames.csv` connects each game and its conference place.<br/>\n4 columns (Season, DayNum, WTeamID, LTeamID) uniquely specify the game, `ConfAbbrev` stores the conference information for the game.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"conference_tourney_games_df = pd.read_csv(stage1dir/'MConferenceTourneyGames.csv')\nconference_tourney_games_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Secondary Tournament\n\nIn parallel to NCAA tournament, secondary tournament is organized. `SecondaryTourney` has some types, either `[\"NIT\", \"CBI\", \"CIT\", \"V16\"]`.<br/>\n\"NIT\" is the most prominent tournament amont these 4 tournaments.\n\nFirst, `MSecondaryTourneyTeams.csv` contains information about each team participated which tournament in each season.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"secondary_tourney_teams_df = pd.read_csv(stage1dir/'MSecondaryTourneyTeams.csv')\nsecondary_tourney_teams_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"`MSecondaryTourneyCompactResults.csv` contains information about each game results of secondary tournament.\n\nNote that **detailed results or event data is not provided**. We can only use compact results for secondary tournament.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"secondary_tourney_results_df = pd.read_csv(stage1dir/'MSecondaryTourneyCompactResults.csv')\nsecondary_tourney_results_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Team spelling data\n\nI could not open it...","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# TODO: it seems there's encoding problem... which encoding can be used to open this file?\n# team_spellings_df = pd.read_csv(stage1dir/'MTeamSpellings.csv')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Tournament slots data\n\nNCAA tournament is organized that it has consistent tournament structure in each year.<br/>\nBelow \"slots\" information indicates which part of the tournament bracket structure each seed team in.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tourney_slots_df = pd.read_csv(stage1dir/'MNCAATourneySlots.csv')\ntourney_seed_round_slots_df = pd.read_csv(stage1dir/'MNCAATourneySeedRoundSlots.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tourney_slots_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"For example, Round 1 of Region W in Season 1985 consists of following 8 matchups.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tourney_slots_df[(tourney_slots_df['Season'] == 1985) & (tourney_slots_df['Slot'].str.startswith('R1W'))]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"`MNCAATourneySeedRoundSlots.csv` stores further information about each `GameRound` and `DayNum`.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tourney_seed_round_slots_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Create stage 1 submission file with ground truth data\n\nAs we already understood, stage 1 prediction target is 2015-2019 tournament result, which is provided by data. I will demonstrate and check our understanding the submission file for stage1.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"At first, we only need tournament result from 2015 until 2019.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"tournament_results2015_df = tournament_results_df.query(\"Season >= 2015\")\ntournament_results2015_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Check again, sample submission format is as follows, consisting of ID and Pred.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Then we would like to create **ID = Season_WTeamID_LTeamID** with **Pred = 1.0**, or **ID = Season_LTeamID_WTeamID** with **Pred = 0.0**.\nBelow code only substitutes the `Pred` value to sample_submission data.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nfor key, row in tournament_results2015_df.iterrows():\n    if row['WTeamID'] < row['LTeamID']:\n        # Check season_win_lost type\n        id_name = str(row['Season']) + '_' + str(row['WTeamID']) + '_' + str(row['LTeamID'])\n        sample_submission.loc[sample_submission['ID'] == id_name, 'Pred'] = 1.0\n    else:\n        # Check season_lost_win type\n        id_name = str(row['Season']) + '_' + str(row['LTeamID']) + '_' + str(row['WTeamID'])\n        sample_submission.loc[sample_submission['ID'] == id_name, 'Pred'] = 0.0","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Save created submission file for submission.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Check histgram. Here, only few rows are changed to pred 1.0 or 0.0, but many of the rows are remain 0.5. Because most of the **matchup is not actually executed**. The score is evaluated only by the actually executed games.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission['Pred'].hist()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Of course, this logic **completely does not work for stage 2**!!!, where we need to predict 2020 tournament result while 2020 tournament data is not provided.<br/>\nThis is just a demonstration of our data understanding.\n\nWhen you refer other people's kernel, please be careful that if they use tournament data during 2015-2019 to train the model, it is **leaked for stage1**. In that case basically we can get any score, as I could get `logloss=0` score here.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"TODO: I would like to add these stuffs later.\n\n - More EDA, more visualization\n - Some feature engineering and check behavior","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}