实用脚本如何分析定位球战术的多样性?

wen 实用脚本 16

实用脚本如何分析定位球战术的多样性

分析定位球战术多样性,核心是把"定位球"拆解成可量化的维度,再用脚本做统计、聚类和可视化,下面给出一套可落地的思路和脚本框架(Python + 常见足球数据格式)。

实用脚本如何分析定位球战术的多样性?


先定义"多样性"的量化维度

定位球战术多样性可以从以下维度衡量:

维度 指标示例
类型多样性 角球/任意球/界外球/点球的比例分布、香农熵
区域多样性 开球落点热区、传球起点-终点分布
战术模式 短传/长传、前点/后点、战术配合次数
人员参与 参与人数、跑位路线数量
时间节奏 从鸣哨到开球的秒数分布
结果多样性 射门/进球/二次进攻比例

香农熵是衡量多样性的好工具:分布越均匀,熵越高,战术越"多样"。


数据准备

假设你有一份事件数据(Opta/StatsBomb/Wyscout 风格),字段大致为:

# set_pieces.csv 示例字段
# match_id, team, type(角球/任意球/界外球), minute,
# start_x, start_y, end_x, end_y, n_passes, outcome(shot/goal/clear)
import pandas as pd
df = pd.read_csv("set_pieces.csv")

核心分析脚本

类型分布与香农熵

import numpy as np
from collections import Counter
def shannon_entropy(series):
    counts = Counter(series)
    total = sum(counts.values())
    probs = np.array([c/total for c in counts.values()])
    return -np.sum(probs * np.log2(probs))
for team, g in df.groupby("team"):
    ent = shannon_entropy(g["type"])
    print(f"{team}: 类型熵={ent:.2f}, 样本={len(g)}")

落点区域多样性(网格化 + 熵)

def zone(x, y, nx=6, ny=3):  # 把场地切成 6x3 网格
    return (int(x // (100/nx)), int(y // (100/ny)))
df["zone"] = df.apply(lambda r: zone(r["end_x"], r["end_y"]), axis=1)
for team, g in df.groupby("team"):
    print(team, "落点熵:", shannon_entropy(g["zone"]))

战术模式聚类(KMeans)

把每次定位球的"传球序列特征"作为向量:传球次数、平均传球长度、横向/纵向位移、参与人数等,聚类后看每队使用的模式数量和各模式占比。

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
feat = df[["n_passes", "start_x", "end_x", "end_y"]].fillna(0)
X = StandardScaler().fit_transform(feat)
km = KMeans(n_clusters=5, random_state=0).fit(X)
df["cluster"] = km.labels_
# 每队使用的战术簇数量 & 分布熵
for team, g in df.groupby("team"):
    print(team, "使用簇:", g["cluster"].nunique(),
          "簇分布熵:", shannon_entropy(g["cluster"]))

时间节奏多样性

# 假设有 whistle_time 和 delivery_time 字段
df["delay"] = df["delivery_time"] - df["whistle_time"]
for team, g in df.groupby("team"):
    print(team, "平均开球延迟:", g["delay"].mean(),
          "标准差:", g["delay"].std())  # 标准差大=节奏更多变

结果多样性

for team, g in df.groupby("team"):
    dist = g["outcome"].value_counts(normalize=True)
    print(team, "结果熵:", shannon_entropy(g["outcome"]), "\n", dist)

综合"多样性评分"

把各维度熵归一化后加权求和,得到一个 0–1 的多样性指数:

def diversity_score(g):
    dims = {
        "type":   shannon_entropy(g["type"]),
        "zone":   shannon_entropy(g["zone"]),
        "cluster":shannon_entropy(g["cluster"]),
        "outcome":shannon_entropy(g["outcome"]),
    }
    # 归一化到 [0,1]:除以理论最大熵 log2(类别数)
    max_ent = {"type": np.log2(g["type"].nunique()),
               "zone": np.log2(g["zone"].nunique()),
               "cluster": np.log2(g["cluster"].nunique()),
               "outcome": np.log2(g["outcome"].nunique())}
    norm = {k: v/max_ent[k] if max_ent[k] > 0 else 0 for k, v in dims.items()}
    weights = {"type":0.2, "zone":0.3, "cluster":0.3, "outcome":0.2}
    return sum(norm[k]*weights[k] for k in dims), norm
for team, g in df.groupby("team"):
    score, detail = diversity_score(g)
    print(f"{team}: 综合多样性={score:.2f}", detail)

可视化(可选)

  • 落点热力图:matplotlib/mplsoccer 画 pitch + hexbin
  • 战术簇雷达图:每队各簇占比画雷达图,一眼看出模式偏向
  • 熵的条形图:对比各队各维度熵
import mplsoccer
pitch = mplsoccer.Pitch()
fig, ax = pitch.draw()
pitch.scatter(df.end_x, df.end_y, ax=ax, alpha=0.3)

关键注意事项

  1. 样本量:定位球单场很少,建议按赛季或多场累计,否则熵不稳定。
  2. 对手调整:可拆"对阵强队/弱队"分别算,看战术是否因对手而变。
  3. 坐标统一:不同数据源坐标系不同,先归一化到 0–100。
  4. 区分定位球子类:角球与任意球战术逻辑差别大,最好分类别算多样性再汇总。
  5. 熵的陷阱:熵高不等于"好",只代表"不重复";要结合结果效率(如每类战术的进球率)一起解读。

最小可用流程总结

读数据 → 分类别清洗 → 定义特征向量
   → 各维度算熵 → 聚类看模式 → 加权综合分 → 可视化对比

如果需要,我可以针对你手上的具体数据字段(StatsBomb JSON / Wyscout / 自采表)写出可直接跑的清洗+分析脚本,告诉我是哪种格式即可。

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

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝