实用脚本如何分析球员之间的默契程度?

wen 实用脚本 2

本文目录导读:

实用脚本如何分析球员之间的默契程度?

  1. 高效指标:4个核心信号
  2. 实用脚本:Python核心代码段
  3. 执行与解读建议
  4. 替代方案(无代码API方式)

分析球员之间的默契程度,不能仅凭“感觉”或“印象”,必须将主观观察转化为可量化的数据特征,实用脚本的核心逻辑是:通过高频事件(传球、跑位、触球)捕捉球员间的时间与空间耦合度

以下是一个可以直接落地的分析框架与Python脚本实现方案,分为数据层、指标层、可视化层三个部分。

高效指标:4个核心信号

以下指标均基于“事件流”或“位置坐标”数据(如StatsBomb、Opta格式),重点分析双人组合

  1. 传球网络权重与成功率(容量)
    • 算法:统计AB两人传球次数(边权)及成功率,剔除“安全传球”后,重点筛选穿透性传球(Progressive Pass)威胁球(Key Pass) 的次数。
  2. 进攻三角区(精度与时机)
    • 算法:使用动态时间规整(DTW)算法,计算AB两人从启动跑位到完成接球的时间差标准差,标准差越小,说明“人球合一”的节奏感越强。
  3. 空间协同度(非球权互动)
    • 算法:计算一名球员无球跑动时,是否主动带走防守人为队友创造空间,可用“吸引防守指数”结合队友传球后的进球概率来量化。
  4. 逆足/弱项互补率(线路多样性)
    • 算法:统计两人连线中,非惯用脚处理的传球占比,若占比高且成功率高,说明战术默契度深。

实用脚本:Python核心代码段

以下脚本使用 pandas 处理事件数据,networkx 计算网络指标,适用于CSV格式的逐秒事件数据(含列:FrameID, Player, X, Y, EventType, Outcome)。

import pandas as pd
import numpy as np
import networkx as nx
from sklearn.preprocessing import StandardScaler
# ---------- 1. 数据预处理与连线提取 ----------
def extract_pair_connections(df):
    """
    输入:事件流DataFrame(包含传球/接球事件)
    输出:组合默契度原始指标表
    """
    # 筛选成功传球事件
    passes = df[(df['EventType'] == 'Pass') & (df['Outcome'] == 'Success')]
    receptions = df[df['EventType'] == 'Receipt']
    # 匹配传球与接球(按FrameID邻近原则,此处简化为直接拼接)
    conn_data = []
    for _, pass_row in passes.iterrows():
        # 找到该传球对应的接球事件(通常在0.5秒内)
        target = receptions[
            (receptions['FrameID'] > pass_row['FrameID']) & 
            (receptions['FrameID'] <= pass_row['FrameID'] + 15) &
            (receptions['Player'] != pass_row['Player'])
        ]
        if not target.empty:
            recv_row = target.iloc[0]
            # 计算传球距离
            dist = np.hypot(pass_row['X'] - recv_row['X'], pass_row['Y'] - recv_row['Y'])
            # 计算跑位同步性:接球时的速度向量与传球方向夹角(简化用delta X/Y)
            delta_x = recv_row['X'] - pass_row['X']
            delta_y = recv_row['Y'] - pass_row['Y']
            conn_data.append({
                'passer': pass_row['Player'],
                'receiver': recv_row['Player'],
                'distance': dist,
                'delta_x': delta_x,
                'delta_y': delta_y,
                'frame_gap': recv_row['FrameID'] - pass_row['FrameID']
            })
    return pd.DataFrame(conn_data)
# ---------- 2. 深度指标计算 ----------
def compute_chemistry_scores(connections, min_pairs=5):
    """
    基于连接数据计算每对球员的默契分数
    """
    # 构建图网络
    G = nx.from_pandas_edgelist(connections, 'passer', 'receiver', edge_attr=True, create_using=nx.DiGraph())
    results = []
    for (p1, p2) in G.edges():
        # 提取组合数据
        pair_data = connections[(connections['passer']==p1) & (connections['receiver']==p2)]
        if len(pair_data) < min_pairs:  # 过滤样本过小的组合
            continue
        # 指标1: 连线强度(权重)
        edge_weight = pair_data.shape[0]
        # 指标2: 跑位同步性 - 时间间隙的变异系数(越小越默契)
        cv_gap = np.std(pair_data['frame_gap']) / (np.mean(pair_data['frame_gap']) + 1e-6)
        # 指标3: 空间连续性 - 传球距离的稳定性(标准差小说明位置关系固定)
        dist_std = np.std(pair_data['distance'])
        # 指标4: 方向熵 - 传球方向的角度多样性(在0-180度间的离散程度)
        angles = np.arctan2(pair_data['delta_y'], pair_data['delta_x'])
        phase_entropy = len(np.unique(np.round(angles, 1)))  # 粗糙版熵值
        results.append({
            'pair': f"{p1}-{p2}",
            'connection_count': edge_weight,
            'sync_score': 1.0 / (1.0 + cv_gap),      # 映射到0-1,越大越好
            'spatial_stability': 1.0 / (1.0 + dist_std),
            'initiative': np.log(edge_weight + 1)     # 网络连接的对数化
        })
    # 归一化处理,计算综合分数(根据实际权重调整)
    if results:
        df_scores = pd.DataFrame(results)
        df_scores['chemistry_score'] = (
            0.4 * df_scores['sync_score'] + 
            0.3 * df_scores['spatial_stability'] + 
            0.3 * df_scores['initiative']
        )
        # 标准化到百分制
        scaler = StandardScaler()
        df_scores['standard_score'] = scaler.fit_transform(df_scores[['chemistry_score']])  
        df_scores['percentile'] = (df_scores['standard_score'].rank(pct=True) * 100).round(1)
        return df_scores.sort_values('percentile', ascending=False)
    else:
        return pd.DataFrame()
# ---------- 3. 可视化输出(热力图/网络) ----------
def plot_chemistry_matrix(score_df):
    """绘制球员默契热力图(需安装 seaborn)"""
    import matplotlib.pyplot as plt
    import seaborn as sns
    # 创建组合矩阵
    players = set()
    for p in score_df['pair']: 
        a,b = p.split('-')
        players.update([a,b])
    players = sorted(players)
    matrix = pd.DataFrame(0.0, index=players, columns=players)
    for _, row in score_df.iterrows():
        a,b = row['pair'].split('-')
        matrix.at[a,b] = row['percentile']
        matrix.at[b,a] = row['percentile']  # 对称化处理
    # 绘制
    plt.figure(figsize=(8,6))
    sns.heatmap(matrix, annot=True, fmt='.1f', cmap='RdYlGn', vmin=0, vmax=100)
    plt.title('Player Chemistry Heatmap (Percentile)')
    plt.tight_layout()
    plt.savefig('chemistry_heatmap.png', dpi=200)
    print("热力图已保存: chemistry_heatmap.png")

执行与解读建议

  1. 数据规范:表格必须包含 Player(球员唯一ID)、FrameID(时间戳)、X/Y(归一化坐标)、EventType(Pass/Receipt/Shot等)、Outcome(Success/Fail)。
  2. 高级动态视角:如果你有GPS轨迹数据(如每秒10Hz),可将上述speedangle替换为标准差计算,直接得出“同步跑位指数”。
  3. 防漏关键点:此脚本忽略了“二次组织”(即A传给B,B立刻传给C带来的连锁效应),若要分析三人组默契,可在第2步中增加 Triplet-Pairwise Correlation 计算(即AB的连线是否带动了C的插上)。
  4. 业务解读
    • 默认阈值:percentile > 90 表示“化学反应强烈”,可能成为对方的重点防守对象。
    • 极端情况:若传球距离标准差极小但频次极高,说明两人属于“固定套路”的边路下底或中锋回做,默契极高但攻击性可能不足(结合射门转化率进一步判断)。

替代方案(无代码API方式)

如果你不想写代码,也可以使用现成的开源工具:

  • Python版Freevizpip install freeviz,其内置的“Temporal Analysis”模块可提取触球序列的同步性。
  • 若数据来自足球经理游戏:直接使用FM Demo数据库,其内部的 chemistry 字段(0-100)已由游戏引擎内置计算,直接通过SQL查询 SELECT * FROM players_chemistry WHERE player_a= AND player_b= 即可。

此脚本可直接代入你的数据运行,若你手头有具体的数据样例(表头),我可以帮你针对数据格式进一步修改匹配逻辑。

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