比賽介紹及數(shù)據(jù)介紹
首先,很感謝以下幾位作者的鏈接:
【Sports+AI】Kaggle體育比賽預(yù)測(cè)總結(jié)
raddar大神的 如何只根據(jù)比賽的對(duì)陣信息來(lái)確定球隊(duì)的水平并排名
Paulo Pinto在討論區(qū)分享的Ken Pom數(shù)據(jù)的鏈接
更多的基礎(chǔ)想法可以參見(jiàn):https://www.kaggle.com/c/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/notebooks
賽題介紹
賽題為谷歌云和NACC合作對(duì)今年的NCAA男子和女子籃球錦標(biāo)賽的比賽結(jié)果做出預(yù)測(cè)。
比賽分為兩個(gè)階段嫉拐,目前位于階段一:參賽選手利用錦標(biāo)賽過(guò)去的結(jié)果構(gòu)建與測(cè)試模型侥钳。第二階段:等NACC在三月中開(kāi)賽坝冕,進(jìn)行真實(shí)比賽結(jié)果的預(yù)測(cè)膘融。
賽題的本質(zhì):一個(gè)二分類問(wèn)題孩擂,但本賽題采用對(duì)數(shù)損失函數(shù)作為評(píng)價(jià)指標(biāo),目的就是給過(guò)度自信或者不自信的判斷更大的懲罰熟史。
where
is the number of games played
is the predicted probability of team 1 beating team 2
is 1 if team 1 wins, 0 if team 2 wins
is the natural (base e) logarithm
def logloss(true_label, predicted, eps = 1e-15):
p = np.clip(predicted, eps, 1-eps) #clip這個(gè)函數(shù)將將數(shù)組中的元素限制在a_min, a_max之間馁害,大于a_max的就使得它等于 a_max,小于a_min,的就使得它等于a_min蹂匹。
if true_label ==1:
return - np.log(p)
return -np.log(1-p)
print(f'Confident Wrong Prediction: \t\t {logloss(1, 0.01):0.4f}') #logloss(0, 0.99)
print(f'Confident Correct Prediction: \t\t {logloss(0, 0.01):0.4f}') #logloss(1, 0.99)
print(f'Non-Confident Wrong Prediction: \t {logloss(1, 0.49):0.4f}') #logloss(0, 0.51)
print(f'Non-Confident Correct Prediction: \t {logloss(0, 0.49):0.4f}') #logloss(1, 0.51)
結(jié)果如下:
Confident Wrong Prediction: 4.6052
Confident Correct Prediction: 0.0101
Non-Confident Wrong Prediction: 0.7133
Non-Confident Correct Prediction: 0.673
可以看出碘菜,過(guò)度自信or不自信會(huì)產(chǎn)生極大的誤差,而比較中庸的評(píng)價(jià)(0.5左右)的損失相對(duì)來(lái)說(shuō)可以接受。
數(shù)據(jù)介紹
0.分別讀取男子和女子的數(shù)據(jù)
import os
os.getcwd()#獲得當(dāng)前工作目錄
os.chdir('D:\\比賽\\')
import numpy as np
import pandas as pd
pd.set_option('display.max_columns', 100)
import matplotlib as mpl
from matplotlib.patches import Circle, Rectangle, Arc
from matplotlib import pyplot as plt
import seaborn as sns
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")
import seaborn as sns
plt.style.use('seaborn-dark-palette')
mypal = plt.rcParams['axes.prop_cycle'].by_key()['color'] # Grab the color pal
import gc
men_folder_path = './kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/'
women_folder_path = './kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-womens-tournament/'
Mstage1_folder_path = 'MDataFiles_Stage1/'
Wstage1_folder_path = 'WDataFiles_Stage1/'
#讀取數(shù)據(jù)M
Mfolder_path = men_folder_path
Mteam_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'Teams.csv')
Mseason_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'Seasons.csv')
Mseed_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'NCAATourneySeeds.csv')
Mregular_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'RegularSeasonCompactResults.csv')
Mnacc_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'NCAATourneyCompactResults.csv')
Mregular_section1['is_regular'] = 1
Mnacc_section1['is_regular'] = 0
Mregular_detail_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'RegularSeasonDetailedResults.csv')
Mnacc_detail_section1 = pd.read_csv(Mfolder_path+Mstage1_folder_path+'M'+'NCAATourneyDetailedResults.csv')
Mregular_detail_section1['is_regular'] = 1
Mnacc_detail_section1['is_regular'] = 0
#讀取數(shù)據(jù)W
Wfolder_path = women_folder_path
Wprefix = 'M'
Wteam_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'Teams.csv')
Wseason_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'Seasons.csv')
Wseed_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'NCAATourneySeeds.csv')
Wregular_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'RegularSeasonCompactResults.csv')
Wnacc_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'NCAATourneyCompactResults.csv')
Wregular_section1['is_regular'] = 1
Wnacc_section1['is_regular'] = 0
Wregular_detail_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'RegularSeasonDetailedResults.csv')
Wnacc_detail_section1 = pd.read_csv(Wfolder_path+Wstage1_folder_path+'W'+'NCAATourneyDetailedResults.csv')
Wregular_detail_section1['is_regular'] = 1
Wnacc_detail_section1['is_regular'] = 0
- Team Data
包含了隊(duì)伍的TeamID炉媒、TeamName、FirstD1Season昆烁、LastD1Season吊骤。
Mteam_section1.sort_values('FirstD1Season', ascending = False).head()
- MTeams.csv and WTeams.csv
- 球隊(duì)信息,注意不是每個(gè)球隊(duì)在每個(gè)賽季都有比賽静尼,因?yàn)楸荣悢?shù)據(jù)只包含甲級(jí)部分白粉。
- 球隊(duì)ID:標(biāo)識(shí)一個(gè)大學(xué)的一只球隊(duì),4位數(shù)字鼠渺,10001999表示男隊(duì)鸭巴,30003999表示女隊(duì),該ID是不會(huì)變的拦盹。
- 球隊(duì)大學(xué)名稱的簡(jiǎn)潔寫法鹃祖。
- 球隊(duì)為1級(jí)聯(lián)賽的第一年,最早是1985年普舆,注意這部分只有男隊(duì)恬口。
- 球隊(duì)為1級(jí)聯(lián)賽的最近的一年,如果目前依然是一級(jí)沼侣,那么該值為2020祖能,同樣也只有男隊(duì)
- 按照FirstD1Season列排序,我們可以看到D1籃球中的一些最新球隊(duì)蛾洛。 比如 新軍Merrimack养铸!
2.Seasons Data
包含了賽季、賽季起始日期(Dayzero 也就是比賽的0點(diǎn) 后邊可以根據(jù)DayNum判斷比賽進(jìn)程)轧膘、每個(gè)賽季的四大賽區(qū)的名稱钞螟。
Mseason_section1.head()
- 不同賽季的歷史數(shù)據(jù),包含一些賽季屬性扶供。
- 賽季表示比賽的年份筛圆,注意當(dāng)前是2020賽季。
- DayZero表示賽季開(kāi)始的那一天的日期椿浓,結(jié)合DayNum可以計(jì)算當(dāng)前日期太援。
- RegionW,RegionX,RegionY,RegionZ表示四個(gè)分組區(qū)域,最后四強(qiáng)就是這4個(gè)區(qū)域中各自的最后冠軍扳碍。
3.Tourney Seed Data
包含賽季提岔、NACC錦標(biāo)賽的種子信息、對(duì)應(yīng)的TeamID笋敞。
Mseed_section1.head()
種子:格式為3/4字符組成碱蒙,前3個(gè)如下,例如W01,表示W(wǎng)分區(qū)的1號(hào)種子赛惩,如果有第4位哀墓,可能是a/b,進(jìn)一步區(qū)分前3個(gè)字符相同的球隊(duì)喷兼。 球隊(duì)Id篮绰。
將種子信息和Team Data合并
Wseed_section1.merge(Wteam_section1, validate='many_to_one').head()
- Regular Season Results
- 常規(guī)賽所有比賽信息。
- 賽季年份季惯。
- DayNum吠各。
- 勝利方的Id、分?jǐn)?shù)勉抓,失敗方的Id贾漏、分?jǐn)?shù)。
- 勝利方是主隊(duì)藕筋、客隊(duì)纵散,還是在第三方球場(chǎng)。如果獲勝團(tuán)隊(duì)是主隊(duì)念逞,則此值為“ H”home困食。如果獲勝團(tuán)隊(duì)是客隊(duì),則該值為“ A”away翎承。如果在中立的球場(chǎng)上進(jìn)行比賽硕盹,則該值為“ N”neutral。
- 加時(shí)次數(shù)叨咖,大于等于0.
查看主場(chǎng)獲勝的情況和加時(shí)賽的情況
Mregular_section1['WLoc'].value_counts()
H 95878
A 49260
N 16414
Mregular_section1['NumOT'].value_counts()
0 155529
1 4989
2 844
3 152
4 32
5 5
6 1
將數(shù)據(jù)按加時(shí)賽數(shù)目降序進(jìn)行展示
Mregular_section1.sort_values('NumOT', ascending=False).head()
查看WScore和Lscore的分布
'''
#bins ---> 箱數(shù)
#hist瘩例、ked ---> 是否顯示箱/密度曲線
#norm_hist ---> 直方圖是否按照密度來(lái)顯示
#rug ---> 是否顯示數(shù)據(jù)分布情況
#vertical ---> 是否水平顯示
#color ---> 設(shè)置顏色
#label ---> 圖例
#axlabel ---> x軸標(biāo)注
'''
sns.distplot(Mregular_section1['WScore'], label = 'WScore', axlabel = '')
sns.distplot(Mregular_section1['LScore'], label = 'LScore', axlabel = '')
plt.legend()
將常規(guī)賽數(shù)據(jù)和TeamData進(jìn)行合并
suffixes參數(shù) get 避免寫好多rename
#將Mregular_section1與Mteam_section1合并兩次 加入TeamName FirstD1Season LastD1Season 等列 后綴W L 區(qū)分
Mregular_section1 = Mregular_section1.merge(Mteam_section1,left_on=['WTeamID'],right_on=['TeamID'],validate='many_to_one').drop('TeamID',axis=1)
Mregular_section1 = Mregular_section1.merge(Mteam_section1,left_on=['LTeamID'],right_on=['TeamID'],suffixes=('_W', '_L'),validate='many_to_one').drop('TeamID',axis=1)
#將Wregular_section1與Wteam_section1合并兩次 加入TeamName列 后綴W L 區(qū)分
Wregular_section1 = Wregular_section1.merge(Wteam_section1,left_on=['WTeamID'],right_on=['TeamID'],validate='many_to_one').drop('TeamID',axis=1)
Wregular_section1 = Wregular_section1.merge(Wteam_section1,left_on=['LTeamID'],right_on=['TeamID'],suffixes=('_W', '_L'),validate='many_to_one').drop('TeamID',axis=1)
Mregular_section1.head()
分別看男子與女子比賽分差的分布
Mregular_section1['Score_Diff'] = Mregular_section1['WScore'] - Mregular_section1['LScore']
Wregular_section1['Score_Diff'] = Wregular_section1['WScore'] - Wregular_section1['LScore']
sns.distplot(a = Mregular_section1["Score_Diff"], bins=40, color="skyblue", hist=True, kde=False, rug=False, label = 'Men')
sns.distplot(a = Wregular_section1["Score_Diff"], bins=40, color="red", hist=True, kde=False, rug=False, label = 'Women')
plt.legend()
對(duì)常規(guī)賽勝場(chǎng)數(shù)進(jìn)行統(tǒng)計(jì)并可視化
#引入counter 對(duì)每個(gè)隊(duì)的勝場(chǎng)進(jìn)行累計(jì)
Mregular_section1['counter'] = 1
Wregular_section1['counter'] = 1
plt.subplots(figsize=(6, 4))
Most_MWinTeam = pd.DataFrame(Mregular_section1.groupby(['TeamName_W'])['counter'].count().sort_values(ascending = False)[:10])
Most_MWinTeam = Most_MWinTeam.reset_index()
ax = sns.barplot(x='counter', y='TeamName_W', data = Most_MWinTeam, color='blue', orient='h')
ax.set_title('Most Winning (Regular Season) Mens Teams', fontsize=15)
plt.subplots(figsize=(20, 8))
Most_MLoseTeam = pd.DataFrame(Mregular_section1.groupby(['TeamName_L'])['counter'].count().sort_values(ascending = False)[:20])
Most_MLoseTeam = Most_MLoseTeam.reset_index()
ax = sns.barplot(x='counter', y='TeamName_L', data = Most_MLoseTeam, color='blue', orient='h')
ax.set_title('Most Losing (Regular Season) Mens Teams', fontsize=15)
- 可以看出比賽具有明顯的主場(chǎng)優(yōu)勢(shì)。
- 曾在2009年出現(xiàn)過(guò)一次六加時(shí)甸各。
- 無(wú)論是勝分還是負(fù)分垛贤,整體均呈正太分布。
- 無(wú)論男女趣倾,比賽的分差主要分布在0-20分聘惦,且男子比賽更為集中,可能是實(shí)力差距小造成的儒恋。
- 在男子比賽中善绎,Duke勝場(chǎng)最多,且很多強(qiáng)隊(duì)例如Kansas诫尽、North carolina等也有著很高的勝場(chǎng)禀酱。而Chicago的負(fù)場(chǎng)最多。
- 在女子比賽中牧嫉,Connecticut勝場(chǎng)最多剂跟。而Air Force的負(fù)場(chǎng)最多减途。
- NCAA Season Results
- NCAA錦標(biāo)賽顾腊。
- 賽季年份币他。
- DayNum。
- 勝利方的Id臂寝、分?jǐn)?shù)送淆,失敗方的Id墓捻、分?jǐn)?shù)。
- 勝利方是主隊(duì)坊夫、客隊(duì),還是在第三方球場(chǎng)撤卢。
- 加時(shí)次數(shù)环凿,大于等于0.
均為中立球場(chǎng)
#如果獲勝團(tuán)隊(duì)是主隊(duì),則此值為“ H”放吩。如果獲勝團(tuán)隊(duì)是客隊(duì)智听,則該值為“ A”。如果在中立的球場(chǎng)上進(jìn)行比賽渡紫,則該值為“ N”到推。
Mnacc_section1['WLoc'].value_counts()
N 2251
Name: WLoc, dtype: int64
加時(shí)賽的次數(shù) 最多僅有一次三加時(shí)的出現(xiàn)
Mnacc_section1['NumOT'].value_counts()
0 2114
1 121
2 15
3 1
Name: NumOT, dtype: int64
該三加時(shí)出現(xiàn)在1995年
Mnacc_section1.sort_values('NumOT', ascending=False).head()
NACC中WScore和LScore的分布
sns.distplot(Mnacc_section1['WScore'], label = 'WScore', axlabel = '')
sns.distplot(Mnacc_section1['LScore'], label = 'LScore', axlabel = '')
plt.legend()
將NACC數(shù)據(jù)和TeamData合并 并得到分差進(jìn)行可視化 并看一下男女比賽中最大分差
#將Mregular_section1與Mteam_section1合并兩次 加入TeamName FirstD1Season LastD1Season 等列 后綴W L 區(qū)分
Mnacc_section1 = Mnacc_section1.merge(Mteam_section1,left_on=['WTeamID'],right_on=['TeamID'],validate='many_to_one').drop('TeamID',axis=1)
Mnacc_section1 = Mnacc_section1.merge(Mteam_section1,left_on=['LTeamID'],right_on=['TeamID'],suffixes=('_W', '_L'),validate='many_to_one').drop('TeamID',axis=1)
#將Wregular_section1與Wteam_section1合并兩次 加入TeamName列 后綴W L 區(qū)分
Wnacc_section1 = Wnacc_section1.merge(Wteam_section1,left_on=['WTeamID'],right_on=['TeamID'],validate='many_to_one').drop('TeamID',axis=1)
Wnacc_section1 = Wnacc_section1.merge(Wteam_section1,left_on=['LTeamID'],right_on=['TeamID'],suffixes=('_W', '_L'),validate='many_to_one').drop('TeamID',axis=1)
Mnacc_section1['Score_Diff'] = Mnacc_section1['WScore'] - Mnacc_section1['LScore']
Wnacc_section1['Score_Diff'] = Wnacc_section1['WScore'] - Wnacc_section1['LScore']
sns.distplot(a = Mnacc_section1["Score_Diff"], color="skyblue", hist=True, kde=False, rug=False, label = 'Men')
sns.distplot(a = Wnacc_section1["Score_Diff"], color="red", hist=True, kde=False, rug=False, label = 'Women')
plt.legend()
Wnacc_section1["Score_Diff"].max()
89
Mnacc_section1["Score_Diff"].max()
58
對(duì)NACC的勝場(chǎng)數(shù)進(jìn)行統(tǒng)計(jì)并可視化
#引入counter 對(duì)每個(gè)隊(duì)的勝場(chǎng)進(jìn)行累計(jì)
Mnacc_section1['counter'] = 1
Wnacc_section1['counter'] = 1
plt.subplots(figsize=(20, 8))
Most_MnaccWinTeam = pd.DataFrame(Mnacc_section1.groupby(['TeamName_W'])['counter'].count().sort_values(ascending = False)[:20])
Most_MnaccWinTeam = Most_MnaccWinTeam.reset_index()
ax = sns.barplot(x='counter', y='TeamName_W', data = Most_MnaccWinTeam, color='blue', orient='h')
ax.set_title('Most Winning (NACC Season) Mens Teams', fontsize=15)
plt.subplots(figsize=(20, 8))
Most_MnaccLoseTeam = pd.DataFrame(Mnacc_section1.groupby(['TeamName_L'])['counter'].count().sort_values(ascending = False)[:20])
Most_MnaccLoseTeam = Most_MnaccLoseTeam.reset_index()
ax = sns.barplot(x='counter', y='TeamName_L', data = Most_MnaccLoseTeam, color='blue', orient='h')
ax.set_title('Most Losing (NACC Season) Mens Teams', fontsize=15)
- NACC均為中立球場(chǎng),沒(méi)有主場(chǎng)優(yōu)勢(shì)惕澎。
- NACC曾在1995年出現(xiàn)過(guò)一次三加時(shí)莉测,雙加時(shí)也比較罕見(jiàn)。
- 無(wú)論是勝分還是負(fù)分唧喉,整體均呈正太分布捣卤。
- 無(wú)論男女,比賽的分差主要分布在0-20分八孝,且男子比賽更為集中董朝,可能是實(shí)力差距小造成的。女子的最大分差為89分干跛,男子最大的的分差為58分子姜。
- 與常規(guī)賽相似,在男子比賽中楼入,Duke勝場(chǎng)最多哥捕,且很多強(qiáng)隊(duì)例如Kansas、North carolina等也有著很高的勝場(chǎng)浅辙。而能在負(fù)場(chǎng)上有著不錯(cuò)的排名也證明了球隊(duì)有著不俗的實(shí)力扭弧,因?yàn)槟阈枰M(jìn)入NACC才有資格輸,可以看到Duke记舆、Kansas在負(fù)場(chǎng)榜也名列前茅鸽捻。
- 在女子比賽中,Connecticut勝場(chǎng)最多。而Stanford御蒲、Duke等的負(fù)場(chǎng)最多衣赶。
6.DetailedResults(Only Men)
- 基本信息:
- 自02-03賽季以來(lái)的各種比賽的罰球、防守籃板厚满、失誤等數(shù)據(jù)府瞄。
- 與第1部分的CompactResult相比,前8列是一致的碘箍,從WTeamId到NumOT遵馆,但是這里會(huì)有其他很多數(shù)據(jù),比如二分球個(gè)數(shù)丰榴、三分球個(gè)數(shù)货邓、發(fā)球個(gè)數(shù)、犯規(guī)次數(shù)等等四濒。
- 最終分?jǐn)?shù)可以由以下方式表示:2×FGM + FGM3 + FTM换况,即2×進(jìn)球數(shù)+三分球數(shù)+罰球數(shù)=總分。
- 這里的信息與第1部分中的比賽信息是嚴(yán)格對(duì)應(yīng)的盗蟆。
- MRegularSeasonDetailedResults.csv
- 03賽季以來(lái)所有非NCAA錦標(biāo)賽以外的比賽的詳細(xì)信息戈二。
- MNCAATourneyDetailedResults.csv
- 03賽季以來(lái)所有NCAA錦標(biāo)賽以外的比賽的詳細(xì)信息。
- 詳細(xì)指標(biāo)
- WFGM:投籃命中數(shù)喳资。
- WFGA:未命中數(shù)觉吭。
- WFGM3:3分命中數(shù),注意這部分?jǐn)?shù)據(jù)是包含在WFGM中的仆邓。
- WFGA3:3分未命中數(shù)亏栈。
- WFTM:罰球命中數(shù)。
- WFTA:罰球未命中數(shù)宏赘。
- WOR:進(jìn)攻籃板绒北。
- WDR:防守籃板。
- WAst:助攻數(shù)察署。
- WTO:失誤數(shù)闷游。
- WStl:搶斷數(shù)。
- WBlk:蓋帽數(shù)贴汪。
- WPF:個(gè)人犯規(guī)數(shù)脐往。
- 失敗方為用L替換W,意思一致扳埂。
Mregular_detail_section1.head(3)
基礎(chǔ)數(shù)據(jù)和細(xì)節(jié)數(shù)據(jù)在特征和數(shù)量上的差異
print(Mregular_section1.shape)
print(Mregular_detail_section1.shape)
print(Mnacc_section1.shape)
print(Mnacc_detail_section1.shape)
(161552, 17)
(87504, 35)
(2251, 17)
(1115, 35)
- regular_section1 和 nacc_section1 一致 只含有Season业簿、DayNum、WTeamID阳懂、WScore梅尤、LTeamID柜思、LScore、WLoc巷燥、NumOT
- regular_detail_section1 和 nacc_detail_section1 一致 且均有以上列
- 唯一的區(qū)別是年份 前者始于1985 后者始于2003
將數(shù)據(jù)進(jìn)行合并進(jìn)行更多的討論
#對(duì)于概況數(shù)據(jù)
#將常規(guī)賽和NCC比賽進(jìn)行合并 并排序
section1 = Mregular_section1.append(Mnacc_section1, ignore_index=True).sort_values(by=['Season','DayNum'])
#將數(shù)據(jù)和seed_section1聯(lián)結(jié) 加入輸贏球隊(duì)的賽區(qū)種子
#section1 = section1.merge(Mseed_section1,left_on=['Season','WTeamID'],right_on=['Season','TeamID']).drop('TeamID',axis=1)
#section1 = section1.merge(Mseed_section1,left_on=['Season','LTeamID'],right_on=['Season','TeamID'],suffixes=('_W', '_L')).drop('TeamID',axis=1)
#將數(shù)據(jù)和season_section1進(jìn)行聯(lián)結(jié) 加入DayZero RegionW RegionX RegionY RegionZ 等列
section1 = section1.merge(Mseason_section1,left_on=['Season'],right_on=['Season'])
#將數(shù)據(jù)和team_section1進(jìn)行聯(lián)結(jié)兩次 加入TeamName FirstD1Season LastD1Season 等列 后綴W L 區(qū)分 前邊已經(jīng)進(jìn)行過(guò)一次操作
#section1 = section1.merge(Mteam_section1,left_on=['WTeamID'],right_on=['TeamID']).drop('TeamID',axis=1)
#section1 = section1.merge(Mteam_section1,left_on=['LTeamID'],right_on=['TeamID'],suffixes=('_W', '_L')).drop('TeamID',axis=1)
section1 = section1.sort_values(by=['Season','DayNum'])
section1.shape
#對(duì)于詳細(xì)數(shù)據(jù)
section1_detail = Mregular_detail_section1.append(Mnacc_detail_section1, ignore_index=True).sort_values(by=['Season','DayNum'])
#section1_detail = section1_detail.merge(Mseed_section1,left_on=['Season','WTeamID'],right_on=['Season','TeamID']).drop('TeamID',axis=1)
#section1_detail = section1_detail.merge(Mseed_section1,left_on=['Season','LTeamID'],right_on=['Season','TeamID'],suffixes=('_W', '_L')).drop('TeamID',axis=1)
section1_detail = section1_detail.merge(Mseason_section1,left_on=['Season'],right_on=['Season'])
section1_detail = section1_detail.merge(Mteam_section1,left_on=['WTeamID'],right_on=['TeamID']).drop('TeamID',axis=1)
section1_detail = section1_detail.merge(Mteam_section1,left_on=['LTeamID'],right_on=['TeamID'],suffixes=('_W', '_L')).drop('TeamID',axis=1)
section1_detail = section1_detail.sort_values(by=['Season','DayNum'])
section1_detail.shape
Count of Champion and second(冠軍赡盘、亞軍的次數(shù)可視化)
##利用DayNum == 154 將每一年的決賽取出
final_round = section1.query('DayNum == 154')
#plt.figure來(lái)設(shè)置窗口尺寸。
plt.subplots(figsize=(20, 8))
#wspace = 0.2 為子圖之間的空間保留的寬度缰揪,平均軸寬的一部分
#hspace = 0.2 為子圖之間的空間保留的高度陨享,平均軸高度的一部分
plt.subplots_adjust(wspace=0, hspace=.6)
plt.subplot(2,1,1)
#rotation代表lable顯示的旋轉(zhuǎn)角度。
plt.xticks(rotation=30)
sns.countplot(x="TeamName_W", data=final_round)
plt.subplot(2,1,2)
plt.xticks(rotation=30)
sns.countplot(x="TeamName_L", data=final_round)
每一年決賽的分?jǐn)?shù)走勢(shì)
final_round['Score_diff'] = final_round['WScore'] - final_round['LScore']
sns.lineplot(data=final_round[['Season','WScore','LScore','Score_diff']].set_index('Season'))
plt.legend(loc = 1)
- 冠軍數(shù)最多的是杜克大學(xué)钝腺,共獲得5次錦標(biāo)賽冠軍抛姑,其次是北卡和康涅狄格州,分別獲得4次冠軍
- 亞軍數(shù)最多的是杜克和密歇根大學(xué)艳狐,均為4次途戒,其次是堪薩斯的3次
- 近年來(lái)決賽的分差較小
對(duì)進(jìn)32強(qiáng)、16強(qiáng)僵驰、8強(qiáng)、4強(qiáng)唁毒、決賽的次數(shù)進(jìn)行統(tǒng)計(jì)并可視化
#根據(jù)DayNum確定比賽階段 根據(jù)TeamName_W進(jìn)行分組 對(duì)Season進(jìn)行累計(jì)
team32 = section1.query('DayNum == 136 or DayNum == 137').groupby('TeamName_W')['Season'].count().rename('Count32').reset_index().sort_values(by='Count32',ascending=False).iloc[:10]
team16 = section1.query('DayNum == 138 or DayNum == 139').groupby('TeamName_W')['Season'].count().rename('Count16').reset_index().sort_values(by='Count16',ascending=False).iloc[:10]
team8 = section1.query('DayNum == 143 or DayNum == 144').groupby('TeamName_W')['Season'].count().rename('Count8').reset_index().sort_values(by='Count8',ascending=False).iloc[:10]
team4 = section1.query('DayNum == 145 or DayNum == 146').groupby('TeamName_W')['Season'].count().rename('Count4').reset_index().sort_values(by='Count4',ascending=False).iloc[:10]
team2 = section1.query('DayNum == 152').groupby('TeamName_W')['Season'].count().rename('Count2').reset_index().sort_values(by='Count2',ascending=False).iloc[:10]
plt.subplots(figsize=(20, 10))
plt.subplot(2,3,1)
plt.xticks(rotation=30)
sns.barplot(x="TeamName_W", y='Count32', data=team32)
plt.subplot(2,3,2)
plt.xticks(rotation=30)
sns.barplot(x="TeamName_W", y='Count16', data=team16)
plt.subplot(2,3,3)
plt.xticks(rotation=30)
sns.barplot(x="TeamName_W", y='Count8', data=team8)
plt.subplot(2,3,4)
plt.xticks(rotation=30)
sns.barplot(x="TeamName_W", y='Count4', data=team4)
plt.subplot(2,3,5)
plt.xticks(rotation=30)
sns.barplot(x="TeamName_W", y='Count2', data=team2)
- 進(jìn)入32強(qiáng)最多的球隊(duì)是堪薩斯的32次
- 進(jìn)入16強(qiáng)最多的球隊(duì)是杜克的25次
- 進(jìn)入8強(qiáng)最多的球隊(duì)是肯塔基的17次蒜茴;
- 進(jìn)入4強(qiáng)最多的球隊(duì)是杜克的12次;
- 進(jìn)入決賽最多的球隊(duì)是杜克的9次浆西;
- 其中結(jié)合之前的分析粉私,杜克大學(xué)9次進(jìn)入決賽,最終獲得5次冠軍近零,4次亞軍的傲人成績(jī)
看一下每一賽季NACC比賽階段的平均分差
#section1.groupby(['is_regular','DayNum'])['Season'].count()
tournament = section1.query('DayNum >= 134 and DayNum <= 154')
tournament['ScoreDiv'] = tournament['WScore'] - tournament['LScore']
tournament = tournament.groupby('Season')[['WScore','LScore','ScoreDiv']].mean().reset_index()
plt.subplots(figsize=(20, 5))
sns.barplot(x="Season", y='ScoreDiv', data=tournament)
- 錦標(biāo)賽平均分差最大的是1993年
- 錦標(biāo)賽平均分差最小的是1985年
- 近5年平均分差在11分左右
- 各個(gè)賽季之間差異不大
將決賽的數(shù)據(jù)和種子信息和賽區(qū)信息進(jìn)行合并 探究種子號(hào)數(shù)和賽區(qū)和奪冠之間的關(guān)系
- 種子長(zhǎng)度為4的提取中間兩位 為3的提取后兩位
- 種子第一位可以獲取屬于哪個(gè)賽區(qū) 和Region合并 再取對(duì)應(yīng)列的數(shù)據(jù) 即為賽區(qū)
section1 = section1.merge(Mseed_section1,left_on=['Season','WTeamID'],right_on=['Season','TeamID']).drop('TeamID',axis=1)
section1 = section1.merge(Mseed_section1,left_on=['Season','LTeamID'],right_on=['Season','TeamID'],suffixes=('_W', '_L')).drop('TeamID',axis=1)
final_round = section1.query('DayNum == 154')
'''
其中第一個(gè)字符是W诺核,X,Y或Z(標(biāo)識(shí)團(tuán)隊(duì)所在的區(qū)域)
后兩個(gè)數(shù)字(01久信、02窖杀, ...,15或16)告訴您該區(qū)域內(nèi)的種子裙士。
對(duì)于參加比賽的球隊(duì)入客,第四個(gè)字符(a或b)可以進(jìn)一步區(qū)分種子,因?yàn)樵趨⒓颖荣惖谋荣愔斜舜嗣鎸?duì)的球隊(duì)將擁有前三個(gè)角色相同的種子腿椎。
'''
#根據(jù)Seed的定義 對(duì)其進(jìn)行切分 取出所在區(qū)域 并得到種子號(hào)
final_round['Seed_W_num'] = final_round.Seed_W.apply(lambda seed:int(seed[1:]) if len(seed)==3 else int(seed[1:-1]))
final_round['Seed_L_num'] = final_round.Seed_L.apply(lambda seed:int(seed[1:]) if len(seed)==3 else int(seed[1:-1]))
final_round['Seed_W_code'] = final_round.Seed_W.apply(lambda seed:'Region'+seed[0])
final_round['Seed_L_code'] = final_round.Seed_L.apply(lambda seed:'Region'+seed[0])
#根據(jù)Seed_L_code確定賽區(qū)
final_round['Seed_W_region'] = final_round.apply(lambda row:row[row['Seed_W_code']], axis=1)
final_round['Seed_L_region'] = final_round.apply(lambda row:row[row['Seed_L_code']], axis=1)
plt.subplots(figsize=(20, 10))
plt.subplots_adjust(wspace=0.2, hspace=0.4)
plt.subplot(3,1,1)
sns.countplot(x="Seed_W_num", data=final_round)
plt.subplot(3,1,2)
sns.countplot(x="Seed_W_region", data=final_round)
plt.subplot(3,1,3)
sns.lineplot(x="Season", y="Seed_W_num", estimator=None, data=final_round)
- 各個(gè)分區(qū)的1號(hào)種子依然是冠軍的大熱門桌硫,共22次獲得冠軍,且冠軍數(shù)量與種子號(hào)基本線性負(fù)相關(guān)啃炸,這說(shuō)明賽前的種子指定的還是相當(dāng)準(zhǔn)確的
- 賽區(qū)上看铆隘,Midwest獲得冠軍最多,其次是South南用,這說(shuō)明在賽區(qū)這一個(gè)維度上膀钠,實(shí)例是不太平衡的掏湾,這點(diǎn)跟NBA不太一樣,NBA由于存在這工資帽這種機(jī)制托修,使得其各隊(duì)實(shí)力相對(duì)會(huì)被限制到一個(gè)范圍內(nèi)忘巧,而大學(xué)則是有籃球名校的存在的
- 從獲得冠軍的球隊(duì)種子號(hào)的趨勢(shì)圖看,冠軍越來(lái)越難以出現(xiàn)完全的黑馬睦刃,基本上以1,2,3號(hào)種子中出現(xiàn)砚嘴,當(dāng)然了,并不是說(shuō)3號(hào)種子就不是黑馬
本節(jié)完
下節(jié)帶來(lái) - 比賽詳細(xì)統(tǒng)計(jì)數(shù)據(jù)可視化