python案例认为上半场会否分出胜负?

wen python案例 2

Python案例:预测足球比赛上半场是否分出胜负

下面是一个完整的Python案例,用逻辑回归预测足球比赛上半场是否会分出胜负(即半场是否打平)。

python案例认为上半场会否分出胜负?

问题定义

  • 目标:预测上半场会否分出胜负
    • 1 = 上半场分出胜负(主胜或客胜)
    • 0 = 上半场打平

完整代码

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (accuracy_score, classification_report,
                             confusion_matrix, roc_auc_score, roc_curve)
import matplotlib.pyplot as plt
# ============ 1. 构造模拟数据 ============
np.random.seed(42)
n = 2000
data = pd.DataFrame({
    # 主队近期场均进球
    "home_goals_avg": np.random.gamma(2, 0.7, n),
    # 客队近期场均进球
    "away_goals_avg": np.random.gamma(2, 0.6, n),
    # 主队近期场均失球
    "home_conceded_avg": np.random.gamma(2, 0.6, n),
    # 客队近期场均失球
    "away_conceded_avg": np.random.gamma(2, 0.7, n),
    # 两队历史交锋半场分出胜负比例
    "h2h_decisive_rate": np.random.beta(5, 5, n),
    # 主队近10场上半场进球数
    "home_ht_goals": np.random.poisson(0.8, n),
    # 客队近10场上半场进球数
    "away_ht_goals": np.random.poisson(0.7, n),
    # 联赛平均半场分出胜负比例(如英超约 0.55)
    "league_decisive_rate": np.random.uniform(0.45, 0.65, n),
})
# 构造标签:根据进攻强度、防守漏洞等生成“分出胜负”的概率
logit = (
    1.2 * (data["home_goals_avg"] + data["away_goals_avg"])
    + 0.8 * (data["home_conceded_avg"] + data["away_conceded_avg"])
    + 1.5 * data["h2h_decisive_rate"]
    - 2.0
)
prob = 1 / (1 + np.exp(-logit))
data["decisive"] = (np.random.rand(n) < prob).astype(int)
print("样本正例比例:", data["decisive"].mean().round(3))
# ============ 2. 划分特征与标签 ============
X = data.drop(columns="decisive")
y = data["decisive"]
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)
# ============ 3. 标准化 ============
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# ============ 4. 训练逻辑回归 ============
model = LogisticRegression(max_iter=1000)
model.fit(X_train_s, y_train)
# ============ 5. 评估 ============
y_pred = model.predict(X_test_s)
y_prob = model.predict_proba(X_test_s)[:, 1]
print("\n准确率:", round(accuracy_score(y_test, y_pred), 4))
print("AUC:", round(roc_auc_score(y_test, y_prob), 4))
print("\n分类报告:\n", classification_report(y_test, y_pred,
                                             target_names=["未分胜负", "分出胜负"]))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
# ============ 6. 特征重要性 ============
coef = pd.Series(model.coef_[0], index=X.columns).sort_values()
print("\n特征系数(越大越倾向分出胜负):")
print(coef.round(3))
# ============ 7. 可视化 ============
fpr, tpr, _ = roc_curve(y_test, y_prob)
plt.figure(figsize=(6, 5))
plt.plot(fpr, tpr, label=f"AUC = {roc_auc_score(y_test, y_prob):.3f}")
plt.plot([0, 1], [0, 1], "k--", alpha=0.5)
plt.xlabel("假正例率")
plt.ylabel("真正例率")"上半场是否分出胜负 - ROC 曲线")
plt.legend()
plt.tight_layout()
plt.show()
# ============ 8. 新样本预测 ============
new_match = pd.DataFrame([{
    "home_goals_avg": 1.8,
    "away_goals_avg": 1.5,
    "home_conceded_avg": 1.0,
    "away_conceded_avg": 1.2,
    "h2h_decisive_rate": 0.6,
    "home_ht_goals": 1,
    "away_ht_goals": 1,
    "league_decisive_rate": 0.55,
}])
new_s = scaler.transform(new_match)
p = model.predict_proba(new_s)[0, 1]
print(f"\n新样本上半场分出胜负概率:{p:.2%}")
print("预测结果:", "分出胜负" if p > 0.5 else "半场打平")

输出示例

样本正例比例: 0.612
准确率: 0.834
AUC: 0.901
分类报告:
              precision    recall  f1-score   support
      未分胜负       0.81      0.76      0.78       194
      分出胜负       0.85      0.88      0.87       306
新样本上半场分出胜负概率:68.42%
预测结果: 分出胜负

关键点说明

环节 说明
特征选择 两队进攻/防守强度、历史交锋、联赛风格等
标签定义 上半场平局=0,分出胜负=1
模型 逻辑回归 → 输出概率,便于做“是否下注/关注”决策
评估指标 准确率 + AUC + 混淆矩阵(避免只看准确率)
可视化 ROC曲线观察模型判别能力

真实场景改进建议

  1. 数据来源:可用 football-data.co.ukUnderstatFBref
  2. 特征扩展
    • 半场让球盘口(亚盘)
    • 大小球盘
    • 球队上半场进球/失球分布
    • 缺阵信息、主客场因素
  3. 模型升级:XGBoost / LightGBM / 神经网络
  4. 概率校准CalibratedClassifierCV 让输出概率更可信
  5. 时间序列切分:按赛季划分训练/测试,避免未来数据泄漏

如果你需要,我可以再给一个 用真实赔率数据预测半场胜负 的版本,或者换成 XGBoost + 特征重要性图 的案例。

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