python案例如何预测点球大战胜负走向?

wen python案例 2

本文目录导读:

python案例如何预测点球大战胜负走向?

  1. 蒙特卡洛模拟法
  2. 机器学习预测法
  3. 实战预测示例
  4. 高级特征工程版
  5. 关键发现和建议

我来分享一个预测点球大战胜负的Python案例,包含数据模拟和机器学习两种方法:

蒙特卡洛模拟法

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 设置随机种子
np.random.seed(42)
class PenaltyShootoutSimulator:
    """点球大战模拟器"""
    def __init__(self, team1_strength, team2_strength):
        """
        team1_strength: 队伍1门将扑救能力(0-1)
        team2_strength: 队伍2门将扑救能力(0-1)
        """
        self.team1_save_prob = team1_strength  # 队伍1门将扑救概率
        self.team2_save_prob = team2_strength  # 队伍2门将扑救概率
        # 球员射门成功率(基于历史数据)
        self.average_shot_accuracy = 0.75  # 平均射门成功率
        self.team1_shot_accuracy = 0.78    # 队伍1射门成功率
        self.team2_shot_accuracy = 0.72    # 队伍2射门成功率
    def simulate_penalty(self, shooter_accuracy, goalkeeper_save_prob):
        """
        模拟单个点球
        返回: 1=进球, 0=未进
        """
        # 考虑门将和射手能力
        success_prob = shooter_accuracy * (1 - goalkeeper_save_prob)
        return 1 if np.random.random() < success_prob else 0
    def simulate_shootout(self):
        """
        模拟整场点球大战
        标准规则: 前5轮,如果平局则进入突然死亡
        """
        # 前5轮
        team1_goals = 0
        team2_goals = 0
        max_rounds = 5
        for round_num in range(max_rounds):
            # 队伍1射门
            team1_score = self.simulate_penalty(
                self.team1_shot_accuracy, 
                self.team2_save_prob
            )
            # 队伍2射门
            team2_score = self.simulate_penalty(
                self.team2_shot_accuracy, 
                self.team1_save_prob
            )
            team1_goals += team1_score
            team2_goals += team2_score
            # 提前结束判断
            remaining = max_rounds - (round_num + 1)
            if team1_goals > team2_goals + remaining:
                return 'Team1', team1_goals, team2_goals
            elif team2_goals > team1_goals + remaining:
                return 'Team2', team1_goals, team2_goals
        # 平局进入突然死亡
        round_num = 5
        while True:
            # 队伍1射门
            team1_score = self.simulate_penalty(
                self.team1_shot_accuracy, 
                self.team2_save_prob
            )
            # 队伍2射门
            team2_score = self.simulate_penalty(
                self.team2_shot_accuracy, 
                self.team1_save_prob
            )
            team1_goals += team1_score
            team2_goals += team2_score
            round_num += 1
            # 突然死亡判断
            if round_num > 5 and team1_goals != team2_goals:
                break
            # 防止死循环
            if round_num > 20:
                # 极小概率下的保护措施
                return 'Draw', team1_goals, team2_goals
        winner = 'Team1' if team1_goals > team2_goals else 'Team2'
        return winner, team1_goals, team2_goals
    def run_simulation(self, n_simulations=10000):
        """
        运行多次模拟
        """
        results = []
        for _ in range(n_simulations):
            result = self.simulate_shootout()
            results.append(result)
        return pd.DataFrame(results, columns=['winner', 'team1_goals', 'team2_goals'])
# 使用示例
simulator = PenaltyShootoutSimulator(
    team1_strength=0.3,  # 队伍1门将扑救率30%
    team2_strength=0.2   # 队伍2门将扑救率20%
)
# 运行10000次模拟
simulation_results = simulator.run_simulation(10000)
# 统计结果
print("=== 点球大战模拟结果 ===")
print(f"队伍1胜率: {simulation_results['winner'].value_counts().get('Team1', 0) / len(simulation_results) * 100:.1f}%")
print(f"队伍2胜率: {simulation_results['winner'].value_counts().get('Team2', 0) / len(simulation_results) * 100:.1f}%")
# 进球数分布
print("\n=== 进球数分布 ===")
print(f"队伍1平均进球: {simulation_results['team1_goals'].mean():.2f}")
print(f"队伍2平均进球: {simulation_results['team2_goals'].mean():.2f}")
# 可视化
plt.figure(figsize=(12, 5))
# 胜率饼图
plt.subplot(1, 2, 1)
winner_counts = simulation_results['winner'].value_counts()
plt.pie(winner_counts.values, labels=winner_counts.index, autopct='%1.1f%%')'点球大战胜率分布')
# 进球数分布
plt.subplot(1, 2, 2)
plt.hist(simulation_results['team1_goals'], alpha=0.7, label='Team 1', bins=10)
plt.hist(simulation_results['team2_goals'], alpha=0.7, label='Team 2', bins=10)
plt.xlabel('进球数')
plt.ylabel('频率')'进球数分布')
plt.legend()
plt.tight_layout()
plt.show()

机器学习预测法

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
class PenaltyMLPredictor:
    """基于机器学习的点球预测"""
    def __init__(self):
        self.model = RandomForestClassifier(n_estimators=100, random_state=42)
    def prepare_training_data(self, n_samples=10000):
        """
        生成训练数据
        """
        data = []
        for _ in range(n_samples):
            # 特征向量
            features = {
                'team1_strength': np.random.uniform(0.5, 0.9),  # 队伍1攻击力
                'team2_strength': np.random.uniform(0.5, 0.9),  # 队伍2攻击力
                'team1_defense': np.random.uniform(0.1, 0.5),   # 队伍1门将能力
                'team2_defense': np.random.uniform(0.1, 0.5),   # 队伍2门将能力
                'form': np.random.uniform(0, 1),                 # 状态因素
                'pressure': np.random.uniform(0, 1),            # 压力因素
                'fatigue': np.random.uniform(0, 1),             # 疲劳因素
                'historical_ratio': np.random.uniform(0, 1)     # 历史胜率
            }
            # 计算胜率(简化的逻辑模型)
            win_probability = (
                0.3 * features['team1_strength'] - 
                0.2 * features['team2_defense'] + 
                0.2 * features['form'] + 
                0.1 * features['historical_ratio'] + 
                0.1 * (1 - features['pressure']) + 
                0.1 * (1 - features['fatigue'])
            )
            # 转换为胜或负
            winner = 1 if win_probability > 0.5 else 0
            data.append((list(features.values()), winner))
        # 转换为DataFrame
        X = pd.DataFrame([d[0] for d in data], 
                        columns=['team1_strength', 'team2_strength', 
                                'team1_defense', 'team2_defense',
                                'form', 'pressure', 'fatigue', 
                                'historical_ratio'])
        y = [d[1] for d in data]
        return X, y
    def train_model(self, X_train, y_train):
        """训练模型"""
        self.model.fit(X_train, y_train)
        return self
    def predict_match(self, match_features):
        """
        预测单个比赛
        match_features: 字典包含所有特征
        """
        feature_names = ['team1_strength', 'team2_strength', 
                        'team1_defense', 'team2_defense',
                        'form', 'pressure', 'fatigue', 'historical_ratio']
        # 确保特征顺序正确
        X_pred = pd.DataFrame([match_features], columns=feature_names)
        # 预测概率
        win_probability = self.model.predict_proba(X_pred)[0][1]
        # 预测结果
        prediction = self.model.predict(X_pred)[0]
        return {
            'win_probability': win_probability,
            'winner': 'Team1' if prediction == 1 else 'Team2',
            'confidence': max(win_probability, 1 - win_probability)
        }
# 查看解释代码
import textwrap
print("="*50)
print("点球预测模型Python实现")
print("="*50)

实战预测示例

# 创建简单预测函数
def simple_penalty_prediction(team1_stats, team2_stats):
    """
    简化的点球预测
    team1_stats: (攻击力, 门将能力)
    team2_stats: (攻击力, 门将能力)
    """
    atk1, gk1 = team1_stats
    atk2, gk2 = team2_stats
    # 综合分析
    team1_advantage = (atk1 * 0.5 - gk2 * 0.3) * 0.6
    team2_advantage = (atk2 * 0.5 - gk1 * 0.3) * 0.6
    # 胜率计算
    total_advantage = 0.5 + (team1_advantage - team2_advantage)
    total_advantage = max(0, min(1, total_advantage))  # 限制在0-1之间
    print(f"队伍1胜率预测: {total_advantage*100:.1f}%")
    print(f"队伍2胜率预测: {(1-total_advantage)*100:.1f}%")
    if total_advantage > 0.6:
        return "Team1 较有优势"
    elif total_advantage < 0.4:
        return "Team2 较有优势"
    else:
        return "双方势均力敌"
# 实战示例
print("示例:巴西(攻击力0.85, 门将能力0.35) vs 德国(攻击力0.82, 门将能力0.40)")
result = simple_penalty_prediction((0.85, 0.35), (0.82, 0.40))
print(f"预测结果: {result}")

高级特征工程版

import numpy as np
def advanced_penalty_predictor(data_dict):
    """
    使用更多特征的高级预测器
    data_dict包含:
    - home_advantage: 主场优势 (0~1)
    - experience: 大赛经验 (0~1)  
    - tiredness: 疲劳程度 (0~1)
    - match_importance: 比赛重要性 (0~1)
    """
    # 基础胜率
    base_rate = 0.5
    # 权重调整
    adjustments = {
        'home_advantage': 0.1,    # 主场优势
        'experience': 0.15,       # 经验
        'tiredness': -0.1,        # 疲劳
        'match_importance': 0.05  # 重要性
    }
    # 调整胜率
    adjusted_rate = base_rate
    for key, weight in adjustments.items():
        if key in data_dict:
            value = data_dict[key] * weight
            # 根据队伍1还是队伍2调整
            if key in ['home_advantage', 'experience']:
                adjusted_rate += value
            else:
                adjusted_rate -= value
    # 限制在0.05-0.95之间
    adjusted_rate = max(0.05, min(0.95, adjusted_rate))
    return {
        'team1_win_prob': adjusted_rate,
        'team2_win_prob': 1 - adjusted_rate,
        'prediction': 'Team1' if adjusted_rate > 0.5 else 'Team2',
        'confidence': abs(adjusted_rate - 0.5) * 2
    }
# 使用示例
match_data = {
    'home_advantage': 0.7,     # 主队有优势
    'experience': 0.8,         # 主队经验丰富
    'tiredness': 0.3,          # 客队更疲劳
    'match_importance': 0.9    # 重要比赛
}
result = advanced_penalty_predictor(match_data)
print(f"预测结果: {result}")

关键发现和建议

  1. 核心因素

    • 门将扑救率
    • 球员射门成功率
    • 心理状态和压力管理
    • 身体疲劳度
  2. 统计分析

    • 点球进球的平均成功率约75-78%
    • 前5轮进球数通常在2-4个
    • 第五轮是情绪压力最大的
  3. 实战建议

    • 利用历史数据进行贝叶斯更新
    • 考虑实时数据(球员最近状态)
    • 融合多家博彩公司的赔率数据

这个案例展示了从基础模拟到机器学习的完整预测链条,你可以根据实际需求调整参数和使用不同的方法。

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