NBA Stern 模型 - 比赛胜率预测

📚 模型概述

Stern 模型是由哈佛大学统计学家 Hal S. Stern 在 1994 年提出的体育比赛预测模型,后来由 Nicholas G. Polson 和 Stern 在 2015 年进一步扩展。

核心论文

1. Stern (1994): "A Brownian Motion Model for the Progress of Sports Scores"

- 发表于: Journal of the American Statistical Association (JASA), Vol. 89, No. 427, pp. 1128-1134

2. Polson & Stern (2015): "The implied volatility of a sports game"

- 发表于: Journal of Quantitative Analysis in Sports, Vol. 11, No. 3

🧮 数学原理

布朗运动模型 (Brownian Motion Model)

Stern 模型将主队与客队的分差建模为一个布朗运动过程

$$X(t) \sim \text{Brownian Motion}$$

其中:

关键参数

参数含义说明
$\mu$漂移项 (Drift)主队相对于客队的预期分差优势
$\sigma^2$方差 (Variance)比赛分数的波动程度
$l$当前领先分数比赛进行到时间 $t$ 时,主队的实际领先分数

胜率计算公式

在比赛进行到时间 $t$,主队领先 $l$ 分时,主队获胜的概率为:

$$P(\text{主队获胜} | l, t) = \Phi\left(\frac{l + \mu(1-t)}{\sigma\sqrt{1-t}}\right)$$

其中 $\Phi(x)$ 是标准正态分布的累积分布函数 (CDF)

赛前胜率(简化公式)

比赛开始前($t = 0$,$l = 0$),主队获胜概率简化为:

$$P(\text{主队获胜}) = \Phi\left(\frac{\mu}{\sigma}\right)$$

📊 实际应用

1. 参数估计

实际使用中需要估计 $\mu$ 和 $\sigma$:

- 例如:Vegas 盘口的分差可以作为 $\mu$ 的估计

- NBA 比赛的典型 $\sigma$ 约为 11-12 分(整场比赛)

2. 比赛中实时更新

模型的强大之处在于可以实时计算胜率


示例:
- 比赛进行到第三节结束 (t = 0.75)
- 主队领先 8 分 (l = 8)
- 预期分差 μ = 3, 波动率 σ = 12

剩余时间方差 = σ² × (1-t) = 144 × 0.25 = 36
剩余时间标准差 = 6

z = (8 + 3×0.25) / 6 = (8 + 0.75) / 6 = 1.46

P(主队获胜) = Φ(1.46) ≈ 0.928 = 92.8%

3. 隐含波动率 (Implied Volatility)

Polson & Stern (2015) 扩展了模型,可以从博彩市场反推隐含波动率

💻 Python 实现示例


import numpy as np
from scipy.stats import norm

def stern_win_probability(lead: float, time_elapsed: float, 
                          mu: float, sigma: float) -> float:
    """
    计算 Stern 模型下的主队获胜概率
    
    参数:
    - lead: 主队当前领先分数 (可为负数表示落后)
    - time_elapsed: 比赛已进行时间比例 (0-1)
    - mu: 预期全场分差 (主队相对客队)
    - sigma: 全场分数波动率 (标准差)
    
    返回:
    - 主队获胜概率 (0-1)
    """
    if time_elapsed >= 1:
        return 1.0 if lead > 0 else (0.5 if lead == 0 else 0.0)
    
    remaining_time = 1 - time_elapsed
    z = (lead + mu * remaining_time) / (sigma * np.sqrt(remaining_time))
    
    return norm.cdf(z)


# 示例使用
if __name__ == "__main__":
    # NBA 典型参数
    sigma = 12  # NBA 整场比赛的典型波动率
    
    # 场景1: 赛前预测 (主队预期赢 5 分)
    print("赛前预测 (主队预期赢5分):")
    print(f"  主队胜率: {stern_win_probability(0, 0, mu=5, sigma=sigma):.1%}")
    
    # 场景2: 半场结束,主队领先 6 分
    print("\n半场结束 (主队领先6分, 预期分差3分):")
    print(f"  主队胜率: {stern_win_probability(6, 0.5, mu=3, sigma=sigma):.1%}")
    
    # 场景3: 第四节开始,主队落后 2 分
    print("\n第四节开始 (主队落后2分, 预期分差-1分):")
    print(f"  主队胜率: {stern_win_probability(-2, 0.75, mu=-1, sigma=sigma):.1%}")
    
    # 场景4: 最后 2 分钟,主队领先 5 分
    print("\n最后2分钟 (主队领先5分):")
    print(f"  主队胜率: {stern_win_probability(5, 0.958, mu=0, sigma=sigma):.1%}")

输出示例


赛前预测 (主队预期赢5分):
  主队胜率: 66.2%

半场结束 (主队领先6分, 预期分差3分):
  主队胜率: 74.8%

第四节开始 (主队落后2分, 预期分差-1分):
  主队胜率: 31.2%

最后2分钟 (主队领先5分):
  主队胜率: 97.9%

📈 模型优缺点

✅ 优点

1. 数学简洁: 基于布朗运动,公式简单优雅

2. 实时更新: 可在比赛任意时刻计算胜率

3. 可解释性强: 参数含义清晰

4. 计算高效: 只需要正态分布 CDF

⚠️ 局限性

1. 假设平稳性: 假设比分变化速率恒定,不考虑节奏变化

2. 忽略离散性: 真实比分是离散的,模型用连续过程近似

3. 不考虑战术: 领先/落后时策略变化不在模型中

4. 参数敏感: $\sigma$ 的估计对结果影响较大

📖 延伸阅读

1. 原始论文 (需要学术访问):

- JASA 1994 论文

- JQAS 2015 论文

2. 免费 PDF:

- Berkeley STAT 157 课程资料

3. 相关模型:

- FiveThirtyEight Elo 系统

- ESPN BPI (Basketball Power Index)

- 马尔可夫链模型 (Markov Chain for Basketball)

🔗 参考文献

文档创建日期: 2026-01-27

整理: 贾维斯 (Jarvis) 🤖