python案例如何结合xGA评估防守表现?

wen python案例 2

本文目录导读:

python案例如何结合xGA评估防守表现?

  1. 案例1:球队整体防守效率(xGA vs 实际失球)
  2. 案例2:射门质量分析(因何失球?)
  3. 案例3:球员/防线个体贡献(防守拦截与限制xGA)
  4. 案例4:球队防守热力图(结合射门坐标)
  5. 案例5:进阶 - 基于xGA的防守策略优化(使用机器学习解释)
  6. 总结:如何优雅地将xGA用于防守评估?

在Python中结合xGA(Expected Goals Against,预期失球)评估防守表现,核心思路是将实际失球数与预期失球数对比,并分析防守行为,xGA通常由射门质量、位置、角度、助攻类型等模型预测得出。

以下是几种常见的结合xGA评估防守的Python实战案例,从简单到进阶:


案例1:球队整体防守效率(xGA vs 实际失球)

场景:你有一支球队整个赛季每场比赛的数据(射门次数、射正、xGA、实际失球)。 目标:判断球队防守是“被高估”还是“被低估”(运气好/差)。

import pandas as pd
import matplotlib.pyplot as plt
# 假设数据
data = {
    'match': ['vsA', 'vsB', 'vsC'],
    'opp_shots': [10, 15, 12],        # 对手射门
    'opp_xG': [1.2, 2.1, 0.8],        # 对手预期进球(=球队的xGA)
    'goals_conceded': [0, 2, 1]        # 实际失球
}
df = pd.DataFrame(data)
# 1. 计算累计xGA和实际失球
cum_xga = df['opp_xG'].cumsum()
cum_goals = df['goals_conceded'].cumsum()
# 2. 绘制对比图
plt.figure(figsize=(10, 6))
plt.plot(df['match'], cum_xga, label='累计xGA', marker='o')
plt.plot(df['match'], cum_goals, label='累计实际失球', marker='s')'球队防守:预期失球 vs 实际失球')
plt.ylabel('累计失球数')
plt.legend()
plt.grid(True)
plt.show()
# 3. 防守效率指标:xGA - 实际失球(正值 = 防守超预期)
df['defensive_overperformance'] = df['opp_xG'] - df['goals_conceded']
print("单场防守超预期值(正=防守好,负=防守差):")
print(df[['match', 'opp_xG', 'goals_conceded', 'defensive_overperformance']])

案例2:射门质量分析(因何失球?)

场景:你有对手每次射门的详细事件数据(坐标、部位、助攻是否跨场)。 目标:识别防守薄弱点(如:禁区外远射太多?或边路传中让对手获得了高质量头球?)。

import pandas as pd
# 示例射门数据(列:对手球员、射门xG、射门位置、助攻类型)
shot_data = pd.DataFrame({
    'opp_shot_id': range(1, 6),
    'xG': [0.05, 0.3, 0.02, 0.8, 0.1],
    'location': ['outside_box', 'inside_box_center', 'outside_box', 'inside_box_center', 'edge_box'],
    'assist_type': ['throughball', 'cross', 'setpiece', 'cutback', 'longball']
})
# 1. 按射门位置聚合xGA占比
position_xGA = shot_data.groupby('location')['xG'].sum().sort_values(ascending=False)
print("不同防守区域被对手创造的xGA分布:")
print(position_xGA)
# 2. 按助攻类型聚合(看看防守是否被传中打穿)
assist_xGA = shot_data.groupby('assist_type')['xG'].sum().sort_values(ascending=False)
print("\n不同进攻方式造成的xGA:")
print(assist_xGA)
# 3. 重点:找出xG极高(黄金机会)的防守瞬间
high_quality_chances = shot_data[shot_data['xG'] > 0.35]
print("\n防守端漏掉的黄金机会数:", len(high_quality_chances))

案例3:球员/防线个体贡献(防守拦截与限制xGA)

场景:你有球队每名防守球员的防守动作数据(抢断、拦截、解围、阻挡)。 目标:评估后卫是否有效“减少了对手的xGA”,这通常需要因果推断,但可以用近似指标。

import pandas as pd
# 此案例引入“防守动作质量”概念:防守动作发生后的5秒内对手射门xG变化。
# 假设你已有防守动作数据(action_id)
defensive_actions = pd.DataFrame({
    'player': ['player_A', 'player_B', 'player_C'],
    'interceptions': [35, 41, 20],
    'tackles_won': [12, 18, 5],
    'blocks': [10, 15, 2],           # 封堵射门
    'clearances': [20, 25, 30]
})
# 核心指标:每90分钟防守动作创造的防守价值(防止了xG)
# 假设封堵一次射门平均可以降低0.85 xGA的影响
defensive_actions['estimated_xGA_prevented'] = (
    defensive_actions['blocks'] * 0.85 +      # 封堵射门价值最大
    defensive_actions['interceptions'] * 0.15 +
    defensive_actions['tackles_won'] * 0.1
)
print(defensive_actions[['player', 'estimated_xGA_prevented']].sort_values(by='estimated_xGA_prevented', ascending=False))

案例4:球队防守热力图(结合射门坐标)

场景:拥有射门的精确坐标,以及球队防守阵型,用散点图可视化对手在哪里获得了高质量射门。

import matplotlib.pyplot as plt
import numpy as np
# 模拟对手射门坐标(x, y,单位为球场长度100,宽度50)
np.random.seed(42)
n_shots = 50
x_coords = np.random.uniform(30, 100, n_shots)  # 大多数在进攻三区
y_coords = np.random.uniform(10, 40, n_shots)   # 中间区域
shot_xg = np.random.uniform(0.02, 0.6, n_shots) # 随机xG
# 绘制球场(简化为矩形)
plt.figure(figsize=(12, 8))
plt.xlim(0, 100)
plt.ylim(0, 50)
plt.scatter(x_coords, y_coords, c=shot_xg, cmap='YlOrRd', s=100, alpha=0.7)
plt.colorbar(label='xGA (对手进球概率)')
# 高亮黄金机会
high_xg = shot_xg > 0.25
plt.scatter(x_coords[high_xg], y_coords[high_xg], facecolors='none', 
            edgecolors='black', s=200, label='高风险射门')
'对手射门质量分布图(防守端需关注区域)')
plt.xlabel('球场X轴(本方球门在右侧)')
plt.ylabel('球场Y轴')
plt.legend()
plt.show()

案例5:进阶 - 基于xGA的防守策略优化(使用机器学习解释)

如果你有大量比赛数据,可以尝试训练模型预测“射门是否变为进球”,然后用模型结果对比防守风格。

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
# 假设数据:每次射门特征(距离、角度、射门部位、是否反击),标签(是否进球)
X = pd.DataFrame({
    'distance_goal': [25, 15, 10, 18, 8],
    'angle': [30, 20, 40, 15, 5],
    'is_heading': [0, 0, 1, 0, 1],
    'is_counter': [1, 0, 0, 1, 0]
})
y = [0, 1, 0, 1, 0]  # 0=未进球,1=进球
model = RandomForestClassifier()
model.fit(X, y)
# 得到每个玩家特征的重要性(哪些防守漏洞更容易导致丢球?)
feature_importance = model.feature_importances_
print("特征重要性(距离、角度、头球、反击):", feature_importance)
# 如果“距离”重要性很高,说明防守经常被远射威胁,需加强禁区前沿逼抢。

如何优雅地将xGA用于防守评估?

维度 分析思路
结果层面 累计xGA vs 实际失球,计算“防守超预期值”(类似门将的PSxG差值)
过程层面 分析对手射门位置的xGA聚合,找出薄弱区域
人员层面 结合防守动作(封堵、拦截)估算“防守者阻止了多少xGA”
策略层面 可视化 + 特征重要性,找到防守战术盲点

最佳实践:不要只看xGA本身,要对比球队的防守风格(高压逼抢/低位防守)、门将扑救质量(PSxG)以及对手射门质量分布,才能全面评估防守表现,如果你的数据和StatsBomb或Opta格式一致,可以引入statsbombpy库获取更专业的开放数据。

抱歉,评论功能暂时关闭!