qinghuan
← 回到知识探索

AI 直觉 / 动手实验

AI说“八成把握”,真的有八成吗?

把相近概率的预测放在一起,看实际发生的比例是否对得上,而不只看最终分对几题。

展开本文目录
  1. 先动手看看
  2. 都分对八成,也可能一个更爱夸口
  3. 把相近分数装进同一个小篮子
  4. 概率误差分数,不是单独的校准成绩
  5. 调完以后,还得换一批数据检查
  6. 记住这三点
  7. 别把例子用过头
  8. 自己试一小步
  9. 查原始资料
  10. 找一份资料继续练
开始前,会这些就够了
  • 知道百分比怎样计算
遇到不熟悉的词,先看这 2 个解释
评测
用事先确定的样本、任务和评分规则,检查模型或整个系统能否满足要求的过程。既可检查答案,也可检查工具操作和最终状态,结果要连同测试条件一起理解。
概率校准
把报出相近概率的预测放在一起,看事情实际发生的比例是否接近这些概率。它检查“八成把握”这类数字是否与观察相符,与最后分类答对多少题有区别。
打开完整术语小抄 ↗

想象一个给工单估计“需要优先处理”概率的分类器。如果很多张都被报为80%,等人工核实后,这一组大约应有八成确实需要优先。概率校准关注的就是这种长期对应关系,而不是某一张工单最后碰巧猜对了没有。

一个分数写成小数,并不说明它已经具备这样的含义。校准要靠带有可靠标签的评测数据来检查。本篇用十条手写数据解释读图方法,既没有运行真实模型,也没有证明任何服务的自信程度可信。

都答对八成,报出的概率也一样靠谱吗?

十条固定记录中,前五条有一条标签为 1,后五条有四条标签为 1。只改变报出的分数,不改变标签;下面再按分数区间重新分组。

切换分数说法
分组左边界包括在内;只有最后一组也包括 1
分数区间数量平均报分标签 1 的频率
[0.0, 0.2)0空组空组
[0.2, 0.4)520.0%1 / 5 = 20.0%
[0.4, 0.6)0空组空组
[0.6, 0.8)0空组空组
[0.8, 1.0]580.0%4 / 5 = 80.0%

用 0.5 做分类门槛,答对 8 / 10(80%);这次的 Brier 分数为 0.160。

两组平均报分与这十条记录的观察频率刚好相同。这是人为安排的例子,不是现实校准保证。

Brier 是 (分数 − 标签)² 的平均值,越低表示这批概率预测的均方误差越小;不能只凭它判断校准,因为它也受区分能力等因素影响。整批仅十条,分组方式还会影响你看到的结果;换一批样本也可能变化。这里没有拟合校准模型。

都分对八成,也可能一个更爱夸口

我们安排两组各五张工单。第一组只有一张真的需要优先,第二组有四张。方案A分别报20%和80%;方案B把它们改报10%和90%。按0.5分界,两种方案选中的工单完全相同,所以最终正确率也相同。

区别在概率本身:A在这份手写样本里正好对上组内频率,B对低概率说得更低、对高概率说得更高,和观察值拉开了距离。这叫更自信,不等于更有根据。每组只有五张,碰巧对上也不足以证明真实使用时一直校准良好。

把相近分数装进同一个小篮子

可靠性图常把预测按概率分组:横轴放组内平均预测概率,纵轴放组内实际正例比例。点越靠近对角线,表示这一组的预测与观察越接近。读图时还要问每个点背后有多少条记录,否则两条样本和两万条会被画成同样醒目的一个点。

下面的数据只有两个概率值,所以直接按相同分数分组。真实数据的分数通常各不相同,需要划分区间;分得过细可能每组太少,分得过粗又可能把内部差异抹平。图形是检查工具,不能替你决定哪种分组永远正确。

小实验 · python
labels = [0, 0, 0, 0, 1, 1, 1, 1, 1, 0]
plans = {'A': [0.2] * 5 + [0.8] * 5,
         'B': [0.1] * 5 + [0.9] * 5}

for name, scores in plans.items():
    accuracy = sum((score >= 0.5) == label
                   for score, label in zip(scores, labels)) / len(labels)
    brier = sum((score - label) ** 2
                for score, label in zip(scores, labels)) / len(labels)
    print(f'{name}: accuracy={accuracy:.0%}, Brier={brier:.3f}')
    for score in sorted(set(scores)):
        group = [label for p, label in zip(scores, labels) if p == score]
        print(f'  predicted={score:.0%}, observed={sum(group)/len(group):.0%}, n={len(group)}')

怎样运行:保存为 calibration_baskets.py,用 Python 3.10 或更新版本运行:python calibration_baskets.py。仅用标准库,不联网。

运行后对照结果
A: accuracy=80%, Brier=0.160
  predicted=20%, observed=20%, n=5
  predicted=80%, observed=80%, n=5
B: accuracy=80%, Brier=0.170
  predicted=10%, observed=20%, n=5
  predicted=90%, observed=80%, n=5

概率误差分数,不是单独的校准成绩

代码还算了 Brier 分数:把每条概率与0或1标签的差平方,再求平均。错误而且特别自信的预测会受到较大惩罚。这里B的分数更高,说明按这种概率误差衡量,它在这份样本上更差。

不过 Brier 同时受到校准、区分不同情况的能力等因素影响,不能把“Brier更低”直接翻译成“校准一定更好”。反过来,永远报告总体正例比例,可能看起来很校准,却没有帮你把需要优先的工单排到前面。排序能力和概率可信程度要分别看。

调完以后,还得换一批数据检查

校准器可以理解为给已有分数再做一次有依据的换算。换算规则需要用合适的数据学习,再到没有参与拟合的数据上评测。它不是把所有分数向0.5挤一挤,也不是给已经答错的内容补一个更温和的语气;使用范围变化后,还要重新检查。

读 scikit-learn 的可靠性图时,连同下方样本分布一起看;读 Guo 等人的论文摘要时,留意结论来自特定分类实验。本篇谈的是定义清楚的二分类事件,不能把聊天模型说出的“我有八成把握”自动当作整段回答为真的概率。

记住这三点

  • 校准检查相近预测概率是否对应相近的实际发生频率。
  • 正确率相同,概率质量也可能不同;每个分组的样本量必须一起看。
  • Brier不是纯校准指标,分类概率的结论也不能直接套到整段聊天回答。

别把例子用过头

  • 手工安排的数据只能演示计算,不能证明真实模型具有相同表现。
  • 总体看起来校准良好,仍可能掩盖不同用户、时间或任务类型的偏差。
  • 学习校准规则和检验最终效果要分开;用同一份样本反复修到贴线会过于乐观。

自己试一小步

如果同一组内不同用户的表现很不一样,整体校准图会漏掉什么?

  1. 为十条数据添加自己设计的两类用户标签。
  2. 分别计算两类用户的预测均值、实际频率和数量。
  3. 再尝试把所有分数改成同一个总体比例,观察哪些信息丢失。

做到这些,就算完成

  • 是否区分分类正确率、组内校准和排序能力?
  • 是否始终显示每组样本数?
  • 是否避免从十条演示数据推断真实服务质量?

查原始资料

想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。

找一份资料继续练

先选一项,按下面的范围继续学;不必从头读完整门课程。