跳到主要内容
DA DataAlgorithm Data & Algorithms
Methods Poisson Reproducible M-01

泊松比分模型的低分区偏差:Dixon-Coles 修正为何仍不够

Abstract · 摘要 独立泊松模型是足球比分预测的事实基线,但它假设主客队进球数相互独立—— 这个假设在低分比分区间存在公认的系统性偏差:平局被低估,一球分差被高估。 本文完整推导 Dixon-Coles 提出的 τ 相关性修正项, 解释它为何只能作用于四个低分格点、为何这组系数是"保持归一"约束下的唯一解, 以及 ρ 的可行域边界为何是最常见的实现 bug 来源。 文中给出 40 行内的标准库实现并实算修正效果:平局概率提升约 1.1 个百分点。 最后论证 τ 修正是一个方向正确但不充分的局部补丁—— 它修的是症状,不是独立性假设本身。
EZCAI DataAlgorithm 约 18 分钟阅读 可复现实现

问题设定:独立泊松基线

设一场比赛主队进球数为 X,客队进球数为 Y。 最常用的建模方式是假定两者服从相互独立的泊松分布,参数分别为 λ(主队期望进球)与 μ(客队期望进球)。

Definition 1 · 独立泊松比分模型

对任意非负整数 xy,比分 xy 的概率为两个边缘泊松概率之积。 该模型有两个自由参数,且完全由 λμ 决定整张比分概率表。

P(X=x,Y=y) = λxeλx! μyeμy!
(1)

式 (1) 的吸引力在于计算成本极低:一旦估出 λμ, 胜平负概率、大小球概率、任意比分概率都可由同一张表求和得到,无需额外建模。

λμ 通常由球队攻防强度参数与主场优势项构成。 本文不讨论强度估计(留待 M‑02 讨论 Elo 与分层贝叶斯方案), 而是直接检验式 (1) 的结构假设是否成立。

偏差量化:低分区被系统性低估

独立性假设意味着已知主队进球数不改变客队进球数的分布。 但足球比赛的真实动态并非如此:比分僵持时双方倾向收缩防守, 一方领先时另一方压上又会同时提高双方进球机会。 这种耦合在低分格点上留下了可测量的痕迹。

文献中反复报告的模式是:独立泊松低估平局(尤其 0‑0 与 1‑1), 同时高估一球分差(1‑0 与 0‑1)。 若这一模式为真,一个只作用于这四个格点的修正项就应当能把概率质量从后者搬向前者。 下表用世界杯典型参数(λ = 1.45、μ = 1.25) 实算修正前后的概率变化,验证修正方向是否符合预期:

Table 1  修正项对各格点的实际作用方向 (λ=1.45, μ=1.25, ρ=−0.045,由本文代码实算)
比分 独立泊松 τ 修正后 相对变化 作用
0‑00.06720.0727+8.2%提升平局
1‑10.12180.1273+4.5%提升平局
1‑00.09750.0920−5.6%压低一球差
0‑10.08400.0785−6.5%压低一球差
2‑10.08830.08830.0%不受影响
2‑00.07070.07070.0%不受影响

表 1 确认了修正的局部性:只有 x ≤ 1 且 y ≤ 1 的四个格点发生变化, 2‑1 与 2‑0 完全不动。聚合到胜平负层面,平局概率从 0.2567 升至 0.2677 (+1.1 个百分点),主客胜各让出约 0.55 个百分点。 ρ = −0.045 是文献常报的量级,实际应用中应由极大似然在历史数据上估计。

Caveat · 本文数值口径

表 1 是模型对模型的对比,展示修正项的数学作用,可由本文第 4 节代码完整复现。 它不是与实际比分频率的拟合优度检验—— 后者需要数千场历史样本才能让单格点频率的标准误降到可用水平, 72 场赛程远远不够。因此本文只主张修正方向正确,不主张 ρ = −0.045 是最优值。

Dixon-Coles 的 τ 相关性修正

修正思路不改变边缘分布,只在低分格点上乘一个偏离因子。 这是一个刻意保守的设计:它承认独立泊松在高分区表现良好, 只在证据表明失效的地方做局部干预。

Theorem 1 · Dixon-Coles 修正形式

引入依赖参数 ρ,定义修正因子 τ(x, y) 仅在 x ≤ 1 且 y ≤ 1 时偏离 1, 则修正后联合概率如式 (2)。当 ρ = 0 时模型退化为独立泊松。

P(X=x,Y=y) = τ(x,y;ρ) λxeλx! μyeμy!
(2)

τ 的四个取值: τ(0,0) = 1 − λμρτ(0,1) = 1 + λρτ(1,0) = 1 + μρτ(1,1) = 1 − ρ。 其余所有格点 τ = 1。

注意符号:ρ < 0 时, τ(0,0) 与 τ(1,1) 大于 1(提升平局概率), 而 τ(0,1) 与 τ(1,0) 小于 1(压低一球分差概率)。 这正是表 1 所要求的修正方向。

Proof Sketch · 概率和为 1 的验证

四个修正项的净增量之和为 λμρλρμρ + ρ 乘以各自的泊松权重。代入边缘概率并展开,交叉项恰好两两相消, 总和仍为 1。这解释了为何 τ 必须取这组特定系数—— 它不是任意选的偏离函数,而是在"只动四格且保持归一"约束下的解。

Constraint · 参数可行域

τ 必须非负,否则会出现负概率。 这给出约束 max(−1/λ, −1/μ) ≤ ρ ≤ min(1, 1/(λμ))。 实现时若不施加此约束,优化器在高 λμ 的比赛上会直接产出非法概率表—— 这是最常见的实现 bug。

实现:40 行内的可复现版本

下面给出式 (2) 的最小实现。仅依赖标准库,无需 NumPy, 目的是让读者能逐行核对推导与代码的对应关系。

Python 3.11 dixon_coles.py · 标准库实现
from math import exp, factorial

def poisson_pmf(k, lam):
    """边缘泊松概率质量函数。"""
    return lam ** k * exp(-lam) / factorial(k)

def tau(x, y, lam, mu, rho):
    """Dixon-Coles 修正因子,仅在 x,y <= 1 的四格偏离 1。"""
    if x == 0 and y == 0:
        return 1.0 - lam * mu * rho
    if x == 0 and y == 1:
        return 1.0 + lam * rho
    if x == 1 and y == 0:
        return 1.0 + mu * rho
    if x == 1 and y == 1:
        return 1.0 - rho
    return 1.0

def rho_bounds(lam, mu):
    """rho 的可行域,越界会产生负概率。"""
    lo = max(-1.0 / lam, -1.0 / mu)
    hi = min(1.0, 1.0 / (lam * mu))
    return lo, hi

def score_matrix(lam, mu, rho=0.0, max_goals=8):
    """返回 (max_goals+1) x (max_goals+1) 的比分概率表。"""
    lo, hi = rho_bounds(lam, mu)
    if not (lo <= rho <= hi):
        raise ValueError(f"rho={rho} 越界,可行域 [{lo:.4f}, {hi:.4f}]")
    grid = [
        [tau(x, y, lam, mu, rho) * poisson_pmf(x, lam) * poisson_pmf(y, mu)
         for y in range(max_goals + 1)]
        for x in range(max_goals + 1)
    ]
    total = sum(map(sum, grid))          # 截断到 max_goals 会丢失尾部质量
    return [[c / total for c in row] for row in grid]

def outcome_probs(grid):
    """从比分表聚合胜/平/负概率。"""
    home = sum(grid[x][y] for x in range(len(grid)) for y in range(x))
    draw = sum(grid[i][i] for i in range(len(grid)))
    return {"home": home, "draw": draw, "away": 1.0 - home - draw}
Pitfall · 归一化不是可选步骤

score_matrix 中的 total 重归一化很容易被省略, 但把比分截断在 8 球会丢掉约 0.02% 的概率质量。 省略后所有下游概率都带一个小的系统性低估, 在 Brier 分数这种平方损失上会被放大。

结论:修正了症状,没修假设

τ 修正是一个工程上极为划算的改动: 两行条件判断、一个参数,就能把平局概率拉回合理区间。 但它的局限同样明确——它没有解释为什么低分区会相关, 只是在观察到偏差的地方贴了一块补丁。

真正的问题在于独立泊松把一场 90 分钟的动态博弈压缩成两个静态参数。 比赛中的进球强度并非常数:它随比分、时间、红牌、换人而变化。 任何只在最终比分层面做修正的方案,都无法捕捉这种时变结构。 更根本的路线是对进球强度过程本身建模——这将是 M‑04 的主题。

Key Takeaways · 要点回顾
  1. 独立泊松的偏差是结构性的,不是抽样噪声:平局低估、一球分差高估,方向稳定。
  2. τ 的四个系数不是随意选的,而是"只动四格 + 保持归一"约束下的唯一解。
  3. ρ 必须约束在可行域内,否则会产出负概率——这是最常见的实现 bug。
  4. 截断比分表后必须重归一化,否则引入系统性低估,在平方损失上被放大。
  5. 修正只作用于最终比分层面,无法捕捉进球强度的时变结构,因此是补丁而非解法。

参考与延伸

  • [1] Dixon, M. J., & Coles, S. G. (1997). Modelling Association Football Scores and Inefficiencies in the Football Betting Market. Journal of the Royal Statistical Society: Series C, 46(2), 265–280. — τ 修正的原始出处。
  • [2] Maher, M. J. (1982). Modelling Association Football Scores. Statistica Neerlandica, 36(3), 109–118. — 攻防强度参数化的奠基工作。
  • [3] Karlis, D., & Ntzoufras, I. (2003). Analysis of Sports Data by Using Bivariate Poisson Models. Journal of the Royal Statistical Society: Series D, 52(3), 381–393. — 双变量泊松:用共享成分显式建模相关性,与 τ 修正互为替代方案。
  • [4] Brier, G. W. (1950). Verification of Forecasts Expressed in Terms of Probability. Monthly Weather Review, 78(1), 1–3. — 本文评估口径的来源。

免责声明:本文为数据科学方法论研究笔记,所有概率估计均带有不确定性, 不构成任何形式的投注建议或投资建议。