機器學習競賽分享:NFL大資料碗(上篇)
kaggle競賽分享:NFL大資料碗 - 上
競賽簡介
一年一度的NFL大資料碗,今年的預測目標是通過兩隊球員的靜態資料,預測該次進攻推進的碼數,並轉換為該概率分佈;
競賽連結
https://www.kaggle.com/c/nfl-big-data-bowl-2020
專案連結,該專案程式碼已經public,大家可以copy下來直接執行
https://www.kaggle.com/holoong9291/nfl-big-data-bowl
github倉庫連結,更多做的過程中的一些思考、問題等可以在我的github中看到
https://github.com/NemoHoHaloAi/Competition/tree/master/kaggle/Top61%25-0.01404-zzz-NFL-Big-Data-Bowl
一些基本概念
- 美式足球:進攻方目的是通過跑動、傳球等儘快抵達對方半場,也就是達陣,而防守方的目的則是相反,盡全力去阻止對方的前進以及儘可能斷球;
- 球場長120碼(109.728米),寬53碼(48.768米),周長是361.992米;
- 球員:雙方場上共22人,進攻方11人,防守方11人,進攻方持球;
- 進攻機會:進攻方共有四次機會,需要推進至少十碼;
- 進攻方:進攻方的職責是通過四次機會,儘可能的向前推進10碼或者達陣,以獲得下一個四次機會,否則就需要交出球權;
- 防守方:防守方則是相反,儘可能的阻止對方前進,如果能夠斷球那更好,直接球權交換;
- handoff:傳球;
- snap:發球;
- 橄欖球基本知識點我瞭解;
- QB:四分衛,通常是發球後接球的那個人,一般口袋陣的中心,但是也不乏有像拉馬爾-傑克遜這樣的跑傳結合的QB,目前古典QB代表是新英格蘭愛國者NE的湯姆-布雷迪;
- RB:跑衛,通常發球後進行衝刺、擺脫等,試圖接住本方QB的傳球后儘可能遠的衝刺;
球場碼線圖
一個常見的開球前站點陣圖
資料欄位介紹、繪圖分析
欄位資訊:
GameId
- a unique game identifier - 比賽IDPlayId
- a unique play identifier -Team
- home or away - 主場還是客場X
- player position along the long axis of the field. See figure below. - 在球場的位置xY
- player position along the short axis of the field. See figure below. - 在球場的位置yS
- speed in yards/second - 速度,碼/秒A
- acceleration in yards/second^2Dis
- distance traveled from prior time point, in yardsOrientation
- orientation of player (deg) 球員面向Dir
- angle of player motion (deg) 球員移動方向NflId
- a unique identifier of the player - NFL球員IDDisplayName
- player's name - 球員名JerseyNumber
- jersey number - 球衣號碼Season
- year of the seasonYardLine
- the yard line of the line of scrimmageQuarter
- game quarter (1-5, 5 == overtime) - 當前是第幾節比賽,5為加時GameClock
- time on the game clock - 比賽時間PossessionTeam
- team with possession - 持球方Down
- the down (1-4) - 達陣Distance
- yards needed for a first down - 距離拿首攻所需距離FieldPosition
- which side of the field the play is happening onHomeScoreBeforePlay
- home team score before play started - 賽前主隊分數VisitorScoreBeforePlay
- visitor team score before play started - 賽前客隊分數NflIdRusher
- the NflId of the rushing playerOffenseFormation
- offense formationOffensePersonnel
- offensive team positional groupingDefendersInTheBox
- number of defenders lined up near the line of scrimmage, spanning the width of the offensive lineDefensePersonnel
- defensive team positional groupingPlayDirection
- direction the play is headedTimeHandoff
- UTC time of the handoff - 傳球時間TimeSnap
- UTC time of the snap - 發球時間Yards
- the yardage gained on the play (you are predicting this) - 目標PlayerHeight
- player height (ft-in) - 球員身高PlayerWeight
- player weight (lbs) - 球員體重PlayerBirthDate
- birth date (mm/dd/yyyy) - 生日、歲數PlayerCollegeName
- where the player attended college - 大學Position
- the player's position (the specific role on the field that they typically play) - 場上位置HomeTeamAbbr
- home team abbreviation - 主隊縮寫VisitorTeamAbbr
- visitor team abbreviation - 客隊縮寫Week
- week into the seasonStadium
- stadium where the game is being played - 體育場Location
- city where the game is being player - 城市StadiumType
- description of the stadium environment - 體育場型別Turf
- description of the field surface - 草皮GameWeather
- description of the game weather - 比賽天氣Temperature
- temperature (deg F) - 溫度Humidity
- humidity - 溼度WindSpeed
- wind speed in miles/hour - 風速WindDirection
- wind direction - 風向
定義問題
迴歸預測,Target是碼數,但是最終結果需要轉換為條件概率分佈;
Evaluation Function
Continuous Ranked Probability Score (CRPS);
專案流程分享
定義模型輸出結果到概率分佈的轉換類
這裡競賽需要的並不是具體的碼數,而是碼數對應的概率分佈,也就是所有碼數在一次進攻中的概率,所以需要這樣一個轉換類,如下:
缺失值處理
訓練資料上看,缺失情況不嚴重,缺失欄位如下:
這裡對缺失的處理根據不同型別的欄位採取不同的方式:
- 天氣相關欄位,由於天氣具有連續性,因此採用前向填充較為合理:
- 體育場型別,嚴格來說應該是通過baidu、google等去搜索,但是NFL的相關資訊baidu搜到的太少,google上看也沒找到,所以用取值最多的來填充:
- FieldPosition,這個欄位的缺失不同於以上兩個,通過對資料的分析,它的缺失源於在中線開球時,此時沒法明確指出是在哪個半場,所以缺失,這裡用一個特別的值來填充,“Middle”;
- OffenseFormation,進攻隊形,實際缺失了5條,統一用取值最多的來填充即可;
- DefendersInTheBox,防守方在混戰線附近的人數,通過觀察資料可以通過球隊、對手、以及防守組成員來填充DefendersInTheBox:
- Orientation 球員方位-角度,Dir 球員移動-角度,只有一條缺失,且該球員正常上場了的,應該是技術型缺失,用mean填充即可;
異常、重複等處理
- StadiumType:存在不同名但是同意思的情況,這裡要整理後歸一處理,避免對模型產生干擾;
- 存在PossessionTeam既不是HomeTeamAbbr也不是VisitorTeamAbbr,共有120場比賽中出現這種情況;
- 草皮欄位處理;
- Location欄位也存在重複含義但是不同值的情況需要歸一;
EDA:探索性資料分析
下面是通過matplotlib繪製的一場比賽中的多個進攻防守回合的展示圖,黑色三角形是QB,紅色是進攻方,淡藍色是防守方:
可以清楚的看到每次進攻不同的站位,以及整個推進的過程,這裡我記錄的一份NFL比賽手記,愛國者vs烏鴉,新老QB的正面交鋒,非常精彩,可以對照著看一下;
特徵工程
這裡由於我個人對橄欖球的瞭解也並不是很多(強推電影弱點),所以特徵工程部分做的並不是很好,從結果看Top61%也反映除了這個問題,但是我依然覺得具有一定的參考意義,下面我會分析每個新特徵構建的目的,以及我的想法;
- WindSpeed,WindDirection:直觀看,對比賽影響應該不大,可能存在某些傳球手喜歡順風或者逆風,但是影響應該很小,所以我這裡選擇丟棄;
- PlayerHeight:轉為球員身高,身高無疑對比賽是有關係的;
- PlayerBirthDate:生日轉為歲數,歲數可以表示一個球員的身體狀況是否處於巔峰等;
- 開球到傳球的時間 - (TimeHandoff-TimeSnap):我認為這一時間的長短一定程度上決定了戰術的選擇,而戰術肯定是影響了進攻碼數的;
- 比賽進行時間 - (15-GameClock+Quarter*15):比賽進行了多久對球員們的體力、戰術選擇等都有很大影響;
- Position_XX:用於統計當前進攻中場上各個角色的人陣列成,這也跟戰術選擇密切關係;
- goal區:碼線對方半場10碼或10碼內,此時距離達陣不到10碼,一般這種情況下戰術選擇會變得與之前不太一樣,不管是防守方還是進攻方;
- 首攻危險:這是我自己定義的,即當目前進攻方僅有一次進攻機會,而所需繼續進攻的碼數大於5時,我認為是有首攻危險的,此時很可能丟失球權,down為4,且distance大於5;
- 距離達陣還有多少碼:一般距離的不同,防守方的防守策略會有不同,距離較遠一般會較為保守,距離較近則會比較激進;
- 其餘object特徵做label encode處理;
聚合資料並整理聚體統計特徵
這裡要注意,訓練資料每一行表示的是一次進攻中一個球員的情況,我們預測的是每次進攻,因此需要把每22條資料聚合為1條,這個過程中會有一些資料統計特徵的產生,下面簡介整個流程:
- 延遲特徵:即每個球員分別在之後0.5s,1s,2s,3s後的位置資訊;
- 平均特徵:分為進攻方和防守方,平均速度、平均加速度、平均身高、平均體重、平均年齡;
- 持球人為中心特徵:當前、延遲0.5s,1s,2s,3s時,進攻方和防守方球員與他的平均距離;
- 持球人為中心特徵2:當前、延遲0.5s,1s,2s,3s時,進攻方和防守方球員在持球人3碼、5碼內的人數估計;
一次進攻的成敗,大部分情況下取決於四分衛的發揮,而對其發揮其重要作用的,除了他自己,就是他身邊的隊友以及對手的數量,這一定程度上影響了他的可選擇空間大小;
這一段的處理程式碼較多,只截取了一部分,如下:
測試資料處理
測試資料處理與訓練資料保持一致即可;
建模
到此,資料處理完畢,後續就是建模、調參、combine等優化處理了,這一步我沒有花太多精力,模型選擇ExtraTreesRegressor,由於其使用了oob,因此不需要CV,結果如下:
最後
大家可以到我的Github上看看有沒有其他需要的東西,目前主要是自己做的機器學習專案、Python各種指令碼工具、資料分析挖掘專案以及Follow的大佬、Fork的專案等:
https://github.com/NemoHoHal