实用脚本如何识别球队的战术风格类型?

wen 实用脚本 1

本文目录导读:

实用脚本如何识别球队的战术风格类型?

  1. 先定义战术风格的维度
  2. 数据来源
  3. 特征工程脚本骨架
  4. 风格分类
  5. 进阶:时序 + 对手校正
  6. 工程化建议
  7. 一句话总结

识别球队的战术风格,本质上是把比赛中的行为数据映射到几个关键维度上,下面给出一套可直接落地的脚本思路,从数据采集到风格标签输出。

先定义战术风格的维度

不要一上来就分"传控/防反"这种大标签,先用连续变量描述:

维度 指标示例 含义
控球倾向 possession%、传球数/90 是否主导球权
推进方式 长传占比、场均推进距离、中后场传球占比 地面渗透 vs 长传冲吊
进攻节奏 每次进攻用时、场均射门、PPDA 快攻 vs 阵地
防守强度 PPDA、抢断位置、犯规数 高位逼抢 vs 低位退防
空间利用 边路进攻占比、传中数、禁区内触球 边中结合 vs 中路
转换倾向 由守转攻平均时长、反击射门占比 反击型 vs 控制型

数据来源

# 常用数据源
# - StatsBomb Open Data (免费, JSON事件流)
# - FBref (球队/球员赛季聚合数据, 可爬)
# - Understat (xG相关, 部分联赛)
# - football-data.org API (基础赛程比分)
# - WhoScored / SofaScore (需注意ToS)

以 StatsBomb 事件数据为例:

from statsbombpy import sb
matches = sb.matches(competition_id=11, season_id=90)  # 西甲某赛季
events = sb.events(match_id=matches.iloc[0]['match_id'])

特征工程脚本骨架

import pandas as pd
import numpy as np
def extract_team_features(events: pd.DataFrame, team: str) -> dict:
    ev = events[events['team'] == team].copy()
    opp = events[events['team'] != team].copy()
    passes = ev[ev['type'] == 'Pass']
    total_passes = len(passes)
    # 1. 控球率
    possession = len(ev) / (len(ev) + len(opp))
    # 2. 长传占比 (传球距离 > 32m)
    if 'pass_length' in passes:
        long_ball_ratio = (passes['pass_length'] > 32).mean()
    else:
        long_ball_ratio = np.nan
    # 3. 进攻方向偏好 (边路 vs 中路)
    if 'pass_end_x' in passes and 'pass_end_y' in passes:
        # y 从 0-80, 中间 18-62 为中路
        central = passes['pass_end_y'].between(18, 62).mean()
        wide = 1 - central
    else:
        central, wide = np.nan, np.nan
    # 4. 推进性传球占比 (向前 > 10m)
    if 'pass_end_x' in passes and 'x' in passes:
        progressive = ((passes['pass_end_x'] - passes['x']) > 10).mean()
    # 5. PPDA (对手每次防守动作允许的传球数, 越低越高位逼抢)
    opp_def_actions = len(opp[opp['type'].isin(
        ['Pressure','Interception','Tackle','Foul Committed'])])
    ppda = total_passes / opp_def_actions if opp_def_actions else np.nan
    # 6. 平均进攻发起位置
    carries = ev[ev['type'] == 'Carry']
    avg_x = ev['x'].mean() if 'x' in ev else np.nan
    return {
        'team': team,
        'possession': possession,
        'long_ball_ratio': long_ball_ratio,
        'central_ratio': central,
        'wide_ratio': wide,
        'progressive_pass_ratio': progressive,
        'ppda': ppda,
        'avg_x': avg_x,
    }

风格分类

方案 A:规则阈值(可解释性强)

def classify_style(f):
    if f['possession'] > 0.58 and f['ppda'] < 10 and f['long_ball_ratio'] < 0.15:
        return '控球压迫型'   # 类似曼城/巴萨
    if f['possession'] < 0.45 and f['ppda'] > 15 and f['progressive_pass_ratio'] > 0.25:
        return '低位防反型'   # 类似穆里尼奥球队
    if f['long_ball_ratio'] > 0.25 and f['wide_ratio'] > 0.55:
        return '长传边路型'
    if f['ppda'] < 8 and f['possession'] < 0.5:
        return '高压反击型'   # 类似克洛普早期
    return '均衡型'

方案 B:无监督聚类(更客观)

from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
def cluster_styles(features_df: pd.DataFrame, k=5):
    cols = ['possession','long_ball_ratio','central_ratio',
            'progressive_pass_ratio','ppda','avg_x']
    X = StandardScaler().fit_transform(features_df[cols].fillna(0))
    km = KMeans(n_clusters=k, n_init=10, random_state=42)
    features_df['cluster'] = km.fit_predict(X)
    # 查看每个簇的均值, 人工命名
    print(features_df.groupby('cluster')[cols].mean())
    return features_df

聚类后每个簇的均值就是风格"指纹",人工对照命名即可。

方案 C:多维度雷达打分

输出 0–100 的风格分数,更适合作图:

def style_radar(f):
    return {
        '控球':       min(100, f['possession'] * 150),
        '高位逼抢':   max(0, 100 - f['ppda'] * 5),
        '直接性':     min(100, f['long_ball_ratio'] * 300),
        '边路倾向':   min(100, f['wide_ratio'] * 150),
        '推进性':     min(100, f['progressive_pass_ratio'] * 300),
    }

进阶:时序 + 对手校正

单一赛季均值会失真,建议:

  1. 滚动窗口:每 5 场滚动计算,看风格漂移
  2. 对手强度校正:用对手 PPDA / 控球率做回归,提取残差
  3. 情境分档:领先 / 落后 / 平局分别统计——很多球队落后时风格突变
  4. xG 链:把进球序列连成 possession chain,看每次进攻的推进路径
# 示例: 按比分状态分组
def split_by_scoreline(events):
    # 需先从 shot/goal 事件推导比分时间线
    ...

工程化建议

  • 事件数据用 polars 或 duckdb 处理,比 pandas 快数倍
  • 特征表落盘 Parquet,方便回测
  • 加 matplotlib / mplsoccer 画热图和雷达图,一眼看出风格
  • 定期跑批:每周更新,监控风格变化(换帅、转会窗后常变)

一句话总结

采集事件 → 抽 6 个维度特征 → 标准化 → 规则或聚类打标签 → 结合情境和时序做校正 → 可视化输出。

核心三件套:possession、PPDA、long_ball_ratio,能把 80% 的战术风格区分开。

需要我针对某个具体数据源(如 StatsBomb / FBref)写一份完整可运行的脚本吗?

上一篇根据实时实用脚本,体能低谷期何时到来?

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

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