python案例如何利用友谊赛数据做预测?

wen python案例 5

本文目录导读:

python案例如何利用友谊赛数据做预测?

  1. 数据准备与加载
  2. 特征工程与数据预处理
  3. 模型训练与评估
  4. 特征重要性分析
  5. 模型预测函数
  6. 可视化结果
  7. 实际预测示例
  8. 模型保存与部署

我来为您提供一个完整的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
  1. 数据质量:友谊赛数据可能包含噪音,需要定期更新和清洗
  2. 特征工程:合理构造的特征比单纯使用原始数据更有效
  3. 模型选择:随机森林通常表现不错,但可以尝试多种模型对比
  4. 过拟合风险:友谊赛样本可能有限,注意使用交叉验证
  5. 实际应用:预测结果应结合实时数据和专家判断

这个案例演示了从数据准备到模型部署的完整流程,您可以根据实际数据调整特征和模型参数。

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