本文目录导读:

我来分享一个预测点球大战胜负的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}")
关键发现和建议
-
核心因素:
- 门将扑救率
- 球员射门成功率
- 心理状态和压力管理
- 身体疲劳度
-
统计分析:
- 点球进球的平均成功率约75-78%
- 前5轮进球数通常在2-4个
- 第五轮是情绪压力最大的
-
实战建议:
- 利用历史数据进行贝叶斯更新
- 考虑实时数据(球员最近状态)
- 融合多家博彩公司的赔率数据
这个案例展示了从基础模拟到机器学习的完整预测链条,你可以根据实际需求调整参数和使用不同的方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播