久久精品中文字幕免费_91香蕉国产亚洲一区二区三区_国产精品巨作无遮拦_亚洲人成电影

    <center id="oy65s"><ol id="oy65s"></ol></center>

  • <menu id="oy65s"></menu>
    當(dāng)前位置:首頁 > 足球資訊 > 正文內(nèi)容

    Soccermatics之三: 足球數(shù)據(jù)集計(jì)算預(yù)期進(jìn)球xG(Expected Goal)

    杏彩體育2年前 (2023-01-31)足球資訊51

    Soccermatics之三: 足球數(shù)據(jù)集計(jì)算xG(Expected Goal)

    開始之前

    本篇假設(shè)讀者熟悉python編程、matplotlib和pandas軟件包的使用。

    代碼還是用到了足球數(shù)據(jù)解析軟件kloppy和機(jī)器學(xué)習(xí)軟件包scikit-learn,它們都是開源軟件。

    開發(fā)環(huán)境和數(shù)據(jù)集參考本系列的第一篇。

    為了方便,代碼中不再使用公制單位作為球場中的位置坐標(biāo),直接使用數(shù)據(jù)集中的原始單位碼(yard)。

    鳴謝

    數(shù)據(jù)集使用了Statsbomb公司(https://www.statsbomb.com)的開放數(shù)據(jù)(https://github.com/statsbomb/open-data)。

    什么是xG

    xG是Expected Goal的縮寫,用于表示一次射門可能的得分機(jī)會,在某些其他運(yùn)動中也有使用(比如冰球)。一次射門的xG通常是一個(gè)[0,1]之間的數(shù)字,如果一次射門進(jìn)球了,那么它的xG就是1。數(shù)字越大表示可能進(jìn)球的概率越大。雖然xG看起來像是概率,但媒體經(jīng)常會把球員多場比賽的xG表現(xiàn)或者球隊(duì)xG加起來衡量其表現(xiàn),因此xG更像一個(gè)數(shù)學(xué)期望。

    目前xG還沒有一個(gè)特別統(tǒng)一的定義。

    看起來xG像是數(shù)據(jù)分析人員才會關(guān)心的指標(biāo),實(shí)際上xG已經(jīng)興起并且被媒體接受,一些發(fā)布比賽結(jié)果以及簡單統(tǒng)計(jì)數(shù)據(jù)的網(wǎng)站,往往會同時(shí)發(fā)布球員和球隊(duì)的xG數(shù)據(jù)。比如愛奇藝在直播今年賽季歐冠的時(shí)候,也會展現(xiàn)球隊(duì)的xG數(shù)據(jù),愛奇藝把xG稱為“預(yù)期進(jìn)球”。

    sky sports dominic calvert lewin xG

    這里舉例,計(jì)算xG可能會使用到下面一些要素:

    位置:射門發(fā)生球場的哪個(gè)位置;

    射門部位:球員使用頭或者左腳還是右腳射門?這個(gè)數(shù)據(jù)在我們使用的公開數(shù)據(jù)集里是有的;

    傳球類型:射門球員得到的傳球是直塞、回傳還是定位球?是高球還是地面球?這些數(shù)據(jù)在statsbomb公開數(shù)據(jù)集也有;

    每一次射門都與數(shù)千次具有相似特征的射門進(jìn)行比較,以確定這次射門進(jìn)球的可能性。這個(gè)可能性就是預(yù)期目標(biāo)總數(shù)。0的 xG 是確定失誤,而1的 xG 是確定的進(jìn)球。如果 xG 為0.5,則表示如果嘗試同樣的射門10次,則預(yù)計(jì)會進(jìn)5球。點(diǎn)球的xG固定為0.75。

    xG的一些用途如下:

    比較 xG 和實(shí)際得分可以衡量一個(gè)球員的射門能力或運(yùn)氣;XG 可以用來評估球隊(duì)在各種情況下的能力,比如面對空門、任意球、角球等等;在國外會在betting中使用xG;

    注意不同實(shí)體發(fā)布的xG的計(jì)算模型并不一致,也沒有哪家的數(shù)據(jù)特別權(quán)威。

    在xG基礎(chǔ)上派生出了很多關(guān)聯(lián)的指標(biāo),比如xGA,xGBuildup,xGChain等等,但都不如xG這么流行,每家媒體的指標(biāo)也不同,因此就不一一展開了。

    計(jì)算思路

    計(jì)算xG采用了從歷史數(shù)據(jù)中提取特征,并進(jìn)行擬合。

    過程還是機(jī)器學(xué)習(xí)老一套,確定特征、提取特征、劃分?jǐn)?shù)據(jù)集、擬合、評估。

    特征選擇

    特征選取首先要局限于事件數(shù)據(jù)能提供的范圍。這里使用了射門事件,根據(jù)Statsbomb開放數(shù)據(jù)的特點(diǎn),這里使用了如下的特征:

    守門員位置射門距離與角度射門位置射門時(shí)封堵球員的數(shù)量射門時(shí)5碼范圍內(nèi)對方干擾球員的數(shù)量進(jìn)攻類型,是定位球還是正常進(jìn)攻射門的身體部位射門的技巧,比如凌空抽射是否是第一次觸球上半場還是下半場該事件持續(xù)時(shí)間

    看起來挺多特征的,Statsbomb開放數(shù)據(jù)里面的信息挺豐富,特別是射門數(shù)據(jù),甚至還包含了射門瞬間其他球員的位置,稱為“凍結(jié)幀”。

    目標(biāo)集是進(jìn)球與否。

    擬合方法

    機(jī)器學(xué)習(xí)常用的擬合方法很多,如果特征選擇和預(yù)處理做得好,擬合方法沒那么重要,這里沒有使用最近的網(wǎng)紅算法XGBoost,而是使用了簡單的Logistic回歸。

    對于數(shù)據(jù)中的一些枚舉類型,比如射門身體部位等,簡單的采用了LabelEncoder編碼器。

    計(jì)算代碼

    我們選取開放數(shù)據(jù)中西甲2020~2021賽季巴塞羅那的比賽(有數(shù)據(jù)的一共35場)

    import pandas as pd import os from kloppy import statsbomb team = Barcelona # 這些比賽id可以寫代碼從開放數(shù)據(jù)中解析讀取 ids = [3773631, 3773665, 3773497, 3773660, 3773593, 3773466, 3773585, 3773552, 3773672, 3773386, 3773565, 3773587, 3773656, 3773377, 3773457, 3773586, 3773372, 3773387, 3773695, 3773369, 3773661, 3773597, 3773523, 3773571, 3773428, 3764661, 3773526, 3773474, 3773625, 3773403, 3773547, 3773415, 3764440, 3773689, 3773477] from kloppy.domain.models.event import EventDataset, Event # 批量加載比賽數(shù)據(jù)集的代碼,利用了kloppy的數(shù)據(jù)結(jié)構(gòu) class SbBatch: def __init__(self, base_url=/location/to/your/data/statsbomb/data/): self.base_url = base_url url = f{self.base_url}competitions.json self.comp = json.load(open(url)) def load_match_by_ids(self, ids): events = [] meta = None for id in ids: dataset = statsbomb.load( event_data=f{self.base_url}events/{id}.json, lineup_data=f{self.base_url}lineups/{id}.json, coordinates=statsbomb ) for e in dataset.records: events.append(e) # 只保留一個(gè)metadata,這里metadata只是為了構(gòu)建EventDataset # 里面的信息是不正確的 meta = dataset.metadata dataset = EventDataset(events, meta) return dataset sb = SbBatch() # 加載多場比賽的數(shù)據(jù)集。這里違反了kloppy的使用規(guī)范,dataset里的元數(shù)據(jù)metadata是錯(cuò)誤的 dataset = sb.load_match_by_ids(ids)

    接下來進(jìn)行特征提?。?/p>

    from kloppy.domain import ShotEvent # 獲取守門員位置 def gk_pos(e: ShotEvent): # 設(shè)定守門員的缺省位置 x = 120 y = 40 # 從射門事件中的凍結(jié)幀提取守門員位置 if freeze_frame in e.raw_event[shot]: for p in e.raw_event[shot][freeze_frame]: if p[teammate] == False and p[position][name] == Goalkeeper: x = p[location][0] y = p[location][1] return (x, y) # 計(jì)算射門時(shí)封堵射門路線的球員個(gè)數(shù) def blocking_opponents_count(e: ShotEvent): # 封堵射門路線的球員個(gè)數(shù)初始值為0 count = 0 x1 = e.coordinates.x y1 = e.coordinates.y # 球門位置 x2 = 120 y2 = 36 x3 = 120 y3 = 44 # 從射門事件中的凍結(jié)幀提取該時(shí)刻其他球員位置 if freeze_frame in e.raw_event[shot]: for p in e.raw_event[shot][freeze_frame]: # 如果封堵球員不是隊(duì)友且不是守門員 if p[teammate] == False and p[position][name] != Goalkeeper: # 通過判斷每個(gè)球員是否位于射門點(diǎn)、球門亮點(diǎn)構(gòu)成的三角形來判斷封堵 xp = p[location][0] yp = p[location][1] c1 = (x2-x1)*(yp-y1)-(y2-y1)*(xp-x1) c2 = (x3-x2)*(yp-y2)-(y3-y2)*(xp-x2) c3 = (x1-x3)*(yp-y3)-(y1-y3)*(xp-x3) if (c1<0 and c2<0 and c3<0) or (c1>0 and c2>0 and c3>0): count = count + 1 return count # 計(jì)算射門時(shí)5碼內(nèi)對方球員個(gè)數(shù) def nearby_opponents_count(e: ShotEvent): count = 0 x = e.coordinates.x y = e.coordinates.y # 從射門事件凍結(jié)幀中提取射門時(shí)其他球員位置 if freeze_frame in e.raw_event[shot]: for p in e.raw_event[shot][freeze_frame]: # 不是隊(duì)友也不是守門員 if p[teammate] == False and p[position][name] != Goalkeeper: xp = p[location][0] yp = p[location][1] from math import sqrt distance = sqrt((x-xp)*(x-xp) + (y-yp)*(y-yp)) if distance <= 5.: count = count + 1 return count # kloppy直接提供了射門距離與角度的計(jì)算 from kloppy.domain.services.transformers.attribute import ( AngleToGoalTransformer, DistanceToGoalTransformer ) df = dataset.filter(shot).filter( # 留下本隊(duì)的射門事件 lambda e: e.team.name==team ).to_df( # 將dataset轉(zhuǎn)換成DataFrame # 或保留或添加如下一些列 period_id, # 上下半場 event_id, team, player, timestamp, coordinates*, # 射門位置 lambda e: {duration: e.raw_event[duration]}, # 射門持續(xù)時(shí)間 lambda e: {statsbomb_xg: e.raw_event[shot][statsbomb_xg]}, # 讀取已計(jì)算的xG,最后可以拿來對照 body_part_type, # 射門身體部位 lambda e: {result: 1. if e.result.is_success else 0.}, # 射門是否得分 lambda e: {play_pattern: e.raw_event[play_pattern][name]}, # 進(jìn)攻類型 lambda e: {technique: e.raw_event[shot][technique][name]}, # 射門技巧 lambda e: {first_time: 1 if first_time in e.raw_event[shot] else 0}, # 是否第一次觸球 lambda e: {goalkeeper_x: gk_pos(e)[0]}, # 守門員x坐標(biāo) lambda e: {goalkeeper_y: gk_pos(e)[1]}, # 守門員y坐標(biāo) lambda e: {blocking_opponents_count: blocking_opponents_count(e)}, # 封堵球員數(shù)量 lambda e: {nearby_opponents_count: nearby_opponents_count(e)}, # 附加干擾球員數(shù)量 AngleToGoalTransformer(), # 射門角度 DistanceToGoalTransformer() # 射門距離 )

    一些以字符串為字面量的枚舉類型無法直接參與計(jì)算,需要映射為數(shù)字。這里采用了LabelEncoder對特征進(jìn)行編碼:

    from sklearn.preprocessing import LabelEncoder, OneHotEncoder body_part_type_encoder = LabelEncoder() player_pattern_encoder = LabelEncoder() technique_encoder = LabelEncoder() df[body_part_type]=body_part_type_encoder.fit_transform(df[body_part_type]) df[play_pattern]=player_pattern_encoder.fit_transform(df[play_pattern]) df[technique]=technique_encoder.fit_transform(df[technique])

    劃分?jǐn)?shù)據(jù)集:

    # 提取特征集 features = df.drop([result, event_id, team, player, timestamp, statsbomb_xg], axis=1) # 提取目標(biāo)集 targets = df[result] # 劃分為訓(xùn)練集與測試集 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(features, targets, test_size=0.2)

    接下來進(jìn)行擬合與預(yù)測

    from sklearn.linear_model import LogisticRegression # 迭代次數(shù)要多一些 log_reg = LogisticRegression(max_iter=10000, random_state=16) log_reg.fit(X_train, y_train) y_pred = logreg.predict_proba(X_test)

    與statsbomb數(shù)據(jù)中自帶的xG數(shù)據(jù)進(jìn)行比較

    xg = df[statsbomb_xg].to_list() for i in range(len(y_pred)): print(y_pred[i][1], xg[i], df[result].to_list()[i])

    得到結(jié)果如下:

    0.0877706743634692 0.08335477 0.0 0.12022498029802782 0.26389658 0.0 0.012459886396227053 0.06492457 0.0 0.04354703879653737 0.04293651 0.0 0.28178765172568637 0.02796916 0.0 0.6173757373601387 0.10423171 0.0 0.07648849141874221 0.028864022 0.0 0.12202760914351773 0.032932542 1.0 0.43569816910546594 0.183775 0.0 0.006054658046803704 0.16166444 0.0 0.07658743195139443 0.07484645 0.0 0.05125376103583803 0.056819215 1.0 0.25866250118166645 0.08732408 0.0 0.06128259188512852 0.04334966 0.0 0.13674399079749752 0.21101888 1.0 0.05742722800738721 0.020735633 0.0 0.5415984823277031 0.04135918 0.0 0.16510526445894433 0.026723294 0.0 0.1842802037847451 0.040642418 0.0 0.0903545841750892 0.04152512 0.0 0.32958785239392163 0.2157016 0.0 0.43364589918370233 0.027891573 0.0 0.21267786284722404 0.18859574 0.0 0.048520974438812065 0.119817905 0.0 0.30197973079119633 0.1121366 1.0 ... 0.05945067768078112 0.45795894 0.0 0.5202560635419263 0.037930463 0.0 0.03916706575065915 0.43497095 1.0 0.04148460332780444 0.10470807 0.0

    第一列為算法計(jì)算出來的xG,第二列是Statsbomb數(shù)據(jù)自帶的xG,第三列是進(jìn)球與否。

    不清楚Statsbomb的xG算法,但應(yīng)該是類似思路,手頭也沒有Statsbomb那么豐富的數(shù)據(jù),因此結(jié)果有差異。

    以上

    掃描二維碼推送至手機(jī)訪問。

    版權(quán)聲明:本文由財(cái)神資訊-領(lǐng)先的體育資訊互動媒體轉(zhuǎn)載發(fā)布,如需刪除請聯(lián)系。

    本文鏈接:http://www.daniuzhishi.com/?id=46264

    “Soccermatics之三: 足球數(shù)據(jù)集計(jì)算預(yù)期進(jìn)球xG(Expected Goal)” 的相關(guān)文章

    競彩足球怎么賺錢?

    2018年世界杯期間很多人買競彩破產(chǎn)。這次世界杯也肯定會有很多人買彩票,買競彩前好好考慮自己經(jīng)濟(jì)能力再買。不要刷信用卡,借網(wǎng)貸買彩票,一旦輸了那就很長時(shí)間還債。 買競彩不要買外圍,各種網(wǎng)絡(luò)賭博軟件。網(wǎng)絡(luò)賭博是我國屬于違法行為,很多平臺贏錢,提現(xiàn)不了的情況...

    球迷進(jìn)入“競彩時(shí)間”

    球迷進(jìn)入“競彩時(shí)間”

    本周末,全球體壇相繼進(jìn)入“競彩時(shí)間”,歐冠、歐羅巴將分別迎來最終決戰(zhàn),法甲新賽季也將火熱開啟,NBA季后賽首輪同步繼續(xù)進(jìn)行。據(jù)了解,競彩將全面開售以上賽事。這個(gè)周末,競彩陪你一起嗨! 歐冠:法甲、德甲班霸直接對話 北京時(shí)間8月24日凌晨3點(diǎn),法甲冠軍巴黎圣日耳曼和德甲冠軍拜...

    競彩冠軍、冠亞軍競猜今日開售

    世界杯倒計(jì)時(shí)100天 新快報(bào)訊 記者陸妍思 通訊員謝明明報(bào)道 告別了2月的冬奧冰雪盛宴,3月體壇馬上進(jìn)入世界杯的節(jié)奏。今天,2018俄羅斯世界杯迎來了“倒計(jì)時(shí)100天”,為了讓廣大球迷和購彩者提前上場感受世界杯的熱烈氛圍,中國體育彩票競彩游戲于即日起開售本屆世界杯賽的冠軍競猜、冠...

    今日足球競彩推薦 足球賽事分析 比分預(yù)測參考,切爾西VS沃特福德

    今日足球競彩推薦 足球賽事分析 比分預(yù)測參考,切爾西VS沃特福德

    周日003英超:切爾西VS沃特福德 切爾西目前球隊(duì)在英超37輪賽事取得20勝11平6負(fù),目前以總積分71分排在本賽事積分榜第3,球隊(duì)目前在本賽事共踢進(jìn)了74球,場均進(jìn)球數(shù)為2.0球,進(jìn)攻能力火力全開,共丟掉了32球,場均丟球數(shù)為0.9球,防守強(qiáng)度仍需提升。上輪英超賽事主場迎戰(zhàn)萊斯特...

    國際足球場與普通足球場的區(qū)別及標(biāo)準(zhǔn)尺寸規(guī)格!

    國際足球場與普通足球場的區(qū)別及標(biāo)準(zhǔn)尺寸規(guī)格!

      足球場整體是矩形的。長的兩邊是稱為邊線。另外兩邊側(cè)面被稱為球門線。兩個(gè)球門線必須50至100碼,并具有相同的長度。兩個(gè)邊線也必須具有相同的長度,以及在100至130碼的長度之間。所有線條必須是等寬的,不超過12厘米。   國際足球場的標(biāo)準(zhǔn)規(guī)格尺寸是由國際足協(xié)制定。對于...

    競彩周六 英超:斯旺西 VS 切爾西

    球探情報(bào)分析:英超第33輪,藍(lán)軍切爾西客場挑戰(zhàn)斯旺西。切爾西上輪客場4-0橫掃阿斯頓維拉,主教練希丁克依舊保持著上任以來聯(lián)賽不敗的戰(zhàn)績,近14場比賽球隊(duì)收獲6勝8平的優(yōu)異成績,主教練應(yīng)記一功。球隊(duì)上輪派遣諸多新力軍上陣,反而受到奇效,帕托、奇克、肯尼迪、佩德羅組成新的攻擊組合大放異彩,實(shí)在...

    ?