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

wen 实用脚本 2

本文目录导读:

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

  1. 先定义指标框架
  2. 数据来源与字段要求
  3. 核心脚本
  4. 进阶:加入控球时长与对手强度
  5. 可视化输出
  6. 指标解读注意事项

在足球数据分析中,进攻三区通常指距对方球门35米或30米以内的区域,也就是前场进攻区域,量化进攻三区效率值,核心目标是回答一个问题:球队/球员把球推进到进攻三区后,究竟制造了多少实质威胁?

下面是一套可以直接落地的脚本化计算框架。


先定义指标框架

效率值 = 产出 / 投入,建议拆成三层:

层级 投入指标 产出指标
推进 进入三区次数
制造 三区内传球数、触球数 禁区内传球、关键传球
终结 三区内控球时长 射门、xG、进球

核心效率公式:

三区效率值 = (射门数 × 0.4 + xG × 0.4 + 进球 × 0.2) / 进入三区次数 × 100

权重可按联赛数据回归校准,这里给的是通用起点。


数据来源与字段要求

需要的事件数据(StatsBomb / Opta / Wyscout 格式均可):

# 每条事件至少包含
{
  "match_id": ,
  "team": ,
  "player": ,
  "event_type": "pass|carry|shot|touch",
  "x": ,          # 球场坐标 0-100 或 0-120
  "y": ,
  "end_x": ,
  "end_y": ,
  "xg": ,         # 仅射门有
  "outcome": 
}

核心脚本

import pandas as pd
import numpy as np
# ---------- 1. 定义进攻三区 ----------
PITCH_LENGTH = 105  # 米
THIRD_ZONE_X = PITCH_LENGTH * (2/3)  # 70米处,即对方三区起点
def in_final_third(x):
    return x >= THIRD_ZONE_X
def in_box(x, y):
    # 标准禁区内:距底线16.5米,宽40.32米
    return x >= PITCH_LENGTH - 16.5 and 13.84 <= y <= 54.16
# ---------- 2. 标记事件 ----------
def tag_events(df):
    df['in_third'] = df['x'].apply(in_final_third)
    df['in_box']   = df.apply(lambda r: in_box(r['x'], r['y']), axis=1)
    return df
# ---------- 3. 计算球队三区效率 ----------
def final_third_efficiency(df, team):
    d = df[(df['team'] == team) & (df['in_third'])].copy()
    entries      = d[d['event_type'].isin(['pass','carry']) & 
                     (d['x'] < THIRD_ZONE_X + 5)].shape[0]  # 刚跨入三区
    passes       = d[d['event_type'] == 'pass'].shape[0]
    box_passes   = d[(d['event_type'] == 'pass') & (d['in_box'])].shape[0]
    shots        = d[d['event_type'] == 'shot'].shape[0]
    xg           = d[d['event_type'] == 'shot']['xg'].sum()
    goals        = d[(d['event_type'] == 'shot') & (d['outcome']=='goal')].shape[0]
    # 效率值(0-100)
    efficiency = (shots*0.4 + xg*0.4 + goals*0.2) / max(entries,1) * 100
    return {
        'team': team,
        'entries': entries,
        'passes_in_third': passes,
        'box_passes': box_passes,
        'shots': shots,
        'xg': round(xg,2),
        'goals': goals,
        'efficiency': round(efficiency,2),
        'box_pass_rate': round(box_passes/max(passes,1),3),
        'shot_per_entry': round(shots/max(entries,1),3)
    }
# ---------- 4. 批量跑全联赛 ----------
results = [final_third_efficiency(df, t) for t in df['team'].unique()]
rank = pd.DataFrame(results).sort_values('efficiency', ascending=False)
print(rank)

进阶:加入控球时长与对手强度

三区控球时长(用事件时间戳)

d['dt'] = d['timestamp'].diff().fillna(0)
possession_time = d[d['team']==team]['dt'].sum()
efficiency_per_min = shots / (possession_time/60)

对手强度修正

# 对手防守强度系数(可用对手失球数倒数归一化)
opp_factor = 1 / (opp_goals_conceded / league_avg_conceded)
adjusted_eff = efficiency * opp_factor

场地因素

主客场分别统计,或加入 home_away 哑变量回归。


可视化输出

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10,6))
ax.barh(rank['team'], rank['efficiency'], color='steelblue')
ax.set_xlabel('进攻三区效率值')
ax.set_title('各队进攻三区效率排名')
plt.tight_layout()
plt.savefig('third_zone_efficiency.png', dpi=150)

指标解读注意事项

  1. 样本量要求:单场样本太小,建议至少10场滚动窗口。
  2. 风格偏差:控球型球队 entries 多但效率可能低;反击型球队 entries 少但效率高,需结合 entries 绝对值一起看。
  3. 权重校准:0.4/0.4/0.2 是经验值,建议用逻辑回归或泊松模型对“是否进球”做拟合来反推权重。
  4. 坐标归一化:不同数据商坐标体系不同(0-100 vs 0-120),务必统一。

如果你告诉我你用的是哪家数据(StatsBomb / Opta / 自采),我可以把坐标和字段映射改写成对应版本,并加上滚动窗口和对手修正的完整脚本。

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