根据实时python案例,射门质量如何评估?

wen python案例 3

射门质量评估的 Python 实战案例

在足球数据分析中,射门质量(Shot Quality) 通常用 xG(Expected Goals,预期进球) 来衡量,下面结合实时 Python 案例,讲解如何评估射门质量。

根据实时python案例,射门质量如何评估?


核心概念

射门质量 ≠ 进球数,而是综合以下维度:

维度 说明
射门距离 离球门越近,质量越高
射门角度 正对球门角度大,质量高
身体部位 脚 > 头 > 其他
进攻类型 反击/定位球/点球
防守压力 防守球员距离
门将位置 是否已出击

实时数据获取(以 StatsBomb 免费数据为例)

# pip install statsbombpy pandas numpy matplotlib
from statsbombpy import sb
import pandas as pd
import numpy as np
# 获取某场比赛的射门事件(示例:2022世界杯决赛)
events = sb.events(match_id=3869685)
shots = events[events['type'] == 'Shot'].copy()
# 提取关键字段
shots = shots[[
    'player', 'team', 'minute',
    'location', 'shot_statsbomb_xg',
    'shot_body_part', 'shot_technique', 'shot_outcome'
]]
print(shots.head())

自建 xG 模型(逻辑回归实战)

StatsBomb 已给 xG,但我们也可以自己训练一个,用于理解评估逻辑。

特征工程

def calc_distance_angle(loc):
    """计算射门距离和角度"""
    x, y = loc[0], loc[1]
    goal_x, goal_y = 120, 40   # 球门中心(StatsBomb坐标120x80)
    post1, post2 = (120, 36), (120, 44)  # 两个门柱
    # 距离
    dist = np.sqrt((x - goal_x)**2 + (y - goal_y)**2)
    # 角度:射门点对两门柱的张角
    a = np.array([x, y])
    b1 = np.array(post1) - a
    b2 = np.array(post2) - a
    cos_angle = np.dot(b1, b2) / (np.linalg.norm(b1) * np.linalg.norm(b2))
    angle = np.arccos(np.clip(cos_angle, -1, 1))
    return dist, np.degrees(angle)
# 构造特征
shots[['distance', 'angle']] = shots['location'].apply(
    lambda loc: pd.Series(calc_distance_angle(loc))
)
shots['is_header'] = (shots['shot_body_part'] == 'Head').astype(int)
shots['is_goal'] = (shots['shot_outcome'] == 'Goal').astype(int)
print(shots[['distance', 'angle', 'is_header', 'is_goal']].describe())

训练逻辑回归模型

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
features = ['distance', 'angle', 'is_header']
X = shots[features]
y = shots['is_goal']
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)
model = LogisticRegression()
model.fit(X_train, y_train)
# 评估
proba = model.predict_proba(X_test)[:, 1]
print(f"AUC: {roc_auc_score(y_test, proba):.3f}")
print(f"系数: {dict(zip(features, model.coef_[0]))}")

射门质量可视化(实时热力图)

import matplotlib.pyplot as plt
from matplotlib.patches import Arc
def plot_shot_map(shots, title="射门质量分布"):
    fig, ax = plt.subplots(figsize=(12, 8))
    # 画球场
    ax.set_xlim(60, 120)   # 只看进攻半场
    ax.set_ylim(0, 80)
    ax.set_facecolor('#1a5c2a')
    # 球门
    ax.plot([120, 120], [36, 44], 'w-', linewidth=3)
    # 射门点:大小=质量,颜色=是否进球
    for _, s in shots.iterrows():
        x, y = s['location']
        quality = s['shot_statsbomb_xg']
        color = 'red' if s['is_goal'] else 'yellow'
        ax.scatter(x, y, s=quality*3000+20, c=color,
                   alpha=0.6, edgecolors='white')
    ax.set_title(title, fontsize=14)
    plt.tight_layout()
    plt.show()
plot_shot_map(shots)

实时评估:单次射门打分函数

def evaluate_shot_quality(x, y, body_part='Foot', 
                          under_pressure=False,
                          is_counter=False,
                          is_set_piece=False):
    """
    返回 0-1 的射门质量分(近似 xG)
    """
    dist, angle = calc_distance_angle([x, y])
    # 基础分:距离衰减 + 角度加成
    base = np.exp(-0.1 * dist) * (angle / 90)
    # 修正项
    if body_part == 'Head':
        base *= 0.7
    if under_pressure:
        base *= 0.75
    if is_counter:
        base *= 1.3
    if is_set_piece:
        base *= 0.9
    return round(float(np.clip(base, 0, 1)), 3)
# 实时调用示例
score = evaluate_shot_quality(108, 40, body_part='Foot')
print(f"该次射门质量分: {score}")   # 0.42

进阶:实时数据流 + 模型推理

如果要实时(比赛进行中)评估,可以这样组织:

import joblib
# 保存训练好的模型
joblib.dump(model, 'xg_model.pkl')
class RealtimeShotEvaluator:
    def __init__(self, model_path='xg_model.pkl'):
        self.model = joblib.load(model_path)
    def on_new_shot(self, event: dict):
        """接收实时事件,输出 xG"""
        dist, angle = calc_distance_angle(event['location'])
        features = pd.DataFrame([{
            'distance': dist,
            'angle': angle,
            'is_header': int(event.get('body_part') == 'Head')
        }])
        xg = self.model.predict_proba(features)[0, 1]
        # 分档
        if xg > 0.5:   level = "绝佳机会"
        elif xg > 0.2: level = "好机会"
        elif xg > 0.05:level = "一般机会"
        else:          level = "低质量远射"
        return {
            'player': event.get('player'),
            'xg': round(xg, 3),
            'level': level,
            'distance': round(dist, 1),
            'angle': round(angle, 1)
        }
# 模拟实时事件
evaluator = RealtimeShotEvaluator()
result = evaluator.on_new_shot({
    'player': 'Messi',
    'location': [112, 38],
    'body_part': 'Foot'
})
print(result)
# {'player': 'Messi', 'xg': 0.371, 'level': '好机会', 
#  'distance': 8.2, 'angle': 42.5}

评估射门质量的常用指标总结

指标 用途
xG (每射门) 单次射门质量
npxG 排除点球,评估运动战质量
xGOT 射正后的进球概率(含门将因素)
PSxG 门将面对射门的扑救难度
Shot Quality Total 球队/球员整场射门质量总和

推荐实时数据源

  • StatsBomb Open Data(免费历史数据)
  • FBref(免费 xG 数据)
  • Opta / Stats Perform(商业实时 API)
  • API-Football(有实时事件但无 xG)
  • SofaScore 爬虫(需谨慎合规)

一句话总结:射门质量 = 用 距离 + 角度 + 部位 + 情境 做特征,训练逻辑回归/梯度提升模型预测进球概率(xG),再封装成实时推理类即可在线评估每次射门。

需要我针对某个具体联赛(如英超/中超)或某类数据源(如追踪数据)展开更深入的案例吗?

上一篇综合python案例,老将经验价值如何衡量?

下一篇当前分类已是最新一篇

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