本文目录导读:

我来给你分享一个使用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.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score, classification_report
import warnings
warnings.filterwarnings('ignore')
# 创建示例数据(模拟10年的友谊赛记录)
np.random.seed(42)
# 生成示例数据
n_matches = 500
data = {
'对手排名': np.random.randint(1, 50, n_matches), # 1-50名
'主场': np.random.choice([0, 1], n_matches), # 0=客场, 1=主场
'天气': np.random.choice(['晴', '雨', '雪', '阴'], n_matches),
'对手实力': np.random.randint(1, 5, n_matches), # 1-4级
'主力球员缺阵': np.random.choice([0, 1], n_matches), # 0=无缺阵, 1=有缺阵
'上一场赢球': np.random.choice([0, 1], n_matches),
'近期状态(最近5场胜率)': np.random.uniform(0, 1, n_matches),
'平均进球': np.random.uniform(0, 3.5, n_matches),
'平均失球': np.random.uniform(0, 3.5, n_matches),
# 标签:胜负结果
'结果': np.random.choice(['胜', '平', '负'], n_matches,
p=[0.5, 0.25, 0.25])
}
df = pd.DataFrame(data)
print("数据集基本信息:")
print(f"总比赛场次: {len(df)}")
print(f"\n结果分布:")
print(df['结果'].value_counts())
print("\n特征列:")
print(df.columns.tolist())
数据预处理与特征工程
# 数据清洗和特征编码
def preprocess_data(df):
# 复制数据避免修改原数据
df_processed = df.copy()
# 处理分类变量
le = LabelEncoder()
df_processed['天气_编码'] = le.fit_transform(df['天气'])
# 创建新特征:进球差
df_processed['进球差'] = df['平均进球'] - df['平均失球']
# 创建综合评分特征
df_processed['综合实力得分'] = (
(df['对手排名'] < 10) * 3 + # 对手排名很前的加3分
(df['对手实力'] == 1) * 2 + # 对手实力最强的加2分
(df['主场'] == 1) * 1 + # 主场加1分
df['近期状态(最近5场胜率)'] * 2 # 状态好的加分
)
# 对手强弱分类
df_processed['对手强弱'] = pd.cut(df['对手排名'],
bins=[0, 5, 15, 30, 50],
labels=['强', '较强', '中等', '弱'])
return df_processed
# 处理数据
df_processed = preprocess_data(df)
print("\n处理后的特征:")
print(df_processed.columns.tolist())
# 查看相关性矩阵
plt.figure(figsize=(12, 8))
correlation_matrix = df_processed[['对手排名', '主场', '主力球员缺阵',
'上一场赢球', '近期状态(最近5场胜率)',
'进球差', '综合实力得分']].corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f')'特征相关性矩阵')
plt.tight_layout()
plt.show()
模型训练
from sklearn.preprocessing import StandardScaler
# 选择特征
features = ['对手排名', '主场', '主力球员缺阵', '上一场赢球',
'近期状态(最近5场胜率)', '进球差', '综合实力得分', '天气_编码']
X = df_processed[features]
y = df_processed['结果'] # 标签
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 随机森林模型
rf_model = RandomForestClassifier(
n_estimators=100,
max_depth=10,
random_state=42,
n_jobs=-1
)
# 训练模型
print("开始训练随机森林模型...")
rf_model.fit(X_train_scaled, y_train)
# 预测与评估
y_pred_rf = rf_model.predict(X_test_scaled)
accuracy_rf = accuracy_score(y_test, y_pred_rf)
print(f"\n随机森林模型准确率: {accuracy_rf:.2%}")
print("\n详细分类报告:")
print(classification_report(y_test, y_pred_rf))
特征重要性分析
# 特征重要性可视化
feature_importance = pd.DataFrame({
'特征': features,
'重要性': rf_model.feature_importances_
}).sort_values('重要性', ascending=False)
plt.figure(figsize=(10, 6))
sns.barplot(data=feature_importance, x='重要性', y='特征')'特征重要性排名')
plt.tight_layout()
plt.show()
print("\n特征重要性排名:")
for idx, row in feature_importance.iterrows():
print(f"{row['特征']}: {row['重要性']:.3f}")
预测下一场比赛
def predict_next_match(model, scaler, features_list):
"""
预测下一场比赛结果
"""
prediction = model.predict([features_list])
probabilities = model.predict_proba([features_list])
result_map = {'胜': '胜利', '平': '平局', '负': '失利'}
class_names = model.classes_
print("="*50)
print("下一场比赛预测:")
print("="*50)
print(f"预测结果: {result_map[prediction[0]]}")
print("\n概率分布:")
for i, prob in enumerate(probabilities[0]):
print(f" {result_map[class_names[i]]}: {prob:.2%}")
return prediction[0], probabilities[0]
# 场景1:主场对阵强队
print("\n场景1: 主场对阵世界排名第3的强队")
scenario1 = [3, 1, 0, 1, 0.8, 1.5, 3, 1] # 排名3,主场,无缺阵,赢球,状态好,进球差1.5
scenario1_scaled = scaler.transform([scenario1])
predict_next_match(rf_model, scaler, scenario1_scaled[0])
# 场景2:客场对阵弱队
print("\n场景2: 客场对阵排名第45位的弱队")
scenario2 = [45, 0, 1, 0, 0.3, -0.5, 1, 0] # 排名45,客场,有缺阵,输球
scenario2_scaled = scaler.transform([scenario2])
predict_next_match(rf_model, scaler, scenario2_scaled[0])
模型对比与优化
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from xgboost import XGBClassifier
# 比较多个模型
models = {
'RandomForest': RandomForestClassifier(n_estimators=100, random_state=42),
'LogisticRegression': LogisticRegression(max_iter=1000, random_state=42),
'XGBoost': XGBClassifier(n_estimators=100, random_state=42, eval_metric='mlogloss'),
'DecisionTree': DecisionTreeClassifier(max_depth=5, random_state=42)
}
results = {}
for name, model in models.items():
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
results[name] = accuracy
print(f"{name} 准确率: {accuracy:.2%}")
# 绘制模型对比图
plt.figure(figsize=(8, 5))
models_names = list(results.keys())
accuracies = list(results.values())
bars = plt.bar(models_names, accuracies, color=['skyblue', 'lightgreen', 'lightcoral', 'orange'])
plt.ylim(0, 1)
plt.ylabel('准确率')'不同模型准确率对比')
plt.grid(axis='y', alpha=0.3)
# 添加数值标签
for bar, acc in zip(bars, accuracies):
plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
f'{acc:.2%}', ha='center', va='bottom')
plt.tight_layout()
plt.show()
结果可视化
# 可视化预测结果与实际结果对比
def visualize_results(y_true, y_pred):
from sklearn.metrics import confusion_matrix
plt.figure(figsize=(15, 5))
# 混淆矩阵
plt.subplot(1, 3, 1)
cm = confusion_matrix(y_true, y_pred, labels=['胜', '平', '负'])
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('混淆矩阵')
plt.xlabel('预测结果')
plt.ylabel('实际结果')
# 结果分布对比
plt.subplot(1, 3, 2)
actual_dist = pd.Series(y_true).value_counts(normalize=True)
pred_dist = pd.Series(y_pred).value_counts(normalize=True)
data = pd.DataFrame({
'实际结果': actual_dist,
'预测结果': pred_dist
}).fillna(0)
data.plot(kind='bar', ax=plt.gca())
plt.title('结果分布对比')
plt.xlabel('比赛结果')
plt.ylabel('比例')
plt.legend()
# 累计命中率
plt.subplot(1, 3, 3)
correct = [1 if y_true[i] == y_pred[i] else 0 for i in range(len(y_true))]
cumulative = np.cumsum(correct) / np.arange(1, len(correct)+1)
plt.plot(cumulative)
plt.title('累计命中率')
plt.xlabel('预测序号')
plt.ylabel('命中率')
plt.tight_layout()
plt.show()
visualize_results(y_test, y_pred_rf)
保存模型与部署
import joblib
# 保存模型和缩放器
joblib.dump(rf_model, 'football_prediction_model.joblib')
joblib.dump(scaler, 'scaler.joblib')
# 创建预测函数(用于生产环境)
def make_prediction(model_file, scaler_file, match_features):
"""
从文件中加载模型并进行预测
"""
model = joblib.load(model_file)
scaler = joblib.load(scaler_file)
features_scaled = scaler.transform([match_features])
prediction = model.predict(features_scaled)
probabilities = model.predict_proba(features_scaled)
return prediction[0], {model.classes_[i]: probabilities[0][i]
for i in range(len(model.classes_))}
print("\n模型保存成功!可用于生产环境的预测服务")
关键要点
- 数据质量:友谊赛数据可能不完整,需要做好清洗
- 特征工程:组合特征(如进球差)比单一特征更有预测力
- 模型选择:随机森林表现稳定,适合分类问题;XGBoost可能更精确
- 过拟合防范:使用训练/测试集划分,观察训练和测试准确率差距
- 实际应用:结果不是绝对,可作为决策参考
优化建议
- 加入更多特征:球队历史交锋、核心球员状态、教练战术影响
- 使用交叉验证获取更稳定的评估
- 考虑时间权重:近期数据权重更大
- 尝试集成学习或深度学习模型(如LSTM处理时间序列)
预测只是辅助工具,比赛中还有诸多不确定因素,这个Python案例分析可以帮助你深入理解数据预测的完整流程!