python案例如何解读后防线的xG against?

wen python案例 4

本文目录导读:

python案例如何解读后防线的xG against?

  1. 第一步:构建/模拟数据
  2. 第二步:核心计算(按比赛聚合xGA)
  3. 第三步:业务解读(关键指标计算)
  4. 第四步:可视化解读(让数据说话)
  5. 第五步:高级解读——如何“读懂”这个数字?
  6. 最终输出:一个自动化报告函数(实战必备)
  7. 核心思维导图

在足球数据分析中,解读后防线的 xG Against (xGA) 是一个核心技能,它衡量的是对手在面对该球队时,创造出的射门机会的预期进球总值

xGA 越高,说明对手获得的绝佳机会越多,该队后防线承受的压力越大(或防守质量越差);xGA 越低,说明后防线限制对手的能力越强。

下面我通过一个Python实战案例,从数据清洗、计算、可视化和业务解读四个维度来拆解。


第一步:构建/模拟数据

假设我们有某支球队(曼城”)在5场比赛中的对手射门数据,每条数据代表一次射门。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 模拟数据:5场比赛,对手的射门记录
np.random.seed(42)
data = {
    'match_id': [1,1,1,1, 2,2,2, 3,3,3,3,3, 4,4, 5,5,5,5,5,5],
    'shot_x': np.random.uniform(75, 100, 20).round(1),  # 射门位置的X坐标(进攻方向100为底线)
    'shot_y': np.random.uniform(20, 80, 20).round(1),   # 射门位置的Y坐标
    'body_part': np.random.choice(['head', 'left_foot', 'right_foot'], 20),
    'situation': np.random.choice(['open_play', 'corner', 'free_kick', 'penalty'], 20),
    'xg': np.random.uniform(0.01, 0.8, 20).round(3)
}
df_shots = pd.DataFrame(data)
print(df_shots.head(5))

第二步:核心计算(按比赛聚合xGA)

计算每场比赛的 xGA(对手xG总和),并加入比赛结果辅助解读。

# 按比赛聚合xGA
xga_per_match = df_shots.groupby('match_id').agg(
    xga=('xg', 'sum'),
    shots_against=('xg', 'count')  # 射门次数
).reset_index()
# 模拟比赛结果(0=平/负,1=胜)
xga_per_match['result'] = [1, 0, 1, 1, 0]  # 随便编的
print(xga_per_match)

输出示例:

match_id xga shots_against result
1 245 4 1
2 102 3 0
3 523 5 1

第三步:业务解读(关键指标计算)

这一部分是最重要的,用来做深度分析:

平均每场xGA(防守强度)

avg_xga = xga_per_match['xga'].mean()
print(f"平均每场xGA: {avg_xga:.3f}")

战胜强队 vs 战败弱队(看防守是否“看人下菜”)

# 强强对话(对手强) vs 弱队(对手弱)
# 假设 match_id=1,3 是对付强队,其余是弱队
xga_per_match['opponent_strength'] = ['strong', 'weak', 'strong', 'weak', 'weak']
# 分组计算
grouped_xga = xga_per_match.groupby('opponent_strength')['xga'].agg(['mean', 'std'])
print(grouped_xga)

射门分布特征(防守风险点)

分析对手射门的位置分布,看看后防线是否经常被对手打 “致命区域”(如小禁区/Six-yard box)。

# 添加“射门位置质量”标签
df_shots['zone'] = pd.cut(df_shots['shot_x'], bins=[0, 80, 90, 100],
                          labels=['远距离', '禁区外-禁区边缘', '禁区内'])
zone_analysis = df_shots.groupby('zone', observed=True).agg(
    total_xg=('xg', 'sum'),
    avg_xg=('xg', 'mean'),
    shot_count=('xg', 'count')
).round(3)
print(zone_analysis)

第四步:可视化解读(让数据说话)

用图表分析xGA的时间分布或对手射门热力图。

# 画每场比赛的xGA柱状图,并用颜色标注胜负
plt.figure(figsize=(10,5))
colors = ['green' if r == 1 else 'red' for r in xga_per_match['result']]
plt.bar(xga_per_match['match_id'], xga_per_match['xga'], color=colors, alpha=0.7)
plt.axhline(y=avg_xga, color='black', linestyle='--', label=f'Avg xGA: {avg_xga:.2f}')
plt.xlabel('Match ID')
plt.ylabel('xG Against')'Expected Goals Against (xGA) per Match')
plt.legend()
plt.show()

第五步:高级解读——如何“读懂”这个数字?

下面是一个决策树式的解读逻辑,你可以直接用这套逻辑来输出分析结论:

场景A:如果某一轮比赛 xGA 极高(> 2.5)

  • 后防线被打穿了。
  • 深挖:查看 df_shots 中是否有大量 shot_x > 90(小禁区)的射门?如果是,说明中后卫盯人不紧,禁区前沿缺少保护;如果多为远射(shot_x < 85),说明是“放远射防传球”的策略,xG虚高但实际威胁一般,属于“战术性放投”。

场景B:xGA 低,但输了比赛

  • 进攻端的问题更大(预期进球高但没进),防守没问题。
  • 深挖:查看本队进球数和xG对比,别错怪后卫线。

场景C:xGA 稳定在 0.8-1.2(优秀区间)

  • 后防线是“体系防”而非“个人能力防”。
  • 深挖:查看对手射门多发生在禁区外(shot_x < 85),说明高位防线策略有效,把对手压制在远离球门区域。

最终输出:一个自动化报告函数(实战必备)

你可以写一个函数,一键生成报告:

def defensive_report(df_shots):
    report = {}
    # 计算xGA
    report['Total_xGA'] = df_shots['xg'].sum()
    report['Avg_xGA_Per_Game'] = df_shots['xg'].sum() / df_shots['match_id'].nunique()
    report['High_Chance_Allowed'] = df_shots[df_shots['xg'] > 0.35]['xg'].count()
    report['Penalty_Conceded'] = df_shots[df_shots['situation'] == 'penalty'].shape[0]
    # 解读文本
    if report['Avg_xGA_Per_Game'] < 1.0:
        report['Verdict'] = "防线稳固,限制对手创造高质量机会。"
    elif report['Avg_xGA_Per_Game'] < 1.8:
        report['Verdict'] = "防线中等,有一定漏洞,但整体可控。"
    else:
        report['Verdict'] = "防线告急!对手每场都能拿到明显得分机会。"
    return report
# 使用
report = defensive_report(df_shots)
print(report)

核心思维导图

  • xGA ≠ 丢球数(没有考虑门将扑救和运气,它是“防线+门将”前的防守质量)
  • 低xGA + 高丢球 = 门将状态差(不是防线问题)
  • 高xGA + 低丢球 = 门将神勇,但防线隐患巨大,迟早崩盘
  • 高xGA + 高丢球 = 后防线彻底崩盘,需要立即调整

Python的作用:自动化聚类(如识别对手射门密集区)、时序分析(xGA随比赛走势的变化)、以及将多维数据(位置、角度、射门距离)压缩成单一的战术评分。

你可以带着这份理解,去加载真实的StatsBomb或Understat数据集(通常有xG字段),跑一遍上面的代码,就能对某支球队的后防线水平有直观、量化的认识了,需要我提供真实数据集的获取方式或更复杂的模型(如射门坐标系热力图)吗?

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