实用脚本如何量化进攻三区效率值?

wen 实用脚本 3

本文目录导读:

实用脚本如何量化进攻三区效率值?

  1. 效率值定义框架
  2. 数据源准备
  3. 核心脚本
  4. 进阶版本:加入情境修正
  5. 可视化输出
  6. 实战注意事项
  7. 可直接用的最小 MVP

在足球数据分析中,进攻三区通常指距离对方底线约1/3的场地区域,也就是前场35米左右的范围,量化进攻三区效率值,核心思路是:衡量球队/球员进入该区域后,转化为实质性威胁的能力

下面是一套可直接落地的实用脚本设计框架。


效率值定义框架

核心公式

进攻三区效率值 = (加权威胁产出 / 进攻三区触球或进入次数) × 标准化系数

分层指标

层级 指标 权重建议
产出层 进球、助攻、射门、关键传球、xG、xA
过程层 传入禁区、成功过人、推进传球
基础层 进攻三区触球数、进入次数 分母

数据源准备

# 常用数据源
# - StatsBomb Open Data (免费, 事件级)
# - Opta / Stats Perform (付费)
# - FBref (免费, 聚合数据)
# - Wyscout (付费)
# - 自建: 视频追踪 + 标注
import pandas as pd
import numpy as np
# 假设事件数据格式(StatsBomb风格)
# columns: match_id, player, team, event_type, x, y, end_x, end_y, outcome

核心脚本

判定进攻三区

def is_final_third(x, pitch_length=105):
    """x为沿进攻方向的坐标(0=己方底线, 105=对方底线)"""
    return x >= pitch_length * 2 / 3  # 前1/3
def is_penalty_area(x, y, pitch_length=105, pitch_width=68):
    """对方禁区: x>=88.5, 13.84<=y<=54.16"""
    return x >= 88.5 and 13.84 <= y <= 54.16

计算单次进攻三区行为的威胁权重

def action_threat_weight(row):
    """给每次进攻三区行为赋威胁权重"""
    w = 0
    if row['event_type'] == 'Shot':
        w += 0.3 + 0.7 * row.get('xg', 0)      # 射门
    if row['event_type'] == 'Pass':
        if row.get('is_key_pass'):
            w += 0.5
        if row.get('end_in_box'):
            w += 0.3
        if row.get('is_assist'):
            w += 0.8
    if row['event_type'] == 'Carry':
        w += 0.1 * row.get('progression', 1)
    if row['event_type'] == 'Dribble' and row.get('success'):
        w += 0.2
    return w

主计算函数

def final_third_efficiency(events_df, entity='team', min_actions=20):
    """
    计算进攻三区效率值
    entity: 'team' 或 'player'
    """
    df = events_df.copy()
    df = df[df.apply(lambda r: is_final_third(r['x']), axis=1)]
    df['threat'] = df.apply(action_threat_weight, axis=1)
    # 分子: 加权威胁总和
    agg = df.groupby(entity).agg(
        threat_sum=('threat', 'sum'),
        actions=('threat', 'count'),
        shots=('event_type', lambda s: (s=='Shot').sum()),
        goals=('is_goal', 'sum'),
        xg=('xg', 'sum') if 'xg' in df else ('threat', 'size')
    ).reset_index()
    # 效率值 = 每次进攻三区行为的平均威胁产出
    agg['ft_efficiency'] = agg['threat_sum'] / agg['actions']
    # 标准化到 0-100 (相对同位置/同联赛)
    agg['ft_efficiency_norm'] = (
        (agg['ft_efficiency'] - agg['ft_efficiency'].min()) /
        (agg['ft_efficiency'].max() - agg['ft_efficiency'].min()) * 100
    )
    # 过滤样本不足
    agg = agg[agg['actions'] >= min_actions]
    return agg.sort_values('ft_efficiency', ascending=False)

调用示例

# 读取事件数据
events = pd.read_csv('events.csv')
# 按球队计算
team_eff = final_third_efficiency(events, entity='team')
# 按球员计算
player_eff = final_third_efficiency(events, entity='player', min_actions=30)
print(team_eff[['team', 'ft_efficiency', 'ft_efficiency_norm', 'goals', 'xg']])

进阶版本:加入情境修正

对手强度修正

def adjust_by_opponent(df, opp_strength):
    """opp_strength: dict {对手: 0-1 强度}"""
    df['opp_factor'] = df['opponent'].map(opp_strength).fillna(0.5)
    df['adjusted_threat'] = df['threat'] * (1 + df['opp_factor'])
    return df

比分情境修正

def adjust_by_scoreline(df):
    """落后时进攻三区行为含金量更高"""
    weight = { 'leading': 0.9, 'drawing': 1.0, 'trailing': 1.2 }
    df['score_factor'] = df['score_state'].map(weight)
    df['adjusted_threat'] = df['threat'] * df['score_factor']
    return df

最终效率值

FTE = (Σ 加权威胁 × 对手系数 × 比分系数) / 进攻三区进入次数 × 100

可视化输出

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
ax.barh(team_eff['team'], team_eff['ft_efficiency_norm'])
ax.set_xlabel('进攻三区效率值 (标准化)')
ax.set_title('各队进攻三区效率对比')
plt.tight_layout()
plt.savefig('ft_efficiency.png', dpi=150)

实战注意事项

  1. 分母选择:用“进攻三区触球数”比“进入次数”更稳定,避免单次长传造成的噪声。
  2. 样本量:球员至少 30 次进攻三区行为,球队至少 5 场比赛。
  3. 位置归一:边锋和中锋的效率基准不同,建议分位置标准化。
  4. xG/xA 优先:有 xG 数据时,用 xG 替代进球数,抗运气干扰。
  5. 防守强度:可引入 PPDA(对手每次防守动作传球数)作为对手强度代理。

可直接用的最小 MVP

如果你只有基础数据(传球、射门位置),最小可行版本:

def mvp_fte(df):
    ft = df[df['x'] >= 70]  # 进攻三区
    return ft.groupby('team').apply(
        lambda g: (g['shots'].sum() * 1 + g['key_passes'].sum() * 0.5) / len(g)
    ).sort_values(ascending=False)

需要我根据你手上的具体数据格式(StatsBomb JSON、Opta CSV、或自建表结构)写一版完整可跑的脚本吗?告诉我字段名即可。

上一篇实用脚本复盘提到的最大收获是什么?

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

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