本文目录导读:

我来提供一个预测点球大战胜负走向的Python案例,涵盖多个维度的分析:
基础概率模型
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
class PenaltyShootoutPredictor:
def __init__(self):
# 基础命中率(基于历史数据)
self.base_success_rate = {
'average': 0.75, # 平均命中率
'elite': 0.80, # 精英射手
'weak': 0.65 # 较弱射手
}
# 门将扑救率
self.goalkeeper_save_rate = {
'top': 0.25, # 顶级门将
'average': 0.15, # 平均门将
'weak': 0.10 # 较弱门将
}
def monte_carlo_simulation(self, team_a_probs, team_b_probs, n_simulations=10000):
"""
蒙特卡洛模拟点球大战
参数:
- team_a_probs: A队每个球员的进球概率列表
- team_b_probs: B队每个球员的进球概率列表
- n_simulations: 模拟次数
"""
results = []
for _ in range(n_simulations):
result = self._simulate_single_shootout(
team_a_probs.copy(),
team_b_probs.copy()
)
results.append(result)
# 统计分析
df_results = pd.DataFrame(results, columns=['winner', 'rounds', 'score_a', 'score_b'])
return {
'team_a_win_prob': (df_results['winner'] == 'A').mean() * 100,
'team_b_win_prob': (df_results['winner'] == 'B').mean() * 100,
'avg_rounds': df_results['rounds'].mean(),
'avg_score_a': df_results['score_a'].mean(),
'avg_score_b': df_results['score_b'].mean(),
'score_distribution': df_results.groupby(['score_a', 'score_b']).size().reset_index(name='counts')
}
def _simulate_single_shootout(self, team_a_probs, team_b_probs):
"""模拟单次点球大战"""
score_a = 0
score_b = 0
round_num = 0
# 前5轮
for i in range(5):
round_num += 1
# A队射门
if i < len(team_a_probs) and np.random.random() < team_a_probs[i]:
score_a += 1
# B队射门
if i < len(team_b_probs) and np.random.random() < team_b_probs[i]:
score_b += 1
# 提前结束判断
remaining = 5 - round_num
if score_a > score_b + remaining:
return ['A', round_num, score_a, score_b]
if score_b > score_a + remaining:
return ['B', round_num, score_a, score_b]
# 突然死亡阶段
i = 5
while i < 10:
round_num += 1
# A队射门
if i < len(team_a_probs) and np.random.random() < team_a_probs[i]:
score_a += 1
# B队射门
if i < len(team_b_probs) and np.random.random() < team_b_probs[i]:
score_b += 1
if score_a != score_b:
return ['A' if score_a > score_b else 'B', round_num, score_a, score_b]
i += 1
# 极限情况 - 平局
return ['Draw', round_num, score_a, score_b]
def player_probability_calculator(self, player_stats, goalkeeper_quality='average'):
"""
根据球员统计数据计算进球概率
参数:
- player_stats: 球员历史数据 DataFrame
- goalkeeper_quality: 门将质量
"""
base_prob = self.base_success_rate['average']
# 考虑门将因素
gk_effect = 1 - self.goalkeeper_save_rate[goalkeeper_quality]
prob = base_prob * gk_effect
# 调节prob基于球员历史数据
if 'success_rate' in player_stats.columns:
historical_rate = player_stats['success_rate'].mean()
prob = (prob + historical_rate) / 2
# 考虑压力因素(第5个罚球手)
if 'penalty_order' in player_stats.columns and player_stats['penalty_order'].iloc[0] == 5:
prob *= 0.95 # 第五个罚球手压力大
return np.clip(prob, 0.5, 0.95)
特征工程与机器学习模型
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import joblib
class AdvancedPredictor:
def __init__(self):
self.model = None
self.feature_importance = None
def extract_features(self, match_data, team_data):
"""
提取预测特征
特征包括:
- 球员历史命中率
- 比赛重要性(决赛/半决赛)
- 球队整体表现
- 时间(第几分钟)
- 球员疲劳程度
- 球队排名差异
"""
features = {
'team_rank_diff': team_data['team_a_rank'] - team_data['team_b_rank'],
'team_form': team_data['recent_form_a'] - team_data['recent_form_b'],
'goalkeeper_save_rate_a': team_data['gk_save_rate_a'],
'goalkeeper_save_rate_b': team_data['gk_save_rate_b'],
'player_success_rate_avg_a': team_data['avg_penalty_success_a'],
'player_success_rate_avg_b': team_data['avg_penalty_success_b'],
'match_importance': match_data['competition_importance'],
'team_fatigue': team_data['fatigue_index_a'] - team_data['fatigue_index_b'],
'head_to_head_wins': team_data['h2h_wins_a'] - team_data['h2h_wins_b'],
'extra_time_minutes': match_data['extra_time_played']
}
return pd.DataFrame([features])
def prepare_training_data(self, historical_matches):
"""
准备训练数据
"""
X = []
y = []
for match in historical_matches:
features = self.extract_features(match['match_data'], match['team_data'])
X.append(features)
y.append(match['outcome']) # 1表示A队赢,0表示B队赢
return pd.concat(X), np.array(y)
def train_model(self, X, y):
"""训练随机森林模型"""
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
self.model = RandomForestClassifier(
n_estimators=200,
max_depth=10,
random_state=42
)
self.model.fit(X_train, y_train)
# 评估
accuracy = self.model.score(X_test, y_test)
# 特征重要性
self.feature_importance = pd.DataFrame({
'feature': X.columns,
'importance': self.model.feature_importances_
}).sort_values('importance', ascending=False)
print(f"模型准确率: {accuracy:.2%}")
return self.model
def predict_match(self, match_data, team_data):
"""预测单场比赛"""
if self.model is None:
raise ValueError("请先训练模型")
features = self.extract_features(match_data, team_data)
# 预测概率
prob_a_win = self.model.predict_proba(features)[0][1]
prob_b_win = 1 - prob_a_win
return {
'team_a_win_probability': prob_a_win * 100,
'team_b_win_probability': prob_b_win * 100,
'features': features
}
可视化分析
class VisualizationTools:
@staticmethod
def plot_win_probability(matrix):
"""绘制胜负概率热力图"""
plt.figure(figsize=(10, 8))
sns.heatmap(matrix, annot=True, fmt='.2f', cmap='RdYlBu_r')
plt.title('点球大战胜负概率矩阵')
plt.xlabel('Team B')
plt.ylabel('Team A')
plt.show()
@staticmethod
def plot_monte_carlo_results(results):
"""绘制蒙特卡洛模拟结果"""
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 胜率饼图
axes[0,0].pie(
[results['team_a_win_prob'], results['team_b_win_prob']],
labels=['Team A', 'Team B'],
autopct='%1.1f%%',
explode=[0.05, 0]
)
axes[0,0].set_title('胜负概率分布')
# 2. 轮次分布
rounds_dist = results['score_distribution']
axes[0,1].hist(rounds_dist['rounds'] if 'rounds' in rounds_dist else [5,6,7,8,9,10],
bins=range(5,11), alpha=0.7)
axes[0,1].set_title('比赛轮次分布')
axes[0,1].set_xlabel('轮次')
axes[0,1].set_ylabel('频率')
# 3. 得分分布
axes[1,0].scatter(results['score_distribution']['score_a'],
results['score_distribution']['score_b'])
axes[1,0].set_xlabel('A队得分')
axes[1,0].set_ylabel('B队得分')
axes[1,0].set_title('比分分布')
# 4. 概率累积图
axes[1,1].plot([0, 100], [0, 100], 'k--', alpha=0.5)
axes[1,1].scatter(results['team_a_win_prob'], 100 - results['team_b_win_prob'])
axes[1,1].fill_between([0, 100], 50, 100, alpha=0.1)
axes[1,1].set_xlabel('A队预测胜率 (%)')
axes[1,1].set_ylabel('实际胜率 (%)')
axes[1,1].set_title('预测vs实际')
plt.tight_layout()
plt.show()
完整使用案例
def full_prediction_example():
# 创建预测器
predictor = PenaltyShootoutPredictor()
# 示例数据:2022世界杯决赛阿根廷vs法国
team_a_probs = [0.85, 0.75, 0.80, 0.70, 0.90] # 阿根廷前5位罚球手
team_b_probs = [0.90, 0.70, 0.85, 0.75, 0.80] # 法国前5位罚球手
# 蒙特卡洛模拟
results = predictor.monte_carlo_simulation(
team_a_probs,
team_b_probs,
n_simulations=10000
)
print("=== 蒙特卡洛模拟结果 ===")
print(f"A队胜率: {results['team_a_win_prob']:.2f}%")
print(f"B队胜率: {results['team_b_win_prob']:.2f}%")
print(f"平均轮次: {results['avg_rounds']:.2f}")
# 可视化结果
viz = VisualizationTools()
viz.plot_monte_carlo_results(results)
# 高级机器学习模型
try:
# 假设有历史数据
historical_data = [] # 需要历史比赛数据
if len(historical_data) > 0:
advanced = AdvancedPredictor()
X, y = advanced.prepare_training_data(historical_data)
model = advanced.train_model(X, y)
# 预测新比赛
match_data = {
'competition_importance': 0.9, # 决赛
'extra_time_played': 30
}
team_data = {
'team_a_rank': 3,
'team_b_rank': 4,
'recent_form_a': 0.85,
'recent_form_b': 0.80,
'gk_save_rate_a': 0.20,
'gk_save_rate_b': 0.15,
'avg_penalty_success_a': 0.78,
'avg_penalty_success_b': 0.76,
'fatigue_index_a': 0.7,
'fatigue_index_b': 0.8,
'h2h_wins_a': 3,
'h2h_wins_b': 2
}
prediction = advanced.predict_match(match_data, team_data)
print(f"\n=== 机器学习预测 ===")
print(f"A队胜率: {prediction['team_a_win_probability']:.2f}%")
print(f"B队胜率: {prediction['team_b_win_probability']:.2f}%")
except Exception as e:
print(f"机器学习模型不可用: {e}")
# 球员个体分析
print("\n=== 球员命中率分析 ===")
for i, prob in enumerate(team_a_probs):
print(f"A队第{i+1}位罚球手命中率: {prob*100:.1f}%")
if __name__ == "__main__":
full_prediction_example()
进阶优化建议
class PredictorOptimization:
@staticmethod
def add_psychological_factors():
"""加入心理因素"""
factors = {
'pressure_index': 1.0, # 压力指数
'momentum_factor': 0.9, # 势头因素
'crowd_influence': 0.95, # 观众影响
'referee_effect': 1.0, # 裁判因素
'tactical_preparation': 1.05 # 战术准备程度
}
return factors
@staticmethod
def add_environmental_factors():
"""加入环境因素"""
environmental = {
'weather': 'clear', # 天气
'pitch_quality': 'excellent', # 场地质量
'altitude': 1500, # 海拔
'temperature': 22, # 温度
'wind_speed': 3 # 风速
}
return environmental
@staticmethod
def ensemble_predictions():
"""集成多种模型预测"""
predictions = []
# 分别用不同模型预测
# 1. 贝叶斯网络
# 2. 逻辑回归
# 3. 随机森林
# 4. 神经网络
# 加权平均
weights = [0.3, 0.2, 0.3, 0.2]
ensemble_pred = np.average(predictions, weights=weights)
return ensemble_pred
这个预测系统涵盖了:
- 蒙特卡洛模拟:通过大量模拟预测胜负概率
- 机器学习模型:基于历史数据训练
- 可视化分析:直观展示预测结果
- 多因素考虑:包括球员、门将、心理、环境等多维因素
实际使用时,需要收集足够的历史数据和实时数据来训练模型,以获得更准确的预测结果。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播