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

wen python案例 1

利用友谊赛数据做预测的Python案例

友谊赛数据预测是一个典型的机器学习问题,常见于足球、篮球等体育赛事预测,下面我给出一个完整的Python案例框架。

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

数据理解

友谊赛数据的特点:

  • 优点:提供额外的样本,尤其是国家队/球队间交手数据
  • 缺点:球队可能不全力出战、阵容轮换、动机不足,噪音大
  • 用途:作为常规赛事的补充特征,或用于冷启动(新球队/新赛季)

完整案例(足球比分预测)

数据准备

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score, classification_report
import matplotlib.pyplot as plt
# 假设数据格式:date, home_team, away_team, home_goals, away_goals, match_type
df = pd.read_csv('matches.csv', parse_dates=['date'])
df = df.sort_values('date').reset_index(drop=True)
print(df.head())

特征工程(核心)

友谊赛数据的关键是提取球队近期状态,但要用时间窗口避免数据泄漏。

def compute_team_form(df, team, current_date, window=10, match_types=None):
    """计算某球队在 current_date 之前的近 window 场表现"""
    mask = (
        ((df['home_team'] == team) | (df['away_team'] == team)) &
        (df['date'] < current_date)
    )
    if match_types:
        mask &= df['match_type'].isin(match_types)
    recent = df[mask].tail(window)
    if len(recent) == 0:
        return {'goals_for': 0, 'goals_against': 0, 'win_rate': 0, 'n': 0}
    gf, ga, wins = [], [], 0
    for _, row in recent.iterrows():
        if row['home_team'] == team:
            gf.append(row['home_goals']); ga.append(row['away_goals'])
            if row['home_goals'] > row['away_goals']: wins += 1
        else:
            gf.append(row['away_goals']); ga.append(row['home_goals'])
            if row['away_goals'] > row['home_goals']: wins += 1
    return {
        'goals_for': np.mean(gf),
        'goals_against': np.mean(ga),
        'win_rate': wins / len(recent),
        'n': len(recent)
    }
def build_features(df, friendly_weight=0.5):
    """构建特征:区分正式赛与友谊赛,友谊赛按权重衰减"""
    features = []
    for idx, row in df.iterrows():
        # 分别统计正式赛、友谊赛表现
        home_official = compute_team_form(df, row['home_team'], row['date'], 
                                          window=10, match_types=['official'])
        away_official = compute_team_form(df, row['away_team'], row['date'], 
                                          window=10, match_types=['official'])
        home_friendly = compute_team_form(df, row['home_team'], row['date'], 
                                          window=10, match_types=['friendly'])
        away_friendly = compute_team_form(df, row['away_team'], row['date'], 
                                          window=10, match_types=['friendly'])
        features.append({
            'home_gf_off': home_official['goals_for'],
            'home_ga_off': home_official['goals_against'],
            'home_wr_off': home_official['win_rate'],
            'away_gf_off': away_official['goals_for'],
            'away_ga_off': away_official['goals_against'],
            'away_wr_off': away_official['win_rate'],
            # 友谊赛数据加权(体现其参考价值较低)
            'home_gf_fr': home_friendly['goals_for'] * friendly_weight,
            'away_gf_fr': away_friendly['goals_for'] * friendly_weight,
            'is_friendly': 1 if row['match_type'] == 'friendly' else 0,
            # 关键特征:实力差
            'attack_diff': home_official['goals_for'] - away_official['goals_against'],
            'defense_diff': home_official['goals_against'] - away_official['goals_for'],
            'form_diff': home_official['win_rate'] - away_official['win_rate'],
        })
    return pd.DataFrame(features)
# 标签:主胜/平/客胜
df['result'] = np.where(df['home_goals'] > df['away_goals'], 2,
                np.where(df['home_goals'] == df['away_goals'], 1, 0))
X = build_features(df)
y = df['result']

模型训练(时间序列切分,避免未来数据泄漏)

# 按时间切分,前80%训练,后20%测试
split = int(len(df) * 0.8)
X_train, X_test = X.iloc[:split], X.iloc[split:]
y_train, y_test = y.iloc[:split], y.iloc[split:]
model = GradientBoostingClassifier(n_estimators=200, max_depth=4, 
                                    learning_rate=0.05, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("准确率:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred, 
                            target_names=['客胜', '平局', '主胜']))
# 特征重要性
imp = pd.Series(model.feature_importances_, index=X.columns).sort_values()
imp.plot(kind='barh', figsize=(8, 6))'特征重要性')
plt.tight_layout()
plt.show()

概率预测(可用于赔率对比)

proba = model.predict_proba(X_test)
# 输出每场比赛三个结果的概率
for i, p in enumerate(proba[:5]):
    print(f"比赛{i}: 客胜={p[0]:.2%}, 平={p[1]:.2%}, 主胜={p[2]:.2%}")

核心技巧总结

要点 说明
时间对齐 只能用比赛日期之前的数据计算球队状态
友谊赛折扣 给友谊赛特征乘以权重(如0.3~0.6),降低噪音
分类型统计 正式赛/友谊赛分开做特征,再融合
动机特征 加"是否临近大赛"等标志,捕捉友谊赛投入度
对手强度 用Elo评分修正对手质量:Elo变化 × 是否友谊赛
样本增广 友谊赛可扩大样本量,缓解冷启动

进阶方向

  1. 泊松回归预测比分:对进球数建模,友谊赛用小λ惩罚
  2. Elo体系融合:K因子对友谊赛设置更低(如20 vs 正式赛40)
  3. 深度学习:用LSTM序列建模球队近期轨迹
  4. 多任务学习:同时预测胜平负+进球数

如果你能提供具体数据格式(字段名)和预测目标(胜平负/比分/进球数),我可以给出针对性的完整代码。

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