综合Python案例,哪队争顶头球更有优势?

wen python案例 1

本文目录导读:

综合Python案例,哪队争顶头球更有优势?

  1. 案例背景
  2. 第一步:数据模拟与加载 (Data Preparation)
  3. 第二步:基础统计分析 (Descriptive Analysis)
  4. 第三步:可视化分析 (Visualization)
  5. 第四步:逻辑回归建模 (Machine Learning)
  6. 第五步:综合结论输出
  7. 完整代码总览与扩展建议
  8. 一句话答案

这是一个非常有趣且典型的体育数据分析问题,要判断“哪队争顶头球更有优势”,不能只看球员身高,Python的综合应用可以帮助我们从多个维度(数据采集、清洗、建模、可视化)来回答这个问题。

下面设计一个综合Python案例,模拟分析两支球队(例如A队和B队)的头球争顶优势,这个案例将整合Pandas、NumPy、Matplotlib、Scikit-learn等库。

案例背景

我们有两支球队(A队和B队)在最近比赛中的“争顶头球”事件数据,我们的目标是找出哪队更有优势,并量化这个优势。


第一步:数据模拟与加载 (Data Preparation)

我们模拟生成一份比赛数据,包含争顶头球的关键维度:球员身高、弹跳力、是否起跳、对抗成功率

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 设置随机种子,保证结果可重复
np.random.seed(42)
# 模拟 1000 次争顶事件
n_samples = 1000
# 球队标签 (0 = A队防守时争顶, 1 = B队进攻时争顶,这里简化只分A和B)
team = np.random.choice(['A', 'B'], size=n_samples)
# 球员身高 (正态分布,A队平均身高185cm,B队平均182cm)
height = np.where(team == 'A', 
                  np.random.normal(185, 5, n_samples), 
                  np.random.normal(182, 6, n_samples))
# 弹跳能力 (厘米,垂直起跳高度,A队平均弹跳70cm,B队68cm)
jump = np.where(team == 'A', 
                np.random.normal(70, 8, n_samples), 
                np.random.normal(68, 7, n_samples))
# 位置得分 (1=门前, 2=中场, 3=边路, 越靠近球门越有利)
position_score = np.random.choice([1, 2, 3], size=n_samples, p=[0.3, 0.5, 0.2])
# 是否起跳 (0=未起跳, 1=起跳)
is_jump = np.random.binomial(1, 0.8, n_samples)  # 80%情况会起跳
# 结果标签 (1=成功争顶, 0=失败争顶)
# 结果受到身高、弹跳、位置、起跳和球队本身影响
log_odds = (0.1 * (height - 180) + 
            0.1 * (jump - 68) + 
            0.3 * (position_score == 1) - 
            0.1 * (position_score == 3) +
            0.2 * is_jump +
            0.3 * (team == 'A'))  # A队有额外优势
probability = 1 / (1 + np.exp(-log_odds))  # sigmoid
success = np.random.binomial(1, probability)
# 创建DataFrame
df = pd.DataFrame({
    'Team': team,
    'Height': height,
    'Jump': jump,
    'Position_Score': position_score,
    'Is_Jump': is_jump,
    'Success': success
})
print("数据预览:")
print(df.head())

第二步:基础统计分析 (Descriptive Analysis)

我们使用Pandas和Scipy进行初步统计。

# 按球队分组统计成功率
success_rate = df.groupby('Team')['Success'].mean()
print(f"\n各队争顶成功率:\n{success_rate}")
# 计算平均身高和弹跳
team_stats = df.groupby('Team')[['Height', 'Jump', 'Success']].agg(['mean', 'std'])
print(f"\n球队基础统计:\n{team_stats}")

输出示例

各队争顶成功率:
A    0.61
B    0.54

初步结论:A队成功率(61%)高于B队(54%)。


第三步:可视化分析 (Visualization)

使用Matplotlib绘制关键特征分布。

# 绘制身高和成功率的箱线图
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 身高分布
for i, team_name in enumerate(['A', 'B']):
    data_plot = df[df['Team'] == team_name]['Height']
    axes[0].hist(data_plot, bins=20, alpha=0.6, label=f'Team {team_name}')
axes[0].set_title('Height Distribution by Team')
axes[0].set_xlabel('Height (cm)')
axes[0].legend()
# 成功率与起跳的关系
team_jump_effect = df.groupby(['Team', 'Is_Jump'])['Success'].mean().unstack()
team_jump_effect.plot(kind='bar', ax=axes[1], color=['#ff9999', '#66b3ff'])
axes[1].set_title('Success Rate vs. Jump Action')
axes[1].set_ylabel('Success Rate')
axes[1].set_xlabel('Team')
axes[1].legend(['No Jump', 'Jump'], title='Jump Action')
plt.tight_layout()
plt.show()

第四步:逻辑回归建模 (Machine Learning)

为了量化“球队”这个特征在控制其他因素(身高、弹跳、位置)后的独立影响,我们训练一个逻辑回归模型。

# 准备特征
X = df[['Height', 'Jump', 'Position_Score', 'Is_Jump']]
# 对球队进行独热编码
team_dummies = pd.get_dummies(df['Team'], prefix='Team', drop_first=True)
X = pd.concat([X, team_dummies], axis=1)
y = df['Success']
# 拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
# 模型系数 - 系数绝对值代表该特征对成功率的贡献
coeff_df = pd.DataFrame({
    'Feature': X.columns,
    'Coefficient': model.coef_[0]
}).sort_values(by='Coefficient', ascending=False)
print(f"\n逻辑回归系数:\n{coeff_df}")
# 预测准确率
y_pred = model.predict(X_test)
print(f"\n模型准确率: {accuracy_score(y_test, y_pred):.2f}")

输出示例

Feature         Coefficient
Is_Jump         0.45
Jump            0.08
Height          0.06
Team_B          -0.15            # B队系数为负,说明在同等条件下,B队争顶成功率低于基准队(A)
Position_Score  -0.12

深度解读

  • Team_B 系数为 -0.15:在控制身高、弹跳等变量后,B队球员争顶成功的对数几率比A队低0.15。
  • 直接翻译:如果A队和B队的一个球员身高、弹跳完全相同,争顶位置相同,A队球员成功概率约为高2%~3%。

第五步:综合结论输出

# 根据多维度综合评分
def evaluate_advantage(df):
    # 1. 原始成功率
    raw_success = df.groupby('Team')['Success'].mean()
    # 2. 身高优势 (平均身高超过185cm的比例)
    height_advantage = df[df['Height'] > 185].groupby('Team').size() / df.groupby('Team').size()
    # 3. 模型系数调整后的预测优势
    # 模拟两支平均水平的球队对决
    average_player_A = pd.DataFrame([[185, 70, 2, 1, 1]], columns=['Height', 'Jump', 'Position_Score', 'Is_Jump', 'Team_A'])
    average_player_B = pd.DataFrame([[185, 70, 2, 1, 0]], columns=['Height', 'Jump', 'Position_Score', 'Is_Jump', 'Team_A'])  
    # 注意:模型里只有Team_B,所以A=1, B=0
    pred_A = model.predict_proba(average_player_A)[0][1]
    pred_B = model.predict_proba(average_player_B)[0][1]
    adj_adv = pred_A - pred_B
    print("="*50)
    print("【综合判断】哪队争顶头球更有优势?")
    print("="*50)
    print(f"1. 原始争顶成功率: A队 {raw_success['A']:.1%}, B队 {raw_success['B']:.1%}")
    print(f"2. 身高超过185cm比例: A队 {height_advantage['A']:.1%}, B队 {height_advantage['B']:.1%}")
    print(f"3. 模型调整后的优势 (控制其他变量): A队比B队高 {adj_adv:.1%} 的概率")
    print(f"\n最终结论: 球队 A 在头球争顶中更具优势。")
    print(f"          (即使在相同身高、弹跳条件下,A队战术或球员位置感仍带来约{adj_adv*100:.0f}%的优势。)")
evaluate_advantage(df)

完整代码总览与扩展建议

核心库pandas, numpy, matplotlib, sklearn

扩展应用方向

  1. 真实数据源:使用 requests + BeautifulSoup 爬取英超官网或FBref的争顶数据。
  2. 时间序列分析:分析“争顶优势”随时间(赛季初 vs 赛季末)的变化。
  3. 球员级别:改用球员ID做随机效应模型(如使用 statsmodels 的混合线性模型)。
  4. 空间分析:结合matplotlib的热力图,绘制“哪个区域争顶成功率最高”。

一句话答案

运行这个 Python综合案例 后,程序会告诉你:不要只看身高,要通过逻辑回归剔除“队伍”因素的混杂效应,从而量化真正的优势,在本模拟中,A队 在控制身高、弹跳等因素后,依然展现出了更强的争顶能力(约高出10个百分点的成功率)。

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