5D Library › 概率判断、布莱尔分数校准与群体智慧的统计理论 · English

第二章 严格恰当评分规则:布莱尔分数与墨菲分解

一位气象学家的评分规则

1950 年,美国气象局的格伦·布莱尔在《每月天气评论》上发表了一篇只有三页的短文,提出用一个简单的数来检验概率预报 (Brier 1950)。设一共有 NN 次预报,每次有 rr 种可能的结局,预报者给第 jj 种结局的概率为 fijf_{ij},实际发生的结局记为 oij=1o_{ij} = 1,其余为 0:

P=1N∑i=1N∑j=1r(fij−oij)2P = \frac{1}{N}\sum_{i=1}^{N}\sum_{j=1}^{r}\left(f_{ij} – o_{ij}\right)^2

这是布莱尔的原始形式,取值在 0 到 2 之间。今天更常用的是二元事件的形式:只看「发生」这一种结局,

BS=1N∑i=1N(fi−oi)2,BS = \frac{1}{N}\sum_{i=1}^{N}\left(f_i – o_i\right)^2,

取值在 0 到 1 之间,等于原始形式的一半。第一章的三选一问题用的是原始形式,本章其余部分用二元形式。这个分数有一个后来被系统研究的好性质:预报者不能靠报出自己并不相信的概率来改善期望分数 (Gneiting and Raftery 2007)。本章后面一节证明这一点。

墨菲分解:校准、区分度与不确定性

1973 年,气象学家阿伦·墨菲把布莱尔分数拆成三部分 (Murphy 1973)。把预报按数值分成 KK 组(例如所有说 30% 的预报为一组),第 kk 组有 nkn_k 次预报,平均预报为 f‾k\bar f_k,其中事件实际发生的比例为 o‾k\bar o_k;全部预报中事件发生的比例为 o‾\bar o。则

BS=1N∑knk(f‾k−o‾k)2⏟REL−1N∑knk(o‾k−o‾)2⏟RES+o‾(1−o‾)⏟UNC.BS = \underbrace{\frac{1}{N}\sum_k n_k(\bar f_k – \bar o_k)^2}_{\text{REL}} \;-\; \underbrace{\frac{1}{N}\sum_k n_k(\bar o_k – \bar o)^2}_{\text{RES}} \;+\; \underbrace{\bar o(1 – \bar o)}_{\text{UNC}}.

  • 可靠性(REL,又称校准误差):说 30% 的事,是否大约三成发生。越小越好,完美校准时为 0。
  • 区分度(RES,又称分辨率):不同组的实际发生率离总体基础率有多远,也就是预报者能否把「较可能」与「较不可能」的事分开。越大越好。
  • 不确定性(UNC):只取决于事件本身的基础率,与预报者无关。

推导

推导。 在第 kk 组内,若每个预报都等于 f‾k\bar f_k,则 ∑i∈k(fi−oi)2=nk(f‾k−o‾k)2+∑i∈k(oi−o‾k)2\sum_{i \in k}(f_i – o_i)^2 = n_k(\bar f_k – \bar o_k)^2 + \sum_{i\in k}(o_i – \bar o_k)^2,后一项等于 nko‾k(1−o‾k)n_k\bar o_k(1 – \bar o_k);再利用 o‾(1−o‾)−1N∑knk(o‾k−o‾)2=1N∑knko‾k(1−o‾k)\bar o(1-\bar o) – \frac{1}{N}\sum_k n_k(\bar o_k – \bar o)^2 = \frac{1}{N}\sum_k n_k \bar o_k(1-\bar o_k),即得上式。若组内的预报并不相同(例如把连续的预报分箱),还会多出两项:组内预报的方差 WBV 与组内预报和结果的协方差 WBC,BS=REL−RES+UNC+WBV−2WBCBS = \text{REL} – \text{RES} + \text{UNC} + \text{WBV} – 2\,\text{WBC} (Stephenson, Coelho, and Jolliffe 2008)。

下面的程序生成 5,000 次合成的预报,先让预报者只说 0%、10%……100%,再让他说连续的数字、事后分成 11 组,分别验证这两个恒等式。

推导

# Brier score and Murphy's decomposition BS = REL - RES + UNC, computed by binning;
# exact when all forecasts in a bin are equal. With binned continuous forecasts two
# within-bin terms appear (Stephenson et al. 2008): BS = REL - RES + UNC + WBV - 2 WBC.
import random

rng = random.Random(1950)

def murphy(f, o, nbins=11):
    n = len(f)
    obar = sum(o) / n
    bins = {}
    for fi, oi in zip(f, o):
        k = min(int(fi * (nbins - 1) + 0.5), nbins - 1)      # nearest of 0, 0.1, ..., 1
        bins.setdefault(k, []).append((fi, oi))
    rel = res = wbv = wbc = 0.0
    for pts in bins.values():
        nk = len(pts)
        fk = sum(p[0] for p in pts) / nk
        ok = sum(p[1] for p in pts) / nk
        rel += nk * (fk - ok) ** 2
        res += nk * (ok - obar) ** 2
        wbv += sum((p[0] - fk) ** 2 for p in pts)
        wbc += sum((p[0] - fk) * (p[1] - ok) for p in pts)
    bs = sum((fi - oi) ** 2 for fi, oi in zip(f, o)) / n
    return bs, rel / n, res / n, obar * (1 - obar), wbv / n, wbc / n

def forecaster(n, rounded):
    f, o = [], []
    for _ in range(n):
        p = rng.betavariate(2, 3)                    # the true chance of this event
        q = min(max(p + rng.gauss(0, 0.08), 0.0), 1.0)  # the forecaster's noisy judgement
        if rounded:
            q = round(q * 10) / 10                   # says only 0 %, 10 %, ..., 100 %
        f.append(q)
        o.append(1 if rng.random() < p else 0)
    return f, o

if __name__ == "__main__":
    for rounded in (True, False):
        f, o = forecaster(5000, rounded)
        bs, rel, res, unc, wbv, wbc = murphy(f, o)
        print("forecasts in steps of 10 %" if rounded else "continuous forecasts, 11 bins")
        print(f"  BS = {bs:.5f}   REL = {rel:.5f}   RES = {res:.5f}   UNC = {unc:.5f}")
        tot = rel - res + unc
        print(f"  REL - RES + UNC = {tot:.5f}   gap = {bs - tot:+.2e}")
        if not rounded:
            print(f"  WBV = {wbv:.5f}  WBC = {wbc:.5f}  REL - RES + UNC + WBV - 2 WBC = "
                  f"{rel - res + unc + wbv - 2 * wbc:.5f}")
# forecasts in steps of 10 %
#   BS = 0.20955   REL = 0.00146   RES = 0.03396   UNC = 0.24204
#   REL - RES + UNC = 0.20955   gap = +2.78e-17
# continuous forecasts, 11 bins
#   BS = 0.20418   REL = 0.00089   RES = 0.03614   UNC = 0.23988
#   REL - RES + UNC = 0.20464   gap = -4.51e-04
#   WBV = 0.00079  WBC = 0.00062  REL - RES + UNC + WBV - 2 WBC = 0.20418

当预报只取 11 个离散值时,REL−RES+UNC\text{REL} – \text{RES} + \text{UNC} 与布莱尔分数相差约 3×10−173 \times 10^{-17},也就是只有计算机的舍入误差:分解是精确的恒等式。当预报是连续数字、事后分箱时,三项之和比布莱尔分数大约 0.00045;把组内方差与协方差两项加回去,就又完全相等。实际应用中常用分箱后的三项分解,这时应当知道,它是一个近似。

谁是「校准完美」的人

一个常见的说法是:「总是报 50% 的人校准完美,因为他从不过度自信。」这只在事件的基础率恰好是 50% 时成立。

推导

20,000 个事件,基础率约 30%。比较五位预报者:总是报 50%;总是报基础率 30%;说出每个事件真实概率的「校准者」;把同样的判断向两端推的「过度自信者」(对数几率乘 2);以及向中间拉的「信心不足者」(对数几率乘 0.5,并以基础率为中心)。最后一部分计算:一个完全校准的人如果只做了 20 次预报,用同样的分组方法算出的 REL 平均是多少。

推导

# Five forecasters, 20,000 events with base rate 30 %: always 50 %, always 30 %,
# calibrated (states the true chance), overconfident (2 x logit), underconfident (0.5 x
# logit about 30 %). Last part: REL from only 20 forecasts of a perfectly calibrated
# person.
import math, random

rng = random.Random(1973)

def logit(p):
    return math.log(p / (1 - p))

def inv(x):
    return 1 / (1 + math.exp(-x))

def decompose(f, o, nb=11):
    n, obar = len(f), sum(o) / len(o)
    bins = {}
    for fi, oi in zip(f, o):
        bins.setdefault(round(fi * (nb - 1)), []).append((fi, oi))
    rel = res = 0.0
    table = []
    for k in sorted(bins):
        pts = bins[k]
        fk = sum(p[0] for p in pts) / len(pts)
        ok = sum(p[1] for p in pts) / len(pts)
        rel += len(pts) * (fk - ok) ** 2
        res += len(pts) * (ok - obar) ** 2
        table.append((fk, ok, len(pts)))
    bs = sum((a - b) ** 2 for a, b in zip(f, o)) / n
    return bs, rel / n, res / n, obar * (1 - obar), table

def cases(n=20000):
    ps = [min(max(rng.betavariate(1.2, 2.8), 0.005), 0.995) for _ in range(n)]
    o = [1 if rng.random() < p else 0 for p in ps]
    fc = {"always 50 %": [0.5] * n,
          "always base rate": [0.3] * n,
          "calibrated": ps,
          "overconfident": [inv(2 * logit(p)) for p in ps],
          "underconfident": [inv(0.5 * logit(p) + 0.5 * logit(0.3)) for p in ps]}
    return {k: decompose(v, o) for k, v in fc.items()}

def small_sample_rel(m=20, reps=4000):
    vals = []
    for _ in range(reps):
        ps = [rng.betavariate(1.2, 2.8) for _ in range(m)]
        f = [round(p * 10) / 10 for p in ps]                 # states its chance, rounded
        o = [1 if rng.random() < q else 0 for q in f]        # events happen at that rate
        vals.append(decompose(f, o)[1])
    vals.sort()
    return sum(vals) / reps, vals[reps // 2]

if __name__ == "__main__":
    res = cases()
    print("forecaster        |   BS    REL    RES    UNC")
    for k, (bs, rel, rs, unc, _) in res.items():
        print(f"{k:17s} | {bs:.4f} {rel:.4f} {rs:.4f} {unc:.4f}")
    print("overconfident: mean forecast -> observed frequency (bins with n >= 200):")
    cells = [f"{f:.2f}->{ob:.2f}" for f, ob, n in res["overconfident"][4] if n >= 200]
    print("  " + "  ".join(cells[:6]))
    print("  " + "  ".join(cells[6:]))
    mean, med = small_sample_rel()
    print(f"perfectly calibrated, only 20 forecasts: REL mean {mean:.4f},"
          f" median {med:.4f} (truth 0)")
# forecaster        |   BS    REL    RES    UNC
# always 50 %       | 0.2500 0.0403 0.0000 0.2097
# always base rate  | 0.2097 0.0000 0.0000 0.2097
# calibrated        | 0.1677 0.0001 0.0413 0.2097
# overconfident     | 0.1797 0.0115 0.0407 0.2097
# underconfident    | 0.1757 0.0075 0.0394 0.2097
# overconfident: mean forecast -> observed frequency (bins with n >= 200):
#   0.02->0.09  0.09->0.25  0.20->0.33  0.30->0.37  0.40->0.44  0.50->0.49
#   0.60->0.55  0.70->0.59  0.80->0.67  0.90->0.74  0.97->0.88
# perfectly calibrated, only 20 forecasts: REL mean 0.0631, median 0.0583 (truth 0)
五位预报者的可靠性图。横轴是同一组预报的平均概率,纵轴是这些事件实际发生的比例;对角线表示完美校准。过度自信者的曲线比对角线平坦:他说 90% 的事只有约 74% 发生,说 9% 的事却有 25% 发生。总是报 50% 与总是报基础率的人各只有一个点。

总是报 50% 的人,REL 为 0.0403,约等于 (0.5−0.3)2(0.5 – 0.3)^2:他系统地高估了这类事件。总是报基础率的人,REL 为 0,校准完美,但 RES 也是 0,他的布莱尔分数正好等于不确定性 0.2097:这是什么也不懂也能达到的分数。说出真实概率的校准者,REL 几乎为 0,RES 为 0.0413,布莱尔分数降到 0.1677。

过度自信者与校准者拥有相同的信息,RES 几乎一样(0.0407),但 REL 升到 0.0115,布莱尔分数因此变差到 0.1797。图一显示了过度自信的典型形状:他说 90% 的事只有约 74% 发生,说 97% 的事约 88% 发生;在另一端,他说 9% 的事其实有约 25% 发生。信心不足者的问题方向相反,REL 为 0.0075。所以,校准与区分度是两种不同的能力:校准好不等于有用,区分度高也不等于说得准。

最后一行提醒一个测量问题:一个完全校准的人,如果只做 20 次预报,按 11 组分箱算出的 REL 平均却是 0.063,中位数 0.058,远离真实值 0。原因是每组只有一两次预报,观察到的发生比例在 0 与 1 之间剧烈跳动。所以,用很少的预报给个人算墨菲分解,会系统地高估校准误差。第八章的试验因此没有用个人的 REL 作主要结局。

恰当评分规则

一条评分规则如果能让预报者只有说出自己真实相信的概率,期望分数才最好,就称为严格恰当的。这一点很重要:一个奖励「说得更极端」的规则,会把诚实的预报者训练成过度自信的人。

推导

推导。 设你相信事件发生的概率是 pp,报出 qq。布莱尔分数的期望(越小越好)为 E(q)=p(1−q)2+(1−p)q2E(q) = p(1-q)^2 + (1-p)q^2,求导得 E′(q)=−2p(1−q)+2(1−p)q=2(q−p)E'(q) = -2p(1-q) + 2(1-p)q = 2(q – p),只在 q=pq = p 时为零,且二阶导数为正:诚实是唯一的最优报告。对数分数 −lnq-\ln q(事件发生)或 −ln(1−q)-\ln(1-q)(未发生)的期望为 −plnq−(1−p)ln(1−q)-p\ln q – (1-p)\ln(1-q),导数为 −p/q+(1−p)/(1−q)-p/q + (1-p)/(1-q),同样只在 q=pq = p 时为零 (Good 1952; Gneiting and Raftery 2007)。看起来同样自然的绝对误差 |q−o||q – o|,期望为 p(1−q)+(1−p)qp(1-q) + (1-p)q,是 qq 的线性函数:只要 p>0.5p > 0.5,报得越接近 1 越好。

推导

# Expected penalty for reporting q when you believe p = 0.70 (lower is better):
# quadratic (Brier), logarithmic, absolute. Strictly proper = honest q = p is the unique
# best.
import math

P = 0.70

def e_quad(q, p=P):
    return p * (1 - q) ** 2 + (1 - p) * q ** 2

def e_log(q, p=P):
    return -p * math.log(q) - (1 - p) * math.log(1 - q)

def e_abs(q, p=P):
    return p * (1 - q) + (1 - p) * q

if __name__ == "__main__":
    grid = [i / 100 for i in range(1, 100)]
    print(" report q | quadratic | logarithmic | absolute")
    for q in (0.50, 0.60, 0.70, 0.80, 0.90, 0.99):
        print(f"   {q:.2f}   |  {e_quad(q):.4f}   |   {e_log(q):.4f}    |  {e_abs(q):.4f}")
    for name, fn in (("quadratic", e_quad), ("logarithmic", e_log), ("absolute", e_abs)):
        best = min(grid, key=fn)
        print(f"{name:11s}: best report on the grid 0.01..0.99 is q = {best:.2f}")
    print(f"log score if you said 0.99 and it did not happen: {-math.log(0.01):.2f}"
          f" (vs {-math.log(0.30):.2f} after saying 0.70)")
#  report q | quadratic | logarithmic | absolute
#    0.50   |  0.2500   |   0.6931    |  0.5000
#    0.60   |  0.2200   |   0.6325    |  0.4600
#    0.70   |  0.2100   |   0.6109    |  0.4200
#    0.80   |  0.2200   |   0.6390    |  0.3800
#    0.90   |  0.2500   |   0.7645    |  0.3400
#    0.99   |  0.2941   |   1.3886    |  0.3040
# quadratic  : best report on the grid 0.01..0.99 is q = 0.70
# logarithmic: best report on the grid 0.01..0.99 is q = 0.70
# absolute   : best report on the grid 0.01..0.99 is q = 0.99
# log score if you said 0.99 and it did not happen: 4.61 (vs 1.20 after saying 0.70)

当你相信 70% 时,布莱尔分数与对数分数都在报 0.70 时最好;绝对误差却在报 0.99 时最好,它不是恰当的评分规则。两种恰当规则对「说得太满」的惩罚程度不同:说 99% 而事情没有发生,对数分数的惩罚是 4.61,而如果当初说 70%,惩罚只有 1.20。对数分数对极端的错误极其严厉(说 100% 而错了,惩罚为无穷大),布莱尔分数则有上限。预测锦标赛大多用布莱尔分数,部分原因就是它不会因一次失误让一个人「永远翻不了身」。

过度自信有几种

证据

校准研究的基本发现。 早期的校准研究发现,在一般知识题上,人们说「我有 90% 把握」时,正确率往往明显低于 90%;在很难的题目上过度自信,在很容易的题目上反而可能信心不足(「难易效应」)(Lichtenstein, Fischhoff, and Phillips 1982)。阿尔珀特与赖法让学生为未知数量给出 98% 的置信区间,真实值落在区间之外的比例远高于名义上的 2% (Alpert and Raiffa 1982)。摩尔与希利区分了三种常被混为一谈的「过度自信」:高估自己的表现、认为自己比别人好,以及对自己的估计过于精确(区间太窄),并指出第三种比前两种更为持久 (Moore and Healy 2008)。在哈兰、摩尔与莫尔韦奇的三个实验中,人们给出的 90% 置信区间只在 29% 到 74% 的情况下包含真实值 (Haran, Moore, and Morewedge 2010)。

本章小结

布莱尔分数是预报与结果之差的平方的平均,墨菲把它分解为可靠性(校准)、区分度与不确定性三项;当组内预报相同时分解是精确的,分箱后则多出组内方差与协方差两项。总是报 50% 的人只在基础率为 50% 时校准完美;一般而言,总是报基础率的人校准完美而区分度为零。过度自信者可以拥有和校准者同样的区分度,却因为说得太满而得分更差。布莱尔分数与对数分数是严格恰当的,绝对误差不是。用很少的预报给个人算校准误差,会系统地偏高。下一章讨论概率判断中最著名的一种错误:忽略基础率。

参考文献

Alpert, Marc, and Howard Raiffa. 1982. “A Progress Report on the Training of Probability Assessors.” In Judgment Under Uncertainty: Heuristics and Biases, edited by Daniel Kahneman, Paul Slovic, and Amos Tversky, 294–305. Cambridge: Cambridge University Press.
Brier, Glenn W. 1950. “Verification of Forecasts Expressed in Terms of Probability.” Monthly Weather Review 78 (1): 1–3. https://doi.org/10.1175/1520-0493(1950)078<0001:VOFEIT>2.0.CO;2.
Gneiting, Tilmann, and Adrian E. Raftery. 2007. “Strictly Proper Scoring Rules, Prediction, and Estimation.” Journal of the American Statistical Association 102 (477): 359–78. https://doi.org/10.1198/016214506000001437.
Good, I. J. 1952. “Rational Decisions.” Journal of the Royal Statistical Society, Series B (Methodological) 14 (1): 107–14.
Haran, Uriel, Don A. Moore, and Carey K. Morewedge. 2010. “A Simple Remedy for Overprecision in Judgment.” Judgment and Decision Making 5 (7): 467–76.
Lichtenstein, Sarah, Baruch Fischhoff, and Lawrence D. Phillips. 1982. “Calibration of Probabilities: The State of the Art to 1980.” In Judgment Under Uncertainty: Heuristics and Biases, edited by Daniel Kahneman, Paul Slovic, and Amos Tversky, 306–34. Cambridge: Cambridge University Press.
Moore, Don A., and Paul J. Healy. 2008. “The Trouble with Overconfidence.” Psychological Review 115 (2): 502–17. https://doi.org/10.1037/0033-295X.115.2.502.
Murphy, Allan H. 1973. “A New Vector Partition of the Probability Score.” Journal of Applied Meteorology 12 (4): 595–600. https://doi.org/10.1175/1520-0450(1973)012<0595:ANVPOT>2.0.CO;2.
Stephenson, David B., Caio A. S. Coelho, and Ian T. Jolliffe. 2008. “Two Extra Components in the Brier Score Decomposition.” Weather and Forecasting 23 (4): 752–57. https://doi.org/10.1175/2007WAF2006116.1.

Fan, Y. (2026). Probabilistic Judgement, Brier-Score Calibration and the Statistics of Collective Intelligence: From Base-Rate Neglect and Signal Detection Theory to Superforecasting, Read Beside Classical Chinese Strategic Calculation [概率判断、布莱尔分数校准与群体智慧的统计理论] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23764998 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).