本文目录导读:

我来为您提供一个完整的Python案例,演示如何利用友谊赛数据做预测,这里以足球友谊赛为例:
数据准备与加载
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
import warnings
warnings.filterwarnings('ignore')
# 创建示例友谊赛数据
np.random.seed(42)
n_matches = 500
data = {
'home_team_rank': np.random.randint(1, 50, n_matches), # 主队排名
'away_team_rank': np.random.randint(1, 50, n_matches), # 客队排名
'home_win_rate': np.random.uniform(0.3, 0.8, n_matches), # 主队近期胜率
'away_win_rate': np.random.uniform(0.3, 0.8, n_matches), # 客队近期胜率
'home_avg_goals': np.random.uniform(0.5, 3.0, n_matches), # 主队场均进球
'away_avg_goals': np.random.uniform(0.5, 3.0, n_matches), # 客队场均进球
'home_avg_conceded': np.random.uniform(0.5, 2.5, n_matches), # 主队场均失球
'away_avg_conceded': np.random.uniform(0.5, 2.5, n_matches), # 客队场均失球
'stadium_advantage': np.random.choice([0, 1], n_matches, p=[0.3, 0.7]), # 主场优势
'weather': np.random.choice(['sunny', 'rainy', 'cloudy'], n_matches), # 天气
'match_importance': np.random.choice(['high', 'medium', 'low'], n_matches) # 比赛重要程度
}
df = pd.DataFrame(data)
# 模拟比赛结果 (1=主队胜, 0=平局, -1=客队胜)
def generate_results(row):
home_strength = (100 - row['home_team_rank']) * 0.3 + row['home_win_rate'] * 10 + \
row['home_avg_goals'] * 2 - row['home_avg_conceded'] * 1.5
away_strength = (100 - row['away_team_rank']) * 0.3 + row['away_win_rate'] * 10 + \
row['away_avg_goals'] * 2 - row['away_avg_conceded'] * 1.5
if row['stadium_advantage'] == 1:
home_strength *= 1.2
# 添加天气影响
if row['weather'] == 'rainy':
home_strength *= 0.9
away_strength *= 0.95
diff = home_strength - away_strength + np.random.normal(0, 3)
if diff > 1:
return 1 # 主队胜
elif diff < -1:
return -1 # 客队胜
else:
return 0 # 平局
df['result'] = df.apply(generate_results, axis=1)
特征工程与数据预处理
# 特征工程
df['rank_diff'] = df['home_team_rank'] - df['away_team_rank']
df['win_rate_diff'] = df['home_win_rate'] - df['away_win_rate']
df['goals_diff'] = df['home_avg_goals'] - df['away_avg_goals']
df['conceded_diff'] = df['home_avg_conceded'] - df['away_avg_conceded']
# 编码分类变量
from sklearn.preprocessing import LabelEncoder, StandardScaler
le_weather = LabelEncoder()
le_importance = LabelEncoder()
le_result = LabelEncoder()
df['weather_encoded'] = le_weather.fit_transform(df['weather'])
df['importance_encoded'] = le_importance.fit_transform(df['match_importance'])
df['result_encoded'] = le_result.fit_transform(df['result'])
# 选择特征
features = ['home_team_rank', 'away_team_rank', 'home_win_rate', 'away_win_rate',
'home_avg_goals', 'away_avg_goals', 'home_avg_conceded', 'away_avg_conceded',
'stadium_advantage', 'weather_encoded', 'importance_encoded',
'rank_diff', 'win_rate_diff', 'goals_diff', 'conceded_diff']
X = df[features]
y = df['result_encoded']
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
print(f"训练集大小: {len(X_train)}")
print(f"测试集大小: {len(X_test)}")
print(f"类别分布:\n{df['result'].value_counts(normalize=True)}")
模型训练与评估
# 随机森林模型
model_rf = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
model_rf.fit(X_train, y_train)
y_pred_rf = model_rf.predict(X_test)
accuracy_rf = accuracy_score(y_test, y_pred_rf)
print(f"随机森林准确率: {accuracy_rf:.3f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred_rf))
# 逻辑回归模型
from sklearn.linear_model import LogisticRegression
model_lr = LogisticRegression(max_iter=1000)
model_lr.fit(X_train, y_train)
y_pred_lr = model_lr.predict(X_test)
accuracy_lr = accuracy_score(y_test, y_pred_lr)
print(f"\n逻辑回归准确率: {accuracy_lr:.3f}")
# XGBoost模型
try:
from xgboost import XGBClassifier
model_xgb = XGBClassifier(n_estimators=100, learning_rate=0.1, random_state=42)
model_xgb.fit(X_train, y_train)
y_pred_xgb = model_xgb.predict(X_test)
accuracy_xgb = accuracy_score(y_test, y_pred_xgb)
print(f"XGBoost准确率: {accuracy_xgb:.3f}")
except:
print("XGBoost未安装,跳过")
特征重要性分析
# 特征重要性
feature_importance = pd.DataFrame({
'feature': features,
'importance': model_rf.feature_importances_
}).sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
plt.barh(feature_importance['feature'][:10], feature_importance['importance'][:10])
plt.xlabel('重要性')'特征重要性分析')
plt.tight_layout()
plt.show()
print("Top 10 重要特征:")
print(feature_importance.head(10))
模型预测函数
def predict_match(home_stats, away_stats, stadium_advantage=1, weather='sunny', importance='medium'):
"""
预测比赛结果
home_stats: 主队统计 (排名, 胜率, 场均进球, 场均失球)
away_stats: 客队统计 (排名, 胜率, 场均进球, 场均失球)
"""
# 构建特征向量
home_rank, home_win_rate, home_goals, home_conceded = home_stats
away_rank, away_win_rate, away_goals, away_conceded = away_stats
# 计算衍生特征
rank_diff = home_rank - away_rank
win_rate_diff = home_win_rate - away_win_rate
goals_diff = home_goals - away_goals
conceded_diff = home_conceded - away_conceded
# 编码分类变量
weather_map = {'sunny': 0, 'rainy': 1, 'cloudy': 2}
importance_map = {'high': 2, 'medium': 1, 'low': 0}
# 创建特征向量
features_list = [home_rank, away_rank, home_win_rate, away_win_rate,
home_goals, away_goals, home_conceded, away_conceded,
stadium_advantage, weather_map[weather], importance_map[importance],
rank_diff, win_rate_diff, goals_diff, conceded_diff]
# 标准化
features_scaled = scaler.transform([features_list])
# 预测概率
prediction = model_rf.predict(features_scaled)
probabilities = model_rf.predict_proba(features_scaled)
# 结果映射
result_map = {0: '客队胜', 1: '平局', 2: '主队胜'} # 注意实际映射
# 根据le_result的映射调整
decoded_result = le_result.inverse_transform(prediction)[0]
return {
'prediction': decoded_result,
'probabilities': probabilities[0],
'confidence': np.max(probabilities[0])
}
可视化结果
# 预测概率可视化
def plot_prediction_probabilities(model, sample_index=0):
X_sample = X_test[sample_index:sample_index+1]
y_true = y_test[sample_index]
proba = model.predict_proba(X_sample)[0]
plt.figure(figsize=(8, 4))
plt.bar(['客队胜', '平局', '主队胜'], proba, color=['red', 'yellow', 'green'])
plt.ylabel('概率')
plt.title(f'预测概率分布 (实际结果: {le_result.inverse_transform([y_true])[0]})')
plt.ylim(0, 1)
for i, p in enumerate(proba):
plt.text(i, p + 0.01, f'{p:.2%}', ha='center')
plt.tight_layout()
plt.show()
plot_prediction_probabilities(model_rf)
# 混淆矩阵
from sklearn.metrics import confusion_matrix
import itertools
def plot_confusion_matrix(cm, classes, title='Confusion Matrix'):
plt.figure(figsize=(8, 6))
plt.imshow(cm, interpolation='nearest', cmap='Blues')
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
thresh = cm.max() / 2
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], 'd'),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.ylabel('真实标签')
plt.xlabel('预测标签')
plt.tight_layout()
plt.show()
cm = confusion_matrix(y_test, y_pred_rf)
plot_confusion_matrix(cm, classes=['客队胜', '平局', '主队胜'])
实际预测示例
# 预测示例
print("="*50)
print("友谊赛预测示例")
print("="*50)
# 示例:强队主场 vs 弱队客场
home_team = (5, 0.75, 2.1, 1.0) # 排名5,胜率75%,场均进球2.1,场均失球1.0
away_team = (35, 0.45, 1.2, 1.8) # 排名35,胜率45%,场均进球1.2,场均失球1.8
result = predict_match(home_team, away_team, stadium_advantage=1, weather='sunny', importance='high')
print(f"\n强队主场 vs 弱队客场:")
print(f"预测结果: {result['prediction']}")
print(f"置信度: {result['confidence']:.2%}")
# 示例:实力相当的中立场地
home_team = (15, 0.60, 1.5, 1.2)
away_team = (18, 0.58, 1.4, 1.3)
result = predict_match(home_team, away_team, stadium_advantage=0, weather='cloudy', importance='low')
print(f"\n实力相当的中立场地:")
print(f"预测结果: {result['prediction']}")
print(f"置信度: {result['confidence']:.2%}")
模型保存与部署
import joblib
# 保存模型和预处理对象
joblib.dump(model_rf, 'friendly_match_model.pkl')
joblib.dump(scaler, 'scaler.pkl')
joblib.dump(le_weather, 'weather_encoder.pkl')
joblib.dump(le_importance, 'importance_encoder.pkl')
joblib.dump(le_result, 'result_encoder.pkl')
print("模型和预处理器已保存")
# 加载模型(生产环境使用)
def load_models():
model = joblib.load('friendly_match_model.pkl')
scaler = joblib.load('scaler.pkl')
le_weather = joblib.load('weather_encoder.pkl')
le_importance = joblib.load('importance_encoder.pkl')
le_result = joblib.load('result_encoder.pkl')
return model, scaler, le_weather, le_importance, le_result
- 数据质量:友谊赛数据可能包含噪音,需要定期更新和清洗
- 特征工程:合理构造的特征比单纯使用原始数据更有效
- 模型选择:随机森林通常表现不错,但可以尝试多种模型对比
- 过拟合风险:友谊赛样本可能有限,注意使用交叉验证
- 实际应用:预测结果应结合实时数据和专家判断
这个案例演示了从数据准备到模型部署的完整流程,您可以根据实际数据调整特征和模型参数。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播