判断上半场是否有进球的案例分析
问题理解
这是一个典型的分类预测问题:根据比赛数据(如球队实力、历史交锋、盘口等),预测上半场是否会产生进球(0-0 还是 ≥1 球)。

下面给出一个完整的 Python 案例,包含数据模拟、特征工程、模型训练和预测。
完整代码案例
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, accuracy_score, roc_auc_score
from sklearn.preprocessing import StandardScaler
# ========== 1. 模拟数据 ==========
np.random.seed(42)
n = 1000
data = pd.DataFrame({
"home_rank": np.random.randint(1, 20, n), # 主队排名
"away_rank": np.random.randint(1, 20, n), # 客队排名
"home_avg_goals_1h": np.random.uniform(0.2, 1.2, n), # 主队上半场场均进球
"away_avg_goals_1h": np.random.uniform(0.2, 1.2, n), # 客队上半场场均进球
"home_conceded_1h": np.random.uniform(0.2, 1.2, n), # 主队上半场场均失球
"away_conceded_1h": np.random.uniform(0.2, 1.2, n), # 客队上半场场均失球
"handicap": np.random.choice([-1, -0.75, -0.5, -0.25, 0, 0.25, 0.5], n), # 亚盘
"over_under_1h": np.random.choice([0.5, 0.75, 1.0, 1.25], n), # 上半场大小球盘
})
# ========== 2. 构造标签:上半场是否有进球 ==========
# 上半场进球数服从泊松分布,λ 由球队进攻/防守能力决定
lam = (data["home_avg_goals_1h"] + data["away_avg_goals_1h"] +
data["home_conceded_1h"] * 0.3 + data["away_conceded_1h"] * 0.3) / 2
data["goals_1h"] = np.random.poisson(lam)
data["has_goal_1h"] = (data["goals_1h"] > 0).astype(int) # 1=有进球, 0=无进球
print("标签分布:")
print(data["has_goal_1h"].value_counts(normalize=True))
# ========== 3. 特征与标签 ==========
features = ["home_rank", "away_rank", "home_avg_goals_1h", "away_avg_goals_1h",
"home_conceded_1h", "away_conceded_1h", "handicap", "over_under_1h"]
X = data[features]
y = data["has_goal_1h"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# ========== 4. 训练模型 ==========
model = RandomForestClassifier(
n_estimators=200,
max_depth=6,
random_state=42,
class_weight="balanced"
)
model.fit(X_train, y_train)
# ========== 5. 评估 ==========
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]
print("\n准确率:", accuracy_score(y_test, y_pred))
print("AUC :", roc_auc_score(y_test, y_prob))
print("\n分类报告:\n", classification_report(y_test, y_pred))
# ========== 6. 特征重要性 ==========
importance = pd.Series(model.feature_importances_, index=features).sort_values(ascending=False)
print("\n特征重要性:\n", importance)
# ========== 7. 预测一场新比赛 ==========
new_match = pd.DataFrame([{
"home_rank": 3,
"away_rank": 15,
"home_avg_goals_1h": 0.9,
"away_avg_goals_1h": 0.4,
"home_conceded_1h": 0.3,
"away_conceded_1h": 0.8,
"handicap": -0.75,
"over_under_1h": 1.0,
}])
prob = model.predict_proba(new_match)[0, 1]
print(f"\n新比赛上半场有进球的概率: {prob:.2%}")
print("预测结论:", "✅ 上半场有进球" if prob > 0.5 else "❌ 上半场无进球")
关键思路解析
为什么用分类模型?
- 目标是判断 "有/无进球"(二分类)
- 相比回归预测具体进球数,二分类更稳健,也符合"是否有进球"的问题本质
核心特征
| 类别 | 特征 | 说明 |
|---|---|---|
| 实力 | 主客队排名 | 强队更容易进球 |
| 进攻 | 上半场场均进球 | 直接相关 |
| 防守 | 上半场场均失球 | 防守弱易进球 |
| 盘口 | 亚盘、上半场大小球 | 市场预期信息 |
数据来源建议(真实场景)
- 历史比赛数据:
football-data.org、com、懂球帝 API - 盘口数据:各博彩公司赔率历史
- 实时抓取:
requests+BeautifulSoup或Selenium
模型优化方向
- 加入 泊松回归 估计λ,再算
P(无进球) = e^(-λ) - 加入 XGBoost / LightGBM 提升效果
- 用 时间序列划分 防止数据泄漏
- 增加 Elo 评分、近期状态等特征
泊松分布解法(更专业)
若已有历史数据,可用泊松模型直接计算无进球概率:
from scipy.stats import poisson
# 假设主队上半场期望进球 0.7,客队 0.5
lam_home, lam_away = 0.7, 0.5
# P(总进球 = 0) = P(主=0) * P(客=0)
p_no_goal = poisson.pmf(0, lam_home) * poisson.pmf(0, lam_away)
print(f"上半场无进球概率: {p_no_goal:.2%}")
print(f"上半场有进球概率: {1 - p_no_goal:.2%}")
输出示例:
上半场无进球概率: 30.12%
上半场有进球概率: 69.88%
| 步骤 | |
|---|---|
| ① 数据 | 收集历史半场比分 + 球队统计 + 盘口 |
| ② 标签 | has_goal_1h = goals_1h > 0 |
| ③ 训练 | RandomForest / XGBoost 二分类 |
| ④ 预测 | 输出概率,与 0.5 比较或用泊松分布 |
| ⑤ 应用 | 结合盘口判断投注价值 |
如果你有真实的比赛数据集,我可以帮你换成真实数据跑一遍,需要的话告诉我数据字段格式即可 👍