{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This kernel creates basic logistic regression models and provides a \n# mechanism to select attributes and check results against tournaments since 2018\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\n\n# To create the final sumissions once the round2 data has been updated, set this to true\nROUND2 = False\nDATA_PATH = '../input/google-cloud-ncaa-march-madness-2020-division-1-womens-tournament/'\nROUND1_PATH = DATA_PATH + \"WDataFiles_Stage1/\"\nROUND2_PATH = DATA_PATH + \"WDataFiles_Stage2/\"","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"_kg_hide-output":false},"cell_type":"code","source":"if ROUND2:\n    tourney_cresults = pd.read_csv(ROUND2_PATH + 'WNCAATourneyCompactResults.csv')\nelse:\n    tourney_cresults = pd.read_csv(ROUND1_PATH + 'WNCAATourneyCompactResults.csv')\n    \ntourney_cresults = tourney_cresults.loc[tourney_cresults['Season'] >= 2010]\n\ntraining_set = pd.DataFrame()\ntraining_set['Result'] = np.random.randint(0,2,len(tourney_cresults.index))\ntraining_set['Season'] = tourney_cresults['Season'].values\ntraining_set['Team1'] = training_set['Result'].values * tourney_cresults['WTeamID'].values + (1-training_set['Result'].values) * tourney_cresults['LTeamID'].values \ntraining_set['Team2'] = (1-training_set['Result'].values) * tourney_cresults['WTeamID'].values + training_set['Result'].values * tourney_cresults['LTeamID'].values \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"78ac1ade5e1ff7d5cb8ddc4411d0101653fa6cba"},"cell_type":"code","source":"# Calculate Delta Seeds\nif ROUND2:\n    seeds = pd.read_csv(ROUND2_PATH + 'WNCAATourneySeeds.csv')\nelse:\n    seeds = pd.read_csv(ROUND1_PATH + 'WNCAATourneySeeds.csv')\n\nseeds['Seed'] =  pd.to_numeric(seeds['Seed'].str[1:3], downcast='integer',errors='coerce')\n\ndef delta_seed(row):\n    cond = (seeds['Season'] == row['Season'])\n    return seeds[cond & (seeds['TeamID'] == row['Team1'])]['Seed'].iloc[0] - seeds[cond & (seeds['TeamID'] == row['Team2'])]['Seed'].iloc[0]\n\ntraining_set['deltaSeed'] = training_set.apply(delta_seed,axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"87221422dd24857b4ce63aade714183735b63839"},"cell_type":"code","source":"# Calculate win pct\nif ROUND2:\n    season_dresults = pd.read_csv(ROUND2_PATH + 'WRegularSeasonDetailedResults.csv')\nelse:\n    season_dresults = pd.read_csv(ROUND1_PATH + 'WRegularSeasonDetailedResults.csv')\n\nrecord = pd.DataFrame({'wins': season_dresults.groupby(['Season','WTeamID']).size()}).reset_index();\nlosses = pd.DataFrame({'losses': season_dresults.groupby(['Season','LTeamID']).size()}).reset_index();\n\nrecord = record.merge(losses, how='outer', left_on=['Season','WTeamID'], right_on=['Season','LTeamID'])\nrecord = record.fillna(0)\nrecord['games'] = record['wins'] + record['losses']\n\ndef delta_winPct(row):\n    cond1 = (record['Season'] == row['Season']) & (record['WTeamID'] == row['Team1'])\n    cond2 = (record['Season'] == row['Season']) & (record['WTeamID'] == row['Team2'])\n    return (record[cond1]['wins']/record[cond1]['games']).mean() - (record[cond2]['wins']/record[cond2]['games']).mean()\n\ntraining_set['deltaWinPct'] = training_set.apply(delta_winPct,axis=1)\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"281b3ff8de250e02167c6723c790a1d5f2cbed8b"},"cell_type":"code","source":"dfW = season_dresults.groupby(['Season','WTeamID']).sum().reset_index()\ndfL = season_dresults.groupby(['Season','LTeamID']).sum().reset_index()\n\ndef get_points_for(row):\n    wcond = (dfW['Season'] == row['Season']) & (dfW['WTeamID'] == row['WTeamID']) \n    fld1 = 'WScore'\n    lcond = (dfL['Season'] == row['Season']) & (dfL['LTeamID'] == row['WTeamID']) \n    fld2 = 'LScore'\n    retVal = dfW[wcond][fld1].sum()\n    if len(dfL[lcond][fld2]) > 0:\n        retVal = retVal + dfL[lcond][fld2].sum() \n    return retVal\n\ndef get_points_against(row):\n    wcond = (dfW['Season'] == row['Season']) & (dfW['WTeamID'] == row['WTeamID']) \n    fld1 = 'LScore'\n    lcond = (dfL['Season'] == row['Season']) & (dfL['LTeamID'] == row['WTeamID']) \n    fld2 = 'WScore'\n    retVal = dfW[wcond][fld1].sum()\n    if len(dfL[lcond][fld2]) > 0:\n        retVal = retVal + dfL[lcond][fld2].sum() \n    return retVal\n\nrecord['PointsFor'] = record.apply(get_points_for, axis=1)\nrecord['PointsAgainst'] = record.apply(get_points_against, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"480b72c0d60c4d049b764c6fd70a0a7e035426bc"},"cell_type":"code","source":"def get_remaining_stats(row, field):\n    wcond = (dfW['Season'] == row['Season']) & (dfW['WTeamID'] == row['WTeamID']) \n    fld1 = 'W' + field\n    lcond = (dfL['Season'] == row['Season']) & (dfL['LTeamID'] == row['WTeamID']) \n    fld2 = 'L'+ field\n    retVal = dfW[wcond][fld1].sum()\n    if len(dfL[lcond][fld2]) > 0:\n        retVal = retVal + dfL[lcond][fld2].sum()\n    return retVal\n\ncols = ['FGM','FGA','FGM3','FGA3','FTM','FTA','OR','DR','Ast','TO','Stl','Blk','PF']\n\nfor col in cols:\n    print(\"Processing\",col)\n    record[col] = record.apply(get_remaining_stats, args=(col,), axis=1)\n\n#record['FGprct'] = record['FGM'] / record['FGA']    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ce8952441201d0fdf48248ed979f9acaad94105f"},"cell_type":"code","source":"def delta_stat(row, field):\n    cond1 = (record['Season'] == row['Season']) & (record['WTeamID'] == row['Team1'])\n    cond2 = (record['Season'] == row['Season']) & (record['WTeamID'] == row['Team2'])\n    return (record[cond1][field]/record[cond1]['games']).mean() - (record[cond2][field]/record[cond2]['games']).mean()\n\ncols = ['PointsFor','PointsAgainst','FGM','FGA','FGM3','FGA3','FTM','FTA','OR','DR','Ast','TO','Stl','Blk','PF']\n\nfor col in cols:\n    print(\"Processing\",col)\n    training_set['delta' + col] = training_set.apply(delta_stat,args=(col,),axis=1)\n\ntraining_set.describe()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9458e08483d55ec9743c9a6ad5a13a6bd75509ca","scrolled":true},"cell_type":"code","source":"# Train a model on all of the data\nimport statsmodels.api as sm\n\n# Field descriptions:\n# deltaSeed: difference in team's seeds\n# deltaWinPct: difference in the team's winning percentage \n# deltaPointsFor: difference in the average points scored per game\n# deltaPointsAgainst: difference in the average points scored agains the teams\n# deltaFGM: difference in the field goals made per game\n# deltaFGA: difference in the field goals attempted per game\n# deltaFGM3: difference in 3 point fields goals made per game\n# deltaFGA3: difference in the 3 points fields goals attempted per game\n# deltaFTM: difference in free throws made per game\n# deltaFTA: difference in free throws attempted per game\n# deltaOR: difference in offence rebounds per game\n# deltaDR: difference in defensive rebounds per game\n# deltaAst: difference in assists per game\n# deltaTO: difference in turnovers per game\n# deltaStl: difference in steals per game\n# deltaBlk: difference in blocks per game\n# deltaPF: difference in personal fouls per game\n\n# You would probabaly want to select a subset of these attributes\ncols = ['deltaSeed', 'deltaWinPct','deltaPointsFor','deltaPointsAgainst','deltaFGM','deltaFGA','deltaFGM3','deltaFGA3','deltaFTM',\n        'deltaFTA','deltaOR','deltaDR','deltaAst','deltaTO','deltaStl','deltaBlk','deltaPF']\nX = training_set[cols]\ny = training_set['Result']\n\nlogit_model=sm.Logit(y,X)\nresult=logit_model.fit()\nprint(result.summary2())       \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a14da4d34515372c9c64879ae28e92f095f0e311"},"cell_type":"code","source":"# Stats from previous competitions\n\ntopprctvalues=[5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100]\n\n#                 2018     2019\nwinner=        [0.40681,0.32245,]\ntop5=          [0.42102,0.33531,]\ntopprctscores=[[0.43673,0.35553,], # 5%\n               [0.44596,0.36147,], # 10%\n               [0.45187,0.36786,], # 15%\n               [0.45688,0.37425,], # 20%\n               [0.46138,0.38114,], # 25%\n               [0.46603,0.38672,], # 30%\n               [0.47232,0.39384,], # 35%\n               [0.47954,0.39988,], # 40%\n               [0.48813,0.40669,], # 45%\n               [0.49291,0.41073,], # 50%\n               [0.50050,0.41809,], # 55%\n               [0.51622,0.42810,], # 60%\n               [0.53278,0.44893,], # 65%\n               [0.55833,0.50060,], # 70%\n               [0.58590,0.58947,], # 75%\n               [0.63404,0.79043,], # 80%\n               [0.69314,0.97132,], # 85%\n               [0.83175,16.99557,], # 90%\n               [1.03407,18.64027,], # 95%\n               [13.22375,24.12266,],] # 100%\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"90a16ea7dd5f29bf2d1276a0f9b7ec48e94b22b4"},"cell_type":"code","source":"# Run cross validation on model against tournaments in 2003-2018.  For the tournaments since 2014, the winning score\n# from the Kaggle tournament is displayed\n\n# TODO: Choose some columns to build the logistic regression models\ncols = ['deltaSeed', 'deltaWinPct', 'deltaPointsAgainst']\n\n# TODO: Adjust winning probabilities by this percent for selected teams, based on your\nbiases = {\n    '1163':1.2, # U Conn\n    '1181':1.2, # Duke \n    '1437':1.2, # Villanova\n    '1314':1.2, # UNC\n}\n\nerrs = []\nfor year in range(2010,2020):\n    print(\"Evaluation on tournament year\",year)\n    Xtrain = training_set[training_set['Season'] != year][cols]\n    ytrain = training_set[training_set['Season'] != year]['Result']\n\n    logit_model=sm.Logit(ytrain,Xtrain)\n    result=logit_model.fit()\n\n    Xtest = training_set[training_set['Season'] == year][cols]\n    ytest = training_set[training_set['Season'] == year]['Result']\n    \n    pred = result.predict(Xtest)\n    for bias in biases:\n        pred.loc[(training_set['Season'] == year) & (training_set['Team1'] == int(bias))] = pred.loc[(training_set['Season'] == year) & (training_set['Team1'] == int(bias))] * biases[bias] \n        pred.loc[(training_set['Season'] == year) & (training_set['Team2'] == int(bias))] = pred.loc[(training_set['Season'] == year) & (training_set['Team2'] == int(bias))] / biases[bias] \n    \n    pred.loc[(pred >= 0.9999)] = 0.9999\n    pred.loc[(pred <= 0.0001)] = 0.0001\n\n    pred.loc[training_set[training_set['Season'] == year]['Result'] == 0] = 1 - pred.loc[training_set[training_set['Season'] == year]['Result'] == 0] \n    err = -np.log(pred).mean()\n\n    errs.append(err)\n\nprint(\"Mean log loss: \",np.mean(errs))\n\n\n\nprint(\"Log losses by season\")\nprint(\"--------------------\")\nprint(\"year\",\"your score\",sep=\"\\t\")\nyears1 = range(2010,2018)\nfor i in range(len(years1)):\n    print(years1[i], \"{0:.6f}\".format(errs[i]),sep=\"\\t\")\n    \nprint(\"Log losses by season\")\nprint(\"--------------------\")\nprint(\"year\",\"your score\",\"your result\",\"winning score\",sep=\"\\t\")    \nyears2 = range(2018,2020)\nfor i in range(len(years2)):\n    result = None\n    if errs[i+len(years1)] < winner[i]:\n        result=\"Win competition\"\n    elif errs[i+len(years1)] < top5[i]:\n        result=\"Top 5 score\"\n    else:\n        for j in range(len(topprctvalues)):\n            if errs[i+len(years1)] < topprctscores[j][i]:\n                result = \"Top \" + str(topprctvalues[j]) + \"%\"\n                break\n        if result is None:\n            result = \"Worst score on Kaggle\"\n\n    print(years2[i], \"{0:.6f}\".format(errs[i+len(years1)]),result+\"\\t\",winner[i],sep=\"\\t\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"54c6646b08c127175474b4867121b28091c6db43"},"cell_type":"code","source":"## Create a submission file\nif ROUND2:\n    sub = pd.read_csv(DATA_PATH + 'WSampleSubmissionStage2_2020.csv')\nelse:\n    sub = pd.read_csv(DATA_PATH + 'WSampleSubmissionStage1_2020.csv')\n\n# Create predictor attributes (as above for the CV)\nsub['Season'], sub['Team1'], sub['Team2'] = sub['ID'].str.split('_').str\nsub[['Season', 'Team1', 'Team2']] = sub[['Season', 'Team1', 'Team2']].apply(pd.to_numeric)\n\nsub['deltaSeed'] = sub.apply(delta_seed,axis=1)\nsub['deltaWinPct'] = sub.apply(delta_winPct,axis=1)\n\ncols = ['PointsFor','PointsAgainst','FGM','FGA','FGM3','FGA3','FTM','FTA','OR','DR','Ast','TO','Stl','Blk','PF']\nfor col in cols:\n    print(\"Processing\",col)\n    sub['delta' + col] = sub.apply(delta_stat,args=(col,),axis=1)\n\n# Build the final model\ncols = ['deltaSeed', 'deltaWinPct', 'deltaPointsAgainst']\n\n# TODO: Adjust winning probabilities by this percent for selected teams, based on your\nbiases = {\n    '3163':1.2, # U Conn\n    '3181':1.2, # Duke \n    '3437':1.2, # Villanova\n    '3314':1.2, # UNC\n}\n\nXtrain = training_set[cols]\nytrain = training_set['Result']\n\nlogit_model=sm.Logit(ytrain,Xtrain)\nresult=logit_model.fit()\n\n# Make your predictions\nXtest = sub[cols]\npred = result.predict(Xtest)\n\n# Bias results based on team preferences\nfor bias in biases:\n    pred.loc[sub['Team1'] == int(bias)] = pred.loc[sub['Team1'] == int(bias)] * biases[bias] \n    pred.loc[sub['Team2'] == int(bias)] = pred.loc[sub['Team2'] == int(bias)] / biases[bias] \n    \npred.loc[(pred >= 0.9999)] = 0.9999\npred.loc[(pred <= 0.0001)] = 0.0001\n\n\n# Manually adjust some predictions\n# U Conn vs Duke\npred.loc[(sub['Team1'] == 3163) & (sub['Team2'] == 3181)] = 0.8\n\n# Create Submission file\nsub['Pred'] = pred\nsub[['ID', 'Pred']].to_csv('submission.csv', index=False)\n","execution_count":null,"outputs":[]}],"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":4}