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

wen python案例 4

足球比赛上半场胜负预测案例

这是一个典型的二分类预测问题,我用 Python 构建一个完整案例,演示如何预测上半场是否分出胜负(即上半场是否有进球导致比分不同)。

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

完整代码案例

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
from sklearn.preprocessing import StandardScaler
# ========== 1. 构造模拟数据 ==========
np.random.seed(42)
n = 2000
data = pd.DataFrame({
    # 主队上半场平均进球能力
    'home_goals_1h_avg': np.random.poisson(0.7, n),
    # 客队上半场平均进球能力
    'away_goals_1h_avg': np.random.poisson(0.5, n),
    # 主队近期上半场进球率
    'home_1h_scoring_rate': np.random.uniform(0, 1, n),
    # 客队近期上半场进球率
    'away_1h_scoring_rate': np.random.uniform(0, 1, n),
    # 两队上半场失球率
    'home_1h_concede_rate': np.random.uniform(0, 1, n),
    'away_1h_concede_rate': np.random.uniform(0, 1, n),
    # 主队上半场控球率
    'home_possession': np.random.uniform(0.35, 0.65, n),
    # 历史交锋上半场分出胜负比例
    'h2h_1h_decided_rate': np.random.uniform(0.2, 0.8, n),
    # 联赛平均上半场进球数
    'league_1h_goals': np.random.uniform(0.8, 1.5, n),
})
# 生成标签(模拟真实规律):上半场是否分出胜负
# 逻辑:进球能力越强、交锋历史越容易分出胜负,概率越高
logit = (
    1.5 * data['home_goals_1h_avg']
    + 1.2 * data['away_goals_1h_avg']
    + 1.0 * data['h2h_1h_decided_rate']
    + 0.8 * (data['home_1h_scoring_rate'] + data['away_1h_scoring_rate'])
    + 0.5 * data['league_1h_goals']
    - 4.5
)
prob = 1 / (1 + np.exp(-logit))
data['y'] = (np.random.rand(n) < prob).astype(int)  # 1=分出胜负, 0=平局
print("标签分布:")
print(data['y'].value_counts(normalize=True))
# ========== 2. 划分数据 ==========
X = data.drop('y', axis=1)
y = data['y']
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)
lr = LogisticRegression(max_iter=1000)
lr.fit(X_train_s, y_train)
y_pred_lr = lr.predict(X_test_s)
y_prob_lr = lr.predict_proba(X_test_s)[:, 1]
print("\n===== 逻辑回归 =====")
print(classification_report(y_test, y_pred_lr))
print("AUC:", round(roc_auc_score(y_test, y_prob_lr), 4))
# ========== 4. 随机森林模型 ==========
rf = RandomForestClassifier(n_estimators=300, max_depth=8, random_state=42)
rf.fit(X_train, y_train)
y_pred_rf = rf.predict(X_test)
y_prob_rf = rf.predict_proba(X_test)[:, 1]
print("\n===== 随机森林 =====")
print(classification_report(y_test, y_pred_rf))
print("AUC:", round(roc_auc_score(y_test, y_prob_rf), 4))
# ========== 5. 特征重要性 ==========
imp = pd.Series(rf.feature_importances_, index=X.columns).sort_values(ascending=False)
print("\n特征重要性:")
print(imp)
# ========== 6. 混淆矩阵 ==========
print("\n混淆矩阵 (0=平局, 1=分出胜负):")
print(confusion_matrix(y_test, y_pred_rf))

关键设计思路

问题定义

  • 正类 (1):上半场分出胜负(包括主队领先或客队领先)
  • 负类 (0):上半场平局(0:0 或 1:1 等)

核心特征

类别 特征示例
球队进攻 上半场平均进球、近期半场进球率
球队防守 半场失球率、被进球概率
对阵特征 历史交锋半场分出胜负比例
联赛特征 联赛平均半场进球数
战术 控球率、射门转化率

模型选择

  • 逻辑回归:可解释性强,能输出概率
  • 随机森林 / XGBoost:处理非线性关系更好
  • AUC 指标比准确率更适合评估

实战注意事项

  1. 数据获取:可用 requests 爬取或调用 Football-Data.org、SportsMonk 等 API
  2. 类别不平衡:实际比赛中上半场平局占比约 40-50%,需用 class_weight='balanced'
  3. 时间序列切分:不能用随机划分,应按时

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