综合Python案例,谁更可能先取得进球?

wen python案例 1

本文目录导读:

综合Python案例,谁更可能先取得进球?

  1. 综合Python案例:预测谁更可能先取得进球
  2. 案例总结与扩展

这是一个很有趣的数据分析/预测问题,要回答“谁更可能先取得进球”,我们需要结合Python进行数据采集(模拟)特征工程概率建模

我将为你构建一个综合案例,包含两种主流场景的分析思路:

  1. 场景A:基于历史比赛数据的统计模型(常用赛前分析) - 使用泊松分布预测进球时间和概率。
  2. 场景B:基于即时比赛状态的动态模型(常用赛中分析) - 使用随机森林预测“接下来5分钟谁进球”。

综合Python案例:预测谁更可能先取得进球

我们假设有一场足球比赛:利物浦 (主场) vs 曼城 (客场)

第一步:模拟或导入数据

为了演示,我们模拟10个赛季的球队攻击力/防守力数据,以及当前比赛的实时事件。

import pandas as pd
import numpy as np
from scipy.stats import poisson, expon
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
# 设置随机种子
np.random.seed(42)
# 1. 模拟球队的平均进球能力 (基于过去表现)
teams = ['Liverpool', 'Manchester City']
# lambda 代表平均每90分钟进球数 (进攻强度)
attack_strength = {'Liverpool': 2.5, 'Manchester City': 2.8}
defense_strength = {'Liverpool': 0.9, 'Manchester City': 0.8}  # 平均每90分钟失球数
print("=== 球队模型参数 ===")
for team in teams:
    print(f"{team}: 预期进球(进攻)={attack_strength[team]}, 预期失球(防守)={defense_strength[team]}")

第二步:场景A - 赛前泊松分布预测

泊松分布非常适合预测足球进球数,我们计算双方在比赛第t分钟取得第一个进球的概率密度。

公式: 期望进球数 $\lambda{team} = attack{team} \times defense_{opponent} \times (t/90)$

def probability_first_goal(attack_team, defense_opp, time_minutes=90):
    """
    计算在给定时间内,该队至少进1球的概率
    """
    lambda_t = attack_team * defense_opp * (time_minutes / 90.0)
    # P(X >= 1) = 1 - P(X=0)
    prob_at_least_one = 1 - poisson.pmf(0, lambda_t)
    return prob_at_least_one
# 计算全场比赛双方至少进1球的概率
prob_liv_any = probability_first_goal(attack_strength['Liverpool'], 
                                       defense_strength['Manchester City'])
prob_city_any = probability_first_goal(attack_strength['Manchester City'], 
                                        defense_strength['Liverpool'])
print("\n=== 赛前预测:谁更可能先进球? ===")
print(f"利物浦全场至少进1球概率: {prob_liv_any:.2%}")
print(f"曼城全场至少进1球概率: {prob_city_any:.2%}")
# 更精确:预测谁先打破僵局 (使用指数分布模拟时间)
# 假设进球事件是泊松过程,进球到达时间服从指数分布
def prob_team_scores_first(attack_a, defense_b, attack_b, defense_a):
    lambda_a = attack_a * defense_b / 90  # 每分钟进球率
    lambda_b = attack_b * defense_a / 90
    # 指数分布:P(T_a < T_b) = lambda_a / (lambda_a + lambda_b)
    prob_a_first = lambda_a / (lambda_a + lambda_b)
    return prob_a_first
prob_liv_first = prob_team_scores_first(attack_strength['Liverpool'], 
                                         defense_strength['Manchester City'],
                                         attack_strength['Manchester City'], 
                                         defense_strength['Liverpool'])
print(f"\n利物浦先于曼城进球的概率: {prob_liv_first:.2%}")
print(f"曼城先于利物浦进球的概率: {1-prob_liv_first:.2%}")
# 可视化进球时间概率密度
time_range = np.linspace(0, 90, 100)
lambda_liv_min = attack_strength['Liverpool'] * defense_strength['Manchester City'] / 90
lambda_city_min = attack_strength['Manchester City'] * defense_strength['Liverpool'] / 90
prob_density_liv = expon.pdf(time_range, scale=1/lambda_liv_min)
prob_density_city = expon.pdf(time_range, scale=1/lambda_city_min)
plt.figure(figsize=(10,4))
plt.plot(time_range, prob_density_liv, label='Liverpool (先进球概率密度)', color='red')
plt.plot(time_range, prob_density_city, label='Manchester City (先进球概率密度)', color='blue')
plt.xlabel('比赛时间 (分钟)')
plt.ylabel('概率密度')'谁更可能先取得进球? - 赛前概率密度分布')
plt.legend()
plt.grid(True)
plt.show()
# 曼城由于更强的攻击力,在先进球概率上略占优势。

第三步:场景B - 赛中动态预测 (实时状态模型)

现实比赛中,当前比分、红黄牌、控球率、射门数等动态变量极大地影响了“接下来谁进球”,我们用机器学习模型来预测。

模拟实时比赛事件数据:假设比赛进行到第60分钟,比分0-0。

# 模拟1000场类似的比赛片段数据
def simulate_match_segments():
    data = []
    for _ in range(1000):
        # 当前比赛状态 (第60分钟)
        home_attack_count = np.random.poisson(8)  # 射门次数
        away_attack_count = np.random.poisson(6)
        home_possession = np.random.uniform(40, 60)  # 控球率 %
        home_cards = np.random.choice([0,1,2], p=[0.7,0.2,0.1])  # 黄牌
        away_cards = np.random.choice([0,1,2], p=[0.6,0.3,0.1])
        current_score_home = 0
        current_score_away = 0
        # 模拟接下来15分钟谁进球 (0=无人, 1=主队, 2=客队)
        # 基于泊松概率
        lambda_home_next = 0.25 + (home_attack_count/10) - (away_cards/20)
        lambda_away_next = 0.20 + (away_attack_count/10) - (home_cards/20)
        events = np.random.poisson(lambda_home_next, 1)[0]
        events_away = np.random.poisson(lambda_away_next, 1)[0]
        if events > 0 and events_away == 0:
            next_goal_team = 1  # 主队
        elif events_away > 0 and events == 0:
            next_goal_team = 2  # 客队
        elif events > 0 and events_away > 0:
            next_goal_team = 1 if np.random.rand() > 0.5 else 2
        else:
            next_goal_team = 0  # 无人进球
        data.append([home_attack_count, away_attack_count, home_possession,
                     home_cards, away_cards, next_goal_team])
    columns = ['home_shots', 'away_shots', 'home_possession',
               'home_cards', 'away_cards', 'next_goal_team']
    return pd.DataFrame(data, columns=columns)
df = simulate_match_segments()
print("\n=== 赛中实时数据样本 ===")
print(df.head())
# 训练随机森林模型
X = df[['home_shots', 'away_shots', 'home_possession', 'home_cards', 'away_cards']]
y = df['next_goal_team']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 模拟当前比赛状态 (利物浦vs曼城,第60分钟)
current_match_state = pd.DataFrame([{
    'home_shots': 7,        # 利物浦射门7次
    'away_shots': 5,        # 曼城射门5次
    'home_possession': 48,  # 控球率48%
    'home_cards': 1,        # 利物浦1张黄牌
    'away_cards': 0         # 曼城0张黄牌
}])
# 预测概率
probabilities = model.predict_proba(current_match_state)[0]
print("\n=== 动态预测:接下来15分钟谁进球? ===")
print(f"无人进球概率: {probabilities[0]:.2%}")
print(f"利物浦进球概率: {probabilities[1]:.2%}")
print(f"曼城进球概率: {probabilities[2]:.2%}")
# 特征重要性分析
feature_importance = pd.DataFrame({
    'feature': X.columns,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)
print("\n特征重要性 (影响谁先进球):")
print(feature_importance)

第四步:综合分析报告

print("\n" + "="*50)
print("FINAL REPORT: WHO IS MORE LIKELY TO SCORE FIRST?")
print("="*50)
# 结合场景A和场景B
print("\n1. 赛前静态分析 (泊松分布):")
print(f"   - 利物浦先于曼城进球的概率: {prob_liv_first:.1%}")
print(f"   - 曼城先于利物浦进球的概率: {1-prob_liv_first:.1%}")
print("\n2. 赛中动态分析 (当前第60分钟, 0-0):")
print(f"   - 利物浦在接下来15分钟进球概率: {probabilities[1]:.1%}")
print(f"   - 曼城在接下来15分钟进球概率: {probabilities[2]:.1%}")
if prob_liv_first > 0.5:
    print("\n>>> 综合结论: 利物浦 (主队) 更可能先取得进球")
else:
    print("\n>>> 综合结论: 曼城 (客队) 更可能先取得进球")
print("\n影响因子: 射门次数和控球率是预测谁先进球的最重要特征。")

案例总结与扩展

模型类型 原理 适用场景 优点 缺点
泊松分布 基于历史进球率计算概率密度 赛前预测 简单、解释性强、数据少 无法利用实时动态
随机森林 基于多维特征(射门、控球等)预测 赛中进行时 可捕捉复杂非线性关系 需要大量历史比赛事件数据

如何在实际中应用?

  1. 获取真实数据:使用 sportsdataverse (Python包) 或 API (如 Opta, StatsBomb) 获取真实的传球、射门坐标数据。
  2. 期望威胁 (xT) 模型:除了简单计数,可以用“传球进入危险区域”的次数来替代“射门数”,预测精度更高。
  3. 时间衰减:比赛临近结束时,采用指数加权,越新的比赛状态权重越高。

这个综合案例展示了从静态统计动态机器学习的完整分析流程,你可以根据自己的数据情况,选择或组合使用这两种方法。

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