本文目录导读:

这是一个很有意思的问题,下面我用一个完整的Python案例分析来探讨“补时长短是否会影响进球概率”。
分析思路
核心问题:补时时间越长,进球概率是否越高?
需要区分两个概念:
- 补时长度 → 影响的是“补时阶段内的进球数”
- 进球概率 → 更准确地说,是“单位时间进球率”是否变化
关键陷阱:补时越长,进球数自然可能越多(时间更长),但这不代表“进球概率/速率”提高了,所以要比较的是每分钟进球率。
完整Python案例
import numpy as np
import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(42)
# ============================================
# 1. 构造模拟数据(也可替换为真实数据)
# ============================================
# 假设我们有 1000 场比赛,记录:补时分钟数、补时阶段进球数
n_matches = 1000
# 补时长度:常见 3-6 分钟,偶尔更长
stoppage_time = np.random.choice(
[2, 3, 4, 5, 6, 7, 8, 9, 10],
size=n_matches,
p=[0.05, 0.20, 0.30, 0.20, 0.12, 0.06, 0.04, 0.02, 0.01]
)
# 真实设定:补时阶段进球率约为 0.035 球/分钟(略高于常规时间)
# 关键:这里让进球率【不随补时长度变化】——即原假设成立
base_rate_per_min = 0.035
# 每场比赛补时阶段的期望进球数
expected_goals = stoppage_time * base_rate_per_min
goals_in_stoppage = np.random.poisson(expected_goals)
df = pd.DataFrame({
'stoppage_min': stoppage_time,
'goals': goals_in_stoppage
})
# ============================================
# 2. 描述性统计:按补时长度分组
# ============================================
summary = df.groupby('stoppage_min').agg(
n_matches=('goals', 'size'),
total_goals=('goals', 'sum'),
avg_goals=('goals', 'mean'),
goal_rate_per_min=('goals', lambda x: x.sum() /
(df.loc[x.index, 'stoppage_min'].sum()))
).reset_index()
print("=== 按补时长度分组统计 ===")
print(summary.to_string(index=False))
# ============================================
# 3. 核心检验:补时长度 vs 每分钟进球率
# ============================================
# 方法A:泊松回归(推荐)——检验补时长度对进球数的影响
# 若进球率恒定,则 goals ~ Poisson(β * stoppage_min),β 应显著
# 这里用简单的 rates 检验代替(无 statsmodels 时的近似)
# 计算每组的“每分钟进球率”
summary['rate'] = summary['total_goals'] / (summary['stoppage_min'] * summary['n_matches'])
print("\n=== 每分钟进球率(应大致恒定)===")
print(summary[['stoppage_min', 'rate']].to_string(index=False))
# 方法B:卡方/泊松检验——比较不同补时组的进球率
# 简化:用线性回归看 rate 是否随补时长度显著变化
slope, intercept, r_value, p_value, std_err = stats.linregress(
summary['stoppage_min'], summary['rate']
)
print(f"\n每分钟进球率 vs 补时长度 线性回归:")
print(f" 斜率 = {slope:.5f}, p值 = {p_value:.3f}")
print(f" → {'进球率随补时显著变化' if p_value < 0.05 else '无显著证据表明进球率随补时变化'}")
# ============================================
# 4. 可视化
# ============================================
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 左图:总进球数 vs 补时长度(会上升,因为时间更长)
axes[0].bar(summary['stoppage_min'], summary['avg_goals'], color='steelblue')
axes[0].set_xlabel('补时长度(分钟)')
axes[0].set_ylabel('平均进球数')
axes[0].set_title('补时越长,进球数越多(时间效应)')
# 右图:每分钟进球率 vs 补时长度(应大致平坦)
axes[1].plot(summary['stoppage_min'], summary['rate'], 'o-', color='crimson')
axes[1].axhline(base_rate_per_min, ls='--', color='gray', label='真实速率')
axes[1].set_xlabel('补时长度(分钟)')
axes[1].set_ylabel('每分钟进球率')
axes[1].set_title('每分钟进球率 vs 补时长度(应无趋势)')
axes[1].legend()
plt.tight_layout()
plt.savefig('stoppage_analysis.png', dpi=100)
plt.show()
关键结论与解读
运行后你会看到类似结果:
| 补时长度 | 平均进球数 | 每分钟进球率 |
|---|---|---|
| 2 分钟 | ~0.07 | ~0.035 |
| 5 分钟 | ~0.17 | ~0.035 |
| 10 分钟 | ~0.35 | ~0.035 |
核心发现:
- 补时越长,补时阶段总进球数越多 —— 这是显然的,因为时间更长(时间累积效应)。
- 但每分钟进球率基本恒定 —— 线性回归斜率不显著(p > 0.05),没有证据表明“补时长短会改变进球概率/速率”。
为什么容易产生“补时影响进球概率”的错觉?
- 选择性偏差:长补时往往出现在比分接近、有争议、有伤停的激烈比赛中,这类比赛本身进球动机更强。
- 幸存者偏差:补时阶段进球多的比赛被记住,形成“补时=进球多”的印象。
- 混淆“总数”与“速率”:把“进球数多”误读为“进球概率高”。
要得到真实结论,真实数据应如何做?
# 用 statsmodels 做泊松回归(offset = log(补时分钟))
import statsmodels.api as sm
import statsmodels.formula.api as smf
# goals ~ Poisson(exp(β0 + β1*stoppage_min)),offset 处理暴露时间
model = smf.glm('goals ~ stoppage_min', data=df,
family=sm.families.Poisson(),
offset=np.log(df['stoppage_min'])).fit()
print(model.summary())
# 若 stoppage_min 系数不显著 → 进球率不随补时长度变化
# 若显著为正 → 长补时比赛进球率更高(可能有战术/比赛状态因素)
同时应控制混杂变量:比分差距、比赛重要性、球队实力、主客场等。
在这个案例中,补时长短本身不会改变“每分钟进球概率”,它只通过“时间更长”增加了总进球数。 若真实数据中发现长补时进球率更高,更可能是比赛情境(比分胶着、激烈程度)导致的混杂,而非补时长度本身。
需要我把这个案例改成用真实比赛数据(比如某联赛赛季数据)来分析吗?