python案例认为上半场会否互交白卷?

wen python案例 1

Python案例分析:预测上半场会否互交白卷

下面我用一个完整的Python案例,演示如何用历史数据 + 机器学习来预测足球比赛"上半场是否互交白卷(0-0)"。

python案例认为上半场会否互交白卷?

问题定义

  • 目标变量HT_0_0(1=上半场0-0,0=上半场有进球)
  • 输入特征:两队近期进攻/防守数据、联赛类型等
  • 模型:逻辑回归 / 梯度提升树(XGBoost)

完整代码示例

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import (classification_report, roc_auc_score,
                             confusion_matrix, roc_curve)
import matplotlib.pyplot as plt
# ========== 1. 模拟数据(实际用真实赛果数据) ==========
np.random.seed(42)
n = 3000
df = pd.DataFrame({
    # 主队近5场场均进球
    'home_goals_avg': np.random.gamma(2, 0.7, n),
    # 客队近5场场均进球
    'away_goals_avg': np.random.gamma(2, 0.6, n),
    # 主队近5场场均失球
    'home_conceded_avg': np.random.gamma(1.5, 0.6, n),
    # 客队近5场场均失球
    'away_conceded_avg': np.random.gamma(1.5, 0.6, n),
    # 主队近5场场均上半场进球
    'home_ht_goals_avg': np.random.gamma(1.2, 0.4, n),
    # 客队近5场场均上半场进球
    'away_ht_goals_avg': np.random.gamma(1.2, 0.35, n),
    # 联赛平均上半场进球(如意甲偏低、荷甲偏高)
    'league_ht_avg': np.random.uniform(0.7, 1.5, n),
    # 是否为德比 / 强强对话(1=是)
    'is_big_match': np.random.binomial(1, 0.15, n),
})
# 用逻辑函数生成标签,让数据有可学习的规律
logit = (
    1.8
    - 2.6 * df['home_ht_goals_avg']
    - 2.4 * df['away_ht_goals_avg']
    - 0.6 * df['home_goals_avg']
    - 0.5 * df['away_goals_avg']
    + 0.9 * (df['league_ht_avg'] < 1.0)        # 低进球联赛
    + 0.7 * df['is_big_match']                  # 强强对话更谨慎
    + np.random.normal(0, 0.6, n)               # 噪声
)
prob = 1 / (1 + np.exp(-logit))
df['HT_0_0'] = np.random.binomial(1, prob)
print("互交白卷比例:", df['HT_0_0'].mean().round(3))
# ========== 2. 划分训练/测试集 ==========
X = df.drop(columns='HT_0_0')
y = df['HT_0_0']
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)
scaler = StandardScaler().fit(X_train)
X_train_s = scaler.transform(X_train)
X_test_s = scaler.transform(X_test)
# ========== 3. 模型训练 ==========
# 逻辑回归(可解释性强)
lr = LogisticRegression(max_iter=1000)
lr.fit(X_train_s, y_train)
# 梯度提升树(效果通常更好)
gb = GradientBoostingClassifier(n_estimators=200, learning_rate=0.05,
                                max_depth=3, random_state=42)
gb.fit(X_train, y_train)
# ========== 4. 评估 ==========
for name, model, Xt in [('LogReg', lr, X_test_s), ('GBDT', gb, X_test)]:
    proba = model.predict_proba(Xt)[:, 1]
    pred = (proba >= 0.5).astype(int)
    print(f"\n=== {name} ===")
    print("AUC:", round(roc_auc_score(y_test, proba), 4))
    print(classification_report(y_test, pred, digits=3))
    print("混淆矩阵:\n", confusion_matrix(y_test, pred))
# ========== 5. 特征重要性(业务解释) ==========
imp = pd.Series(gb.feature_importances_, index=X.columns).sort_values(ascending=False)
print("\n特征重要性:\n", imp.round(3))
# ========== 6. 单场比赛预测示例 ==========
match = pd.DataFrame([{
    'home_goals_avg': 1.6,
    'away_goals_avg': 1.1,
    'home_conceded_avg': 0.9,
    'away_conceded_avg': 1.0,
    'home_ht_goals_avg': 0.7,
    'away_ht_goals_avg': 0.4,
    'league_ht_avg': 0.9,     # 低进球联赛
    'is_big_match': 1,
}])
p = gb.predict_proba(match)[0, 1]
print(f"\n本场互交白卷概率:{p:.1%}")
print("判定:", "✅ 倾向0-0" if p > 0.5 else "❌ 上半场会有进球")
# ========== 7. ROC曲线可视化 ==========
fpr, tpr, _ = roc_curve(y_test, gb.predict_proba(X_test)[:, 1])
plt.figure(figsize=(6,5))
plt.plot(fpr, tpr, label=f'GBDT (AUC={roc_auc_score(y_test, gb.predict_proba(X_test)[:,1]):.3f})')
plt.plot([0,1],[0,1],'--',color='gray')
plt.xlabel('False Positive Rate'); plt.ylabel('True Positive Rate')'上半场互交白卷预测 - ROC')
plt.legend(); plt.tight_layout(); plt.show()

运行结果示例

互交白卷比例: 0.318
=== GBDT ===
AUC: 0.832
              precision    recall  f1-score   support
           0      0.808     0.901     0.852       512
           1      0.734     0.564     0.638       238
特征重要性:
 home_ht_goals_avg     0.312
 away_ht_goals_avg     0.287
 league_ht_avg         0.148
 home_goals_avg        0.091
 away_goals_avg        0.077
 is_big_match          0.048
 home_conceded_avg     0.021
 away_conceded_avg     0.016
本场互交白卷概率:63.4%
判定:✅ 倾向0-0

关键业务洞察

因素 对"互交白卷"的影响
两队近5场上半场进球均值 越低,越容易0-0(最强特征)
联赛类型 意甲/法乙/低级别联赛 > 荷甲/德甲
强强对话 / 德比 上半场更保守,0-0概率↑
总进球预期值 若全场大小球盘口 ≤ 2.25,0-0概率显著升高
主客场形势 保级战、无欲无求的比赛0-0更多

实战建议

  1. 数据来源

    • 免费:football-data.co.uk(欧洲各大联赛CSV)
    • 专业:Opta、SofaScore API、Flashscore
  2. 特征工程可深挖

    • 两队近5场上半场得失球(比全场均值更关键)
    • 上半场大小球盘口(博彩公司隐含概率)
    • 主帅风格(如穆里尼奥 vs 克洛普)
    • 天气、休息天数、主裁判场均进球
  3. 模型选择

    • 想要概率校准→ 逻辑回归 + 校准曲线
    • 想要精度→ XGBoost / LightGBM + 贝叶斯超参搜索
    • 想要不确定性→ 贝叶斯逻辑回归
  4. 注意数据泄漏:生成特征时只能用比赛当天之前的数据。

  5. 下注视角:即使模型给出63%的0-0概率,也要对比博彩公司赔率隐含概率,只有当 p_model > p_market 时才有价值。


如果你有真实赛果数据(CSV/Excel),我可以帮你改成直接读取并对接你手上的字段,告诉我文件格式即可。

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