{"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":"\n!pip install fastai2\n\n# from fastai.tabular import *\nfrom fastai2.tabular.all import *\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom sklearn.ensemble import RandomForestRegressor\nfrom sklearn.tree import DecisionTreeRegressor\n\n# Input data files are available in the \"../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# Any results you write to the current directory are saved as output.\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-09-06T09:46:46.326289Z","iopub.execute_input":"2021-09-06T09:46:46.326706Z","iopub.status.idle":"2021-09-06T09:46:58.533253Z","shell.execute_reply.started":"2021-09-06T09:46:46.326615Z","shell.execute_reply":"2021-09-06T09:46:58.530502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seeds = pd.read_csv(\"/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/MDataFiles_Stage1/MNCAATourneySeeds.csv\")\n\nseeds = seeds.assign(\n    SeedNum = lambda df: df.apply(lambda row: int(row.Seed[1:3]), axis = 1)\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reg_season_results = pd.read_csv(\"/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/MDataFiles_Stage1/MRegularSeasonDetailedResults.csv\")\n\nw_team_stats = (\n    reg_season_results.groupby([\"Season\", \"WTeamID\"])\n    .agg(\n        W=(\"WTeamID\",\"count\"),\n        NumOT=(\"NumOT\", \"sum\"),\n        Score=(\"WScore\", \"sum\"),\n        FGM=(\"WFGM\", \"sum\"),\n        FGA=(\"WFGA\", \"sum\"),\n        FGM3=(\"WFGM3\", \"sum\"),\n        FGA3=(\"WFGA3\", \"sum\"),\n        FTM=(\"WFTM\", \"sum\"),\n        FTA=(\"WFTA\", \"sum\"),\n        OR=(\"WOR\", \"sum\"),\n        DR=(\"WDR\", \"sum\"),\n        Ast=(\"WAst\", \"sum\"),\n        TO=(\"WTO\", \"sum\"),\n        Stl=(\"WStl\", \"sum\"),\n        Blk=(\"WBlk\", \"sum\"),\n        PF=(\"WPF\", \"sum\"),\n        OppScore=(\"LScore\", \"sum\"),\n        OppFGM=(\"LFGM\", \"sum\"),\n        OppFGA=(\"LFGA\", \"sum\"),\n        OppFGM3=(\"LFGM3\", \"sum\"),\n        OppFGA3=(\"LFGA3\", \"sum\"),\n        OppFTM=(\"LFTM\", \"sum\"),\n        OppFTA=(\"LFTA\", \"sum\"),\n        OppOR=(\"LOR\", \"sum\"),\n        OppDR=(\"LDR\", \"sum\"),\n        OppAst=(\"LAst\", \"sum\"),\n        OppTO=(\"LTO\", \"sum\"),\n        OppStl=(\"LStl\", \"sum\"),\n        OppBlk=(\"LBlk\", \"sum\"),\n        OppPF=(\"LPF\", \"sum\"),\n    )\n    .reset_index()\n    .rename(columns={\"WTeamID\": \"TeamID\"})\n)\n\nl_team_stats = (\n    reg_season_results.groupby([\"Season\", \"LTeamID\"])\n    .agg(\n        L=(\"LTeamID\",\"count\"),\n        NumOT=(\"NumOT\", \"sum\"),\n        Score=(\"LScore\", \"sum\"),\n        FGM=(\"LFGM\", \"sum\"),\n        FGA=(\"LFGA\", \"sum\"),\n        FGM3=(\"LFGM3\", \"sum\"),\n        FGA3=(\"LFGA3\", \"sum\"),\n        FTM=(\"LFTM\", \"sum\"),\n        FTA=(\"LFTA\", \"sum\"),\n        OR=(\"LOR\", \"sum\"),\n        DR=(\"LDR\", \"sum\"),\n        Ast=(\"LAst\", \"sum\"),\n        TO=(\"LTO\", \"sum\"),\n        Stl=(\"LStl\", \"sum\"),\n        Blk=(\"LBlk\", \"sum\"),\n        PF=(\"LPF\", \"sum\"),\n        OppScore=(\"WScore\", \"sum\"),\n        OppFGM=(\"WFGM\", \"sum\"),\n        OppFGA=(\"WFGA\", \"sum\"),\n        OppFGM3=(\"WFGM3\", \"sum\"),\n        OppFGA3=(\"WFGA3\", \"sum\"),\n        OppFTM=(\"WFTM\", \"sum\"),\n        OppFTA=(\"WFTA\", \"sum\"),\n        OppOR=(\"WOR\", \"sum\"),\n        OppDR=(\"WDR\", \"sum\"),\n        OppAst=(\"WAst\", \"sum\"),\n        OppTO=(\"WTO\", \"sum\"),\n        OppStl=(\"WStl\", \"sum\"),\n        OppBlk=(\"WBlk\", \"sum\"),\n        OppPF=(\"WPF\", \"sum\"),\n    )\n    .reset_index()\n    .rename(columns={\"LTeamID\": \"TeamID\"})\n)\n\nteam_stats = (\n    pd.merge(w_team_stats, l_team_stats, how=\"outer\", on=[\"Season\", \"TeamID\"], suffixes=(\"_W\", \"_L\"))\n    .fillna(0)\n    .astype(int)\n    .assign(\n        G = lambda df: df.W + df.L,\n        NumOT = lambda df: df.NumOT_W + df.NumOT_L,\n        Pts = lambda df: df.Score_W + df.Score_L,\n        FGM = lambda df: df.FGM_W + df.FGM_L,\n        FGA = lambda df: df.FGA_W + df.FGA_L,\n        FGM3 = lambda df: df.FGM3_W + df.FGM3_L,\n        FGA3 = lambda df: df.FGA3_W + df.FGA3_L,\n        FTM = lambda df: df.FTM_W + df.FTM_L,\n        FTA = lambda df: df.FTA_W + df.FTA_L,\n        ORB = lambda df: df.OR_W + df.OR_L,\n        DRB = lambda df: df.DR_W + df.DR_L,\n        Ast = lambda df: df.Ast_W + df.Ast_L,\n        TO = lambda df: df.TO_W + df.TO_L,\n        Stl = lambda df: df.Stl_W + df.Stl_L,\n        Blk = lambda df: df.Blk_W + df.Blk_L,\n        PF = lambda df: df.PF_W + df.PF_L,\n        OppPts = lambda df: df.OppScore_W + df.OppScore_L,\n        OppFGM = lambda df: df.OppFGM_W + df.OppFGM_L,\n        OppFGA = lambda df: df.OppFGA_W + df.OppFGA_L,\n        OppFGM3 = lambda df: df.OppFGM3_W + df.OppFGM3_L,\n        OppFGA3 = lambda df: df.OppFGA3_W + df.OppFGA3_L,\n        OppFTM = lambda df: df.OppFTM_W + df.OppFTM_L,\n        OppFTA = lambda df: df.OppFTA_W + df.OppFTA_L,\n        OppORB = lambda df: df.OppOR_W + df.OppOR_L,\n        OppDRB = lambda df: df.OppDR_W + df.OppDR_L,\n        OppAst = lambda df: df.OppAst_W + df.OppAst_L,\n        OppTO = lambda df: df.OppTO_W + df.OppTO_L,\n        OppStl = lambda df: df.OppStl_W + df.OppStl_L,\n        OppBlk = lambda df: df.OppBlk_W + df.OppBlk_L,\n        OppPF = lambda df: df.OppPF_W + df.OppPF_L,\n    )\n    .assign(\n        WinPerc = lambda df: df.W / df.G,\n        Minutes = lambda df: df.G * 40 + df.NumOT * 5,\n        PtsPG = lambda df: df.Pts / df.G,\n        FGPerc = lambda df: df.FGM / df.FGA,\n        FG3Perc = lambda df: df.FGM3 / df.FGA3,\n        FTPerc = lambda df: df.FTM / df.FTA,\n        ORBPG = lambda df: df.ORB / df.G,\n        DRBPG = lambda df: df.DRB / df.G,\n        AstPG = lambda df: df.Ast / df.G,\n        TOPG = lambda df: df.TO / df.G,\n        AstTO = lambda df: df.Ast / df.TO,\n        StlPG = lambda df: df.Stl / df.G,\n        BlkPG = lambda df: df.Blk / df.G,\n        PFPG = lambda df: df.PF / df.G,\n        OppPtsPG = lambda df: df.OppPts / df.G,\n        OppFGPerc = lambda df: df.OppFGM / df.OppFGA,\n        OppFG3Perc = lambda df: df.OppFGM3 / df.OppFGA3,\n        OppFTPerc = lambda df: df.OppFTM / df.OppFTA,\n        OppORBPG = lambda df: df.OppORB / df.G,\n        OppDRBPG = lambda df: df.OppDRB / df.G,\n        OppAstPG = lambda df: df.OppAst / df.G,\n        OppTOPG = lambda df: df.OppTO / df.G,\n        OppAstTO = lambda df: df.OppAst / df.OppTO,\n        OppStlPG = lambda df: df.OppStl / df.G,\n        OppBlkPG = lambda df: df.OppBlk / df.G,\n        OppPFPG = lambda df: df.OppPF / df.G,\n    )\n    .assign(\n        Possessions = lambda df: df.FGA - df.ORB + df.TO + .475 * df.FTA,\n        OppPossessions = lambda df: df.OppFGA - df.OppORB + df.OppTO + .475 * df.OppFTA,\n        OffEff = lambda df: 100 * df.Pts / df.Possessions,\n        DefEff = lambda df: 100 * df.OppPts / df.OppPossessions,\n        EFGPerc = lambda df: (df.FGM + 0.5 * df.FGM3) / df.FGA,\n        ORBPerc = lambda df: df.ORB / (df.ORB + df.OppDRB),\n        TOPerc = lambda df: df.TO / df.Possessions,\n        FTRate = lambda df: df.FTA / df.FGA,\n        OppEFGPerc = lambda df: (df.OppFGM + 0.5 * df.OppFGM3) / df.OppFGA,\n        OppORBPerc = lambda df: df.OppORB / (df.OppORB + df.DRB),\n        OppTOPerc = lambda df: df.OppTO / df.OppPossessions,\n        OppFTRate = lambda df: df.OppFTA / df.OppFGA,\n    )\n    .loc[:, [\n        \"Season\",\n        \"TeamID\",\n        \"W\",\n        \"L\",\n        \"G\",\n        \"WinPerc\",\n        \"Minutes\",\n        \"PtsPG\",\n        \"FGPerc\",\n        \"FG3Perc\",\n        \"FTPerc\",\n        \"ORBPG\",\n        \"DRBPG\",\n        \"AstPG\",\n        \"TOPG\",\n        \"AstTO\",\n        \"StlPG\",\n        \"BlkPG\",\n        \"PFPG\",\n        \"OppPtsPG\",\n        \"OppFGPerc\",\n        \"OppFG3Perc\",\n        \"OppFTPerc\",\n        \"OppORBPG\",\n        \"OppDRBPG\",\n        \"OppAstPG\",\n        \"OppTOPG\",\n        \"OppAstTO\",\n        \"OppStlPG\",\n        \"OppBlkPG\",\n        \"OppPFPG\",\n        \"OffEff\",\n        \"DefEff\",\n        \"EFGPerc\",\n        \"ORBPerc\",\n        \"TOPerc\",\n        \"FTRate\",\n        \"OppEFGPerc\",\n        \"OppORBPerc\",\n        \"OppTOPerc\",\n        \"OppFTRate\"\n    ]])\n\nteam_stats.head()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Team Conferences Feature\nteam_conferences = pd.read_csv(\"/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/MDataFiles_Stage1/MTeamConferences.csv\")\nteam_conferences.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nregular_season_compact_results = pd.read_csv(\"/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/MDataFiles_Stage1/MRegularSeasonCompactResults.csv\")\n\nregular_season_compact_results = (\n    regular_season_compact_results\n    .assign(\n        LowerTeamID = regular_season_compact_results[[\"WTeamID\", \"LTeamID\"]].apply(min, axis = 1),\n        HigherTeamID = regular_season_compact_results[[\"WTeamID\", \"LTeamID\"]].apply(max, axis = 1),\n    )\n)\n\n# Data Augmentation\nregular_season_compact_results = (\n    regular_season_compact_results\n    .append(\n        regular_season_compact_results.copy()\n        .assign(\n            LowerTeamID = regular_season_compact_results.HigherTeamID,\n            HigherTeamID = regular_season_compact_results.LowerTeamID,\n        )\n    )\n)\n\n# Merge Team Stats Feature\nregular_season_compact_results = (\n    regular_season_compact_results\n    .merge(team_stats, left_on=[\"Season\", \"LowerTeamID\"], right_on=[\"Season\", \"TeamID\"], suffixes=(\"_LowerTeamID\", \"_HigherTeamID\"))\n    .merge(team_stats, left_on=[\"Season\", \"HigherTeamID\"], right_on=[\"Season\", \"TeamID\"], suffixes=(\"_LowerTeamID\", \"_HigherTeamID\"))\n    .drop(\"TeamID_LowerTeamID\", axis=1)\n    .drop(\"TeamID_HigherTeamID\", axis=1)\n)\n\n# Merge Team Conferences Feature\nregular_season_compact_results = (\n    regular_season_compact_results\n    .merge(team_conferences, left_on=[\"Season\", \"LowerTeamID\"], right_on=[\"Season\", \"TeamID\"], suffixes=(\"_LowerTeamID\", \"_HigherTeamID\"))\n    .merge(team_conferences, left_on=[\"Season\", \"HigherTeamID\"], right_on=[\"Season\", \"TeamID\"], suffixes=(\"_LowerTeamID\", \"_HigherTeamID\"))\n    .drop(\"TeamID_LowerTeamID\", axis=1)\n    .drop(\"TeamID_HigherTeamID\", axis=1)\n)\n\nregular_season_compact_results = regular_season_compact_results.assign(\n    LowerTeamIDWin = lambda df: (df.LowerTeamID == df.WTeamID).astype(int)\n)\n\nregular_season_compact_results.head()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eff_vars = [\n    \"OffEff_LowerTeamID\",\n    \"DefEff_LowerTeamID\",\n    \"EFGPerc_LowerTeamID\",\n    \"ORBPerc_LowerTeamID\",\n    \"TOPerc_LowerTeamID\",\n    \"FTRate_LowerTeamID\",\n    \"OppEFGPerc_LowerTeamID\",\n    \"OppORBPerc_LowerTeamID\",\n    \"OppTOPerc_LowerTeamID\",\n    \"OppFTRate_LowerTeamID\",\n    \"OffEff_HigherTeamID\",\n    \"DefEff_HigherTeamID\",\n    \"EFGPerc_HigherTeamID\",\n    \"ORBPerc_HigherTeamID\",\n    \"TOPerc_HigherTeamID\",\n    \"FTRate_HigherTeamID\",\n    \"OppEFGPerc_HigherTeamID\",\n    \"OppORBPerc_HigherTeamID\",\n    \"OppTOPerc_HigherTeamID\",\n    \"OppFTRate_HigherTeamID\"\n]\n\nbox_vars = [\n    \"WinPerc_LowerTeamID\",\n#     \"W_LowerTeamID\",\n#     \"L_LowerTeamID\",\n#     \"G_LowerTeamID\",\n#     \"PtsPG_LowerTeamID\",\n#     \"FGPerc_LowerTeamID\",\n#     \"FG3Perc_LowerTeamID\",\n#     \"FTPerc_LowerTeamID\",\n#     \"ORBPG_LowerTeamID\",\n#     \"DRBPG_LowerTeamID\",\n#     \"AstPG_LowerTeamID\",\n#     \"TOPG_LowerTeamID\",\n#     \"AstTO_LowerTeamID\",\n#     \"StlPG_LowerTeamID\",\n#     \"BlkPG_LowerTeamID\",\n#     \"PFPG_LowerTeamID\",\n#     \"OppPtsPG_LowerTeamID\",\n#     \"OppFGPerc_LowerTeamID\",\n#     \"OppFG3Perc_LowerTeamID\",\n#     \"OppFTPerc_LowerTeamID\",\n#     \"OppORBPG_LowerTeamID\",\n#     \"OppDRBPG_LowerTeamID\",\n#     \"OppAstPG_LowerTeamID\",\n#     \"OppTOPG_LowerTeamID\",\n#     \"OppAstTO_LowerTeamID\",\n#     \"OppStlPG_LowerTeamID\",\n#     \"OppBlkPG_LowerTeamID\",\n#     \"OppPFPG_LowerTeamID\",\n    \"WinPerc_HigherTeamID\",\n#     \"W_HigherTeamID\",\n#     \"L_HigherTeamID\",\n#     \"G_HigherTeamID\",\n#     \"PtsPG_HigherTeamID\",\n#     \"FGPerc_HigherTeamID\",\n#     \"FG3Perc_HigherTeamID\",\n#     \"FTPerc_HigherTeamID\",\n#     \"ORBPG_HigherTeamID\",\n#     \"DRBPG_HigherTeamID\",\n#     \"AstPG_HigherTeamID\",\n#     \"TOPG_HigherTeamID\",\n#     \"AstTO_HigherTeamID\",\n#     \"StlPG_HigherTeamID\",\n#     \"BlkPG_HigherTeamID\",\n#     \"PFPG_HigherTeamID\",\n#     \"OppPtsPG_HigherTeamID\",\n#     \"OppFGPerc_HigherTeamID\",\n#     \"OppFG3Perc_HigherTeamID\",\n#     \"OppFTPerc_HigherTeamID\",\n#     \"OppORBPG_HigherTeamID\",\n#     \"OppDRBPG_HigherTeamID\",\n#     \"OppAstPG_HigherTeamID\",\n#     \"OppTOPG_HigherTeamID\",\n#     \"OppAstTO_HigherTeamID\",\n#     \"OppStlPG_HigherTeamID\",\n#     \"OppBlkPG_HigherTeamID\",\n#     \"OppPFPG_HigherTeamID\"\n]\n\nconf_vars = [\n    \"ConfAbbrev_LowerTeamID\",\n    \"ConfAbbrev_HigherTeamID\",\n]\n\nind_vars = eff_vars + conf_vars\ndep_var = \"LowerTeamIDWin\"\n\ndf = regular_season_compact_results.loc[:, ind_vars + [dep_var]]\n\nprocs = [Categorify]\n\ncond = regular_season_compact_results.Season < 2015\ntrain_idx = np.where(cond)[0]\nvalid_idx = np.where(~cond)[0]\n\n# FastAI v1\n# cat = []\n# cont = eff_vars + [dep_var]\n# tl = (\n#     TabularList.from_df(\n#         df,\n#         cat_names=cat,\n#         cont_names=cont,\n#         procs=procs\n#     )\n#     .split_by_idx(list(valid_idx))\n#     .label_from_df(cols=dep_var)\n# )\n# tl.train.inner_df.head()\n\n# FastAI v2\nsplits = (list(train_idx), list(valid_idx))\ncont, cat = cont_cat_split(df, 1, dep_var=dep_var)\ndata = TabularPandas(df, procs, cat, cont, y_names=dep_var, splits=splits)\ndata.show()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def pred(season, lowerTeam, higherTeam):\n    return 0.5\n\ndef kaggle_clip_log(x):\n    return np.log(np.clip(x, 1.0e-15, 1.0 - 1.0e-15))\n\ndef kaggle_log_loss(pred, result):\n    return -(result * kaggle_clip_log(pred) + (1 - result) * kaggle_clip_log(1.0 - pred))\n\ndef model_kaggle_log_loss(m, xs, y): return kaggle_log_loss(m.predict(xs), y).mean()\n\nregular_season_compact_results = regular_season_compact_results.assign(\n    LowerTeamIDWinProb = lambda df: df.apply(lambda row: pred(row.Season, row.LowerTeamID, row.HigherTeamID), axis = 1),\n    LogLoss = lambda df: kaggle_log_loss(df.LowerTeamIDWinProb, df.LowerTeamIDWin)\n)\n\nregular_season_compact_results.LogLoss.mean()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xs, y = data.train.xs, data.train.y\nvalid_xs, valid_y = data.valid.xs, data.valid.y\n\nm = DecisionTreeRegressor(max_leaf_nodes = 64)\nm.fit(xs, y)\nmodel_kaggle_log_loss(m, xs, y), model_kaggle_log_loss(m, valid_xs, valid_y)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rf(xs, y, n_estimators=40, max_features=0.5, min_samples_leaf=5, **kwargs):\n    return RandomForestRegressor(n_jobs=-1, n_estimators=n_estimators, max_features=max_features,\n        min_samples_leaf=min_samples_leaf, oob_score=True).fit(xs, y)\n\nm = rf(xs, y)\nmodel_kaggle_log_loss(m, xs, y), model_kaggle_log_loss(m, valid_xs, valid_y)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rf_feat_importance(m, df):\n    return pd.DataFrame({'cols':df.columns, 'imp':m.feature_importances_}\n                       ).sort_values('imp', ascending=False)\n\ndef plot_fi(fi):\n    return fi.plot('cols', 'imp', 'barh', figsize=(12,7), legend=False)\n\nfi = rf_feat_importance(m, xs)\nplot_fi(fi[:20])","metadata":{},"execution_count":null,"outputs":[]}]}