定位:这是本讲义补充的前置讲,原课没有对应的一节。原课的第三条学习目标是”设计实验来评估提示设计、优化提示的表现”,后面每一讲(尤其是第 2 讲的上下文学习、第 4 讲的思维链、第 10 讲的自动提示、第 17 讲的评估)都要比较提示的好坏;这一篇把需要的统计学讲清楚。 依据说明:区间、检验、样本量公式都是标准的统计学内容(Wilson 1927;McNemar 1947;Connor 1987 的配对样本量公式;Holm 1979);LLM 评测里的具体建议参考 Miller(2024)“Adding Error Bars to Evals”和 Zhao et al.(2021)。全部实验是本讲义自己设计的:前三个脚本用一个”知道真值”的模拟世界,第四个脚本用第 1 讲训练的真实小模型。 配套代码 Code:
code/prereq3/(只用 Python 标准库,04 号脚本的后半部分用 PyTorch;4 个脚本 + 1 个模块;最慢的脚本约 7 秒) 预计阅读时间:2–3 小时(含运行代码)
0. 本讲导航 · How to read this lecture
0.1 为什么需要统计学
前置讲 P2 的实验跑完,得到了这样一张表:
| 模板 | 准确率 [95% CI] |
|---|---|
| A 直接问 | 84.4% [75.8, 90.3] |
| B 只答一个词 | 84.4% [75.8, 90.3] |
| C 只输出 JSON | 81.2% [72.3, 87.8] |
C 比 A 低 3 个百分点——C 更差吗?再看一些你会在论文、博客、群聊里看到的说法:
- “加了一句 ‘Let’s think step by step’,准确率从 62% 提到了 66%。“(在 100 道题上)
- “我们试了 20 种提示,最好的那个比基线高 8 个百分点。”
- “这个提示在 GPT-X 上好用,在 GPT-Y 上没区别。“(各测了一次)
- “我们每道题采样了 10 次,所以结果很可靠。”
每一句都可能是真的,也可能只是运气。这一篇讲怎样判断。好消息是需要的统计学并不多,而且几乎全部可以用”模拟一下,看看会怎样”来理解——这正是代码要做的事。
0.2 学习目标 Learning goals
- 理解抽样误差:测试集是从”所有可能的题”里抽出来的一份样本,准确率因此有波动;会算标准误,会用 Wilson 区间。
- 知道在同一组题上比较两个提示时为什么要用配对的方法(McNemar 检验、配对差值区间),以及它能省多少题。
- 理解功效和样本量:要多少道题才能发现一个给定大小的差别;“不显著”不等于”一样好”。
- 理解多重比较和赢家诅咒:试了很多个提示、挑最好的那个时会发生什么,怎样用开发集 / 测试集划分和 Holm 校正避免自欺。
- 认识题目之外的随机性来源:每道题采样多次(要用聚类标准误)、示例的选择和顺序(要当作随机因素)。
- 能写出一份提示实验的检查清单。
0.3 本讲地图 Map
§1 抽样误差:测试集只是一份样本 ← 代码 01 演示 1
§2 置信区间:Wald 为什么不行,Wilson、bootstrap ← 代码 01 演示 2–4
§3 比较两个提示:配对 ← 代码 02 演示 1
§4 功效与样本量:要多少道题 ← 代码 02 演示 2–3
§5 试了很多个提示之后:赢家诅咒与多重比较 ← 代码 03
§6 随机性的其他来源:多次采样、示例的选择 ← 代码 04
§7 一份提示实验的检查清单
§8 小结 §9 常见误区 §10 练习 §11 延伸阅读 §12 下一讲预告
0.4 术语 Terms
| 术语 | 意思 |
|---|---|
| 总体 / 样本(population / sample) | 所有可能的题 / 你实际用来测的那些题 |
| 估计值(estimate) | 从样本算出来的数,例如测试集上的准确率 ;真实值 是总体上的准确率 |
| 标准误(standard error, SE) | 估计值在”换一份样本”时的标准差 |
| 置信区间(confidence interval) | 一个随样本变化的区间;95% 区间的意思是”用这种方法算,95% 的情况下会包含真值” |
| 原假设(null hypothesis) | 通常是”两个提示一样好” |
| p 值 | 如果原假设成立,看到至少这么极端的结果的概率 |
| 显著性水平 α | 事先定的门槛,常用 0.05:p < α 就说”显著” |
| 第一类错误 / 假阳性 | 其实一样好,却说有差别(概率 ≤ α) |
| 第二类错误 / 功效(power) | 真有差别却没测出来 / 真有差别时测出来的概率 |
| 配对(paired) | 两个提示用同一组题,逐题比较 |
| 族错误率(FWER) | 做了很多次检验时,至少一个假阳性的概率 |
1. 抽样误差:测试集只是一份样本 · Sampling error
配套代码:
01_intervals.py演示 1、模块stats_kit.py
一个提示”真正的”准确率,是它在所有可能的题(总体)上的准确率 。我们没法把所有可能的题都测一遍,只能抽一份测试集(样本),算出 。换一份同样难度的测试集, 就会变。
stats_kit.ItemBank 是一个”知道真值”的模拟世界:每道题有一个难度,每个提示有一个能力,提示答对一道题的条件由两者决定(还有一点每个提示自己的”手感”)。我们可以精确地设定一个提示的真实准确率,再看测出来会怎样。01 号脚本演示 1:一个真实准确率为 70% 的提示,在 1 万份各 50 道题的测试集上各测一次——
- 前 5 次的结果:64%、64%、74%、62%、66%。
- 1 万次结果的标准差是 0.0646,中间 95% 落在 58%–82%。
**同一个提示,换一份 50 道题的测试集,准确率可以差 10 个百分点以上。**两个提示在 50 道题上差 6 个百分点,完全可能是同一个提示测了两次。
这个标准差有一个简单的公式。把每道题对或错看成一次抛硬币(正面的概率是 ),准确率就是 次抛硬币里正面的比例,它的标准差是
代入 、 得 0.0648,和模拟出来的 0.0646 几乎一样。这个结论只需要一个假设:测试题是从同一个题库里随机抽的、相互独立的。两个直接的推论:
- 标准误随 缩小:题目多 4 倍,误差才减半。
- 准确率越接近 50%,误差越大( 在 0.5 时最大)。
2. 置信区间 · Confidence intervals
配套代码:
01_intervals.py演示 2–4
2.1 “95% 置信区间”是什么意思
一个 95% 置信区间是一个方法:用它从样本算出一个区间,如果反复做这个实验(每次抽一份新的测试集),算出来的区间有 95% 的次数会包含真值。注意主语是”方法”,不是”这一个区间”——真值要么在这个区间里,要么不在,没有概率可言。这个”95% 的次数”叫覆盖率,可以用模拟检验。
2.2 Wald 区间为什么不行
最常见的区间是 Wald 区间:——把公式里的 直接换成 。演示 2 在 12 种情形下各模拟 4000 次实验,看它的覆盖率:
| 题数 | 真实准确率 | Wald 覆盖率 | Wilson 覆盖率 |
|---|---|---|---|
| 10 | 50% | 89.3% | 97.9% |
| 10 | 90% | 65.2% | 93.4% |
| 10 | 98% | 17.6% | 98.5% |
| 30 | 98% | 45.6% | 97.9% |
| 100 | 98% | 86.2% | 94.8% |
| 400 | 50% | 95.6% | 94.8% |
题多、准确率在中间时,Wald 区间没问题;可题少、准确率接近 100% 时它严重失灵。准确率 98% 时 10 道题全对很常见,Wald 区间就变成 ——“绝对不会错”。LLM 评测里高准确率、小样本的情形恰恰很多。
Wilson 区间(Wilson 1927)把” 落在 里”这个不等式对 解出来,而不是先把 换成 :
它在所有 12 种情形下的覆盖率都在 93.4%–98.5%(小样本时略偏保守,宁宽勿窄),而且永远落在 里。默认用 Wilson 区间;本讲义的所有表格都用它(console.pct_ci、stats_kit.wilson_ci)。
2.3 要多少道题
演示 3,准确率 80% 时:
| 题数 | 50 | 100 | 200 | 500 | 1000 | 2000 | 5000 |
|---|---|---|---|---|---|---|---|
| Wilson 半宽(百分点) | ±10.9 | ±7.8 | ±5.5 | ±3.5 | ±2.5 | ±1.8 | ±1.1 |
反过来,想要 ±5 / ±3 / ±2 / ±1 个百分点,大约要 246 / 683 / 1537 / 6147 道题(准确率 50% 时更多:385 / 1068 / 2401 / 9604)。公式是 。很多论文和博客在几十、几百道题上比较提示,报告的差别常常落在这个误差里。
2.4 bootstrap:没有公式时
自助法(bootstrap)用手上的这份题目代替总体,模拟”再出一份题”:从 道题里有放回地抽 道,算一次统计量;重复几千次,取中间 95% 那一段。演示 4:对准确率,bootstrap 区间 [0.640, 0.770] 和 Wilson 区间 [0.638, 0.764] 几乎一样;对”简单题准确率 − 难题准确率”这种没有现成公式的统计量,bootstrap 照样给出区间 [0.425, 0.637]。F1、加权平均、两个指标的差……只要能写出”怎样从题目算出这个数”,就能用 bootstrap。
关键是重抽的单位必须是独立的单位——在提示实验里通常是”题目”。§3 的配对 bootstrap 重抽题目(两个提示的结果跟着题目一起走),§6 的多次采样也要按题目聚类。
3. 比较两个提示:配对 · Paired comparisons
配套代码:
02_paired.py演示 1
3.1 同一组题上的 2×2 表
比较两个提示时,几乎总是让它们做同一组题。02 号脚本演示 1:提示 A 的真实准确率 70%,B 是 73%,同一组 200 道题。逐题对比:
| B 对 | B 错 | |
|---|---|---|
| A 对 | 129 | 14 |
| A 错 | 17 | 40 |
A 答对 143 道(71.5%),B 答对 146 道(73.0%)。两个提示在 169 道题上结果一样(都对或都错),只在 31 道题上”意见不同”。同一道题上两者结果的相关系数是 0.61:难题两个提示都容易错,简单题都容易对。
3.2 McNemar 检验:只看意见不同的题
两个提示都对、都错的题,对”谁更好”没有任何信息。McNemar 检验只看意见不同的题:A 对 B 错的有 道,A 错 B 对的有 道。如果 A、B 一样好,每道意见不同的题”A 赢”还是”B 赢”就像抛硬币,所以 。p 值就是这个二项分布两侧的尾概率(mcnemar_exact 用精确的二项分布,不需要大样本近似)。
3.3 配对为什么灵敏得多
演示 1 对同一份数据做了几种分析:
| 分析方法 | B − A | 95% 区间 | p 值 |
|---|---|---|---|
| 不配对:两比例 z 检验 | +1.5% | [−7.3%, +10.3%] | 0.738 |
| 配对:McNemar 精确检验 | +1.5% | – | 0.720 |
| 配对:差值的正态区间 | +1.5% | [−4.0%, +7.0%] | – |
| 配对:bootstrap(按题重抽) | +1.5% | [−4.0%, +7.0%] | – |
(这次抽到的 200 道题上只差 1.5 个百分点,比真实的 3 个点小,又是一个抽样误差的例子。)配对的区间(±5.5)比不配对的(±8.8)窄了 38%,相当于不配对时要多用 2.6 倍的题。原因在方差的公式里:
同一组题上,两个提示的结果正相关,协方差项把方差减掉了一大块——“这组题碰巧难”这部分共同的波动,在作差时被抵消了。不配对的检验假设两组结果相互独立,把这份相关性白白浪费了。同一组题上比较两个提示,总是用配对的方法。
4. 功效与样本量 · Power and sample size
配套代码:
02_paired.py演示 2–3
4.1 两种错误
| 两个提示其实一样好 | 真的有差别 | |
|---|---|---|
| 检验说”显著” | 第一类错误(假阳性),概率 ≤ α | 正确,概率 = 功效 |
| 检验说”不显著” | 正确 | 第二类错误(漏检) |
α(常用 0.05)控制假阳性;功效是”真有差别时能测出来”的概率,常用的目标是 80%。
4.2 一个 3 个百分点的差别,要多少道题
演示 2:真实差别 3 个百分点(70% vs 73%),每种题数模拟 1000 次实验,看有多少次检验结果显著:
| 题数 | 不配对 z 检验 | McNemar(配对) | McNemar 的公式预测 |
|---|---|---|---|
| 100 | 0.6% | 6.6% | 11% |
| 200 | 2.7% | 15.6% | 18% |
| 500 | 8.4% | 33.8% | 38% |
| 1000 | 22.8% | 63.2% | 64% |
| 2000 | 59.5% | 91.6% | 91% |
- 题目少时,一个真实的差别大多数时候测不出来:200 道题时配对检验只有 15.6% 的把握,500 道题时也只有 33.8%。反过来说,“在 200 道题上没有发现显著差别”不等于”两个提示一样好”——可能只是题太少。
- 配对检验在每种题数下都灵敏得多。达到 80% 功效,配对需要约 1448 道题,不配对需要约 3554 道,差了 2.5 倍。题目和 API 调用都是钱。
4.3 在实验之前规划题数
McNemar 检验的样本量有一个近似公式(Connor 1987):
其中 是想检测的差别, 是两个提示”意见不同”的题占的比例。需要的题数大致和 成正比:差别越小,需要的题越多(差别减半,题数要乘 4);两个提示在越多的题上意见不同,同样的平均差就越难分辨。表里的公式预测和模拟基本吻合(题少时公式略乐观)。实际做法:先用几十道题做一个小规模的预实验,估计 ,再代入公式。
不配对的标准公式( 每组 )假设两组题相互独立。用在同一组题上时,它在题少的时候严重高估功效(100 道题时预测 7%、实际 0.6%)——这又是一个”同一组题不要用不配对的方法”的理由。
4.4 假阳性率
演示 3:两个提示的真实准确率完全相同,每次实验 500 道题、重复 2000 次。McNemar 检验有 3.4% 的实验”显著”(精确检验略偏保守,低于名义上的 5%);不配对的检验只有 0.2%——它把两个提示的结果当成独立的,高估了差值的方差,过于保守,这和它功效低是同一枚硬币的两面。
假阳性率 5% 的意思是:每做 20 次”其实没区别”的比较,大约有 1 次会冤枉出一个差别。这不是 bug,是 α = 0.05 的定义。如果你做了很多次比较,问题就来了(§5)。
4.5 显著不等于重要
题目足够多时,再小的差别都会”显著”:2 万道题上,0.5 个百分点的差别也能显著。可这个差别值不值得你把提示改得更长、更贵?报告结果时,差别的大小(带区间)比 p 值更重要;还要一起报告成本(token 数、延迟),前置讲 P2 的记账就是为此。
5. 试了很多个提示之后 · Multiple comparisons and the winner’s curse
5.1 赢家诅咒
提示工程的日常是:写 20 个版本,在一组开发题上各跑一遍,留下最好的那个。03 号脚本演示 1 让 20 个版本一样好(真实准确率都是 70%,只是每个在不同的题上”手感”不同),挑开发集第一名,再看它在全新的 2000 道题上的表现(重复 500 次):
| 开发集题数 | 随便一个版本的开发集准确率 | 第一名的开发集准确率 | 第一名在新题上 | 虚高 |
|---|---|---|---|---|
| 50 | 70.5% | 77.8% | 70.0% | +7.9 |
| 100 | 69.8% | 75.3% | 70.0% | +5.3 |
| 400 | 70.0% | 72.8% | 70.0% | +2.8 |
20 个一模一样好的版本,开发集上的”第一名”平均比真实水平高 5 个百分点以上,一换到新题就”掉回”70%。这叫赢家诅咒:挑最大值这个动作本身,就把运气选了进来。
这就是”在开发集上过拟合提示”:你反复修改提示、每次都看开发集分数,最后留下的版本有一部分好成绩来自运气。对策很简单,但必须严格执行:挑选用的开发集和报告用的测试集分开,测试集只在最后用一次。第 10 讲的自动提示优化会在开发集上试几百个提示,这个问题会被放大几百倍。
5.2 多重比较
演示 2:基线和 20 个版本的真实准确率都是 70%,在同一组 200 道题上,每个版本和基线做一次 McNemar 检验(只数”比基线好”的方向),重复 500 次:
| 做法 | 至少有一个”显著优于基线”的比例 |
|---|---|
| 不校正(每个检验都用 p < 0.05) | 16.2% |
| Bonferroni(p < 0.05 / 20) | 1.2% |
| Holm(逐步校正) | 1.2% |
每个检验单独看,冤枉的概率都不超过 5%;可 20 个检验里至少一个被冤枉的概率要大得多。试的版本越多,“总能找到一个显著的”就越确定。两种校正方法:
- Bonferroni:每个检验的门槛降到 ( 是检验的个数)。
- Holm(1979):把 p 值从小到大排序,第 小的(从 0 开始数)和 比较,一旦有一个不显著就停下。它和 Bonferroni 一样把族错误率控制在 α 以内,但更容易发现真正的差别。
5.3 挑得出来 ≠ 证明得了
演示 3:20 个版本里真有一个好 5 个百分点(75%),其余 19 个和基线一样(70%):
| 开发集题数 | 第一名正是那个更好的版本 | Holm 校正后检测出它 | 平均每次的假发现 |
|---|---|---|---|
| 100 | 53.4% | 1.8% | 0.02 |
| 400 | 93.6% | 24.6% | 0.02 |
| 1000 | 100.0% | 80.2% | 0.01 |
100 道题时,有将近一半的概率第一名不是真正更好的那个——19 个运气好的普通版本里,总有一个能冲到前面。400 道题时它大多能排第一,可经过校正之后,只有四分之一的概率能被证明显著优于基线。校正在保护你(假发现始终接近 0),代价是需要更多的题。候选越多,开发集要越大。
实用的做法:
- 事先写下你要比较哪几个(“预注册”),而不是事后从 20 个里挑一个显著的报告;
- 挑选和检验分开:在开发集上挑,在独立的测试集上只检验挑出来的那一个(只比一次,就不需要校正);
- 确实要同时比较多个时,比较了几个就校正几个。
6. 随机性的其他来源 · Other sources of randomness
“抽到了哪些题”不是唯一的随机性来源。
6.1 每道题采样多次:按题聚类
温度 > 0 时,同一道题每次的回答可能不同;常见的做法是每道题采样 次,算总的正确率。可标准误该怎么算?04 号脚本演示 1:100 道题 × 每道题 5 次采样,重复 2000 次实验——
| 数值 | |
|---|---|
| 估计值在不同实验之间的真实标准差 | 0.0324 |
| 朴素 SE(把 500 个结果当成相互独立)的平均值 | 0.0214 |
| 按题聚类的 SE 的平均值 | 0.0322 |
| 朴素 95% 区间的覆盖率 | 79.2% |
| 聚类 95% 区间的覆盖率 | 94.9% |
同一道题的 5 次采样并不独立:难题 5 次都容易错,简单题 5 次都容易对。把 500 个结果当成 500 次独立的试验,SE 就小了一大截,区间”自信”得过了头。正确的做法是按题聚类:先算每道题的平均正确率 ,再算它们的均值的标准误 (cluster_se)。Miller(2024)建议 LLM 评测里一律这样报告:每道题采样多次、或者一篇文章出好几道题(阅读理解)时,都按”题”或”文章”聚类。
在第 1 讲的迷你 GPT 上(演示 3),96 道知识题在温度 1.0 下各采样 8 次:70 道题 8 次全对,26 道时对时错,聚类 SE 是朴素 SE 的 1.58 倍。温度 1.5 时,时对时错的题增加到 67 道,准确率从 92.8% 降到 78.0%——温度不只是”随机性”,它会系统性地改变你测到的结果,比较两个提示时必须保持一致。
6.2 预算固定时:多出题,还是多采样
演示 2:一共只能调用 400 次——
| 分配方式 | 估计值的标准差 | 95% 区间半宽 |
|---|---|---|
| 400 道题 × 1 次 | 0.0242 | ±4.7 |
| 200 道题 × 2 次 | 0.0268 | ±5.3 |
| 100 道题 × 4 次 | 0.0338 | ±6.6 |
| 50 道题 × 8 次 | 0.0430 | ±8.4 |
| 25 道题 × 16 次 | 0.0577 | ±11.3 |
估计值的方差 ≈(题目之间的差异) +(同一道题内部的采样噪声)。多采样只能缩小第二项,第一项只有多出题才能缩小,而它通常是大头。多次采样有它的用处(第 4 讲的 self-consistency 用投票提高单题的准确率),但如果目的只是”把准确率测准”,钱应该花在更多的题上。
6.3 示例的选择也是随机性
演示 4 回到第 1 讲 06 号脚本的那个实验:迷你 GPT 不认识 “question / answer” 这两个词,要靠示例看出格式。同一个模板、同一组题,只换示例(每次随机选 个,整组题共用同一组示例),换 20 组:
| 示例数 | 20 组里最低 | 平均 | 最高 | 标准差 |
|---|---|---|---|---|
| 1 个 | 12.0% | 25.7% | 38.0% | 8.5 个百分点 |
| 2 个 | 70.5% | 86.8% | 92.0% | 6.2 个百分点 |
**只换了示例,准确率就能差二十几个百分点。**这不是小模型才有的毛病:Zhao et al.(2021)在 GPT-3 上报告,示例的选择和顺序能让准确率从接近随机变到接近最好(第 2 讲的主题)。
2 个示例时,20 组之间的标准差(6.2 个百分点)比一次运行自己的标准误(约 3.7 个百分点)还大。也就是说,只用一组示例跑一次,报告的置信区间根本没有包含”换一组示例会怎样”这部分不确定性,而它比”换一批题”的不确定性还大。所以:
- 示例的选择(以及顺序、提示的措辞)要当作实验里的一个随机因素:用几组不同的示例各跑一遍,报告平均值和波动;
- 比较两种提示策略时(例如”零样本 vs 少样本”),每种都要在多组示例上比较,而不是各挑一组”看起来不错的”;
- 同一组示例下,两种策略的比较仍然可以配对(同一组题)。
7. 一份提示实验的检查清单 · A checklist
把这一篇和前置讲 P2 合在一起,一次可信的提示实验大致是这样的:
实验之前
- 写下要回答的问题和要比较的提示(预注册):比较几个,就准备校正几个。
- 把题目分成开发集(改提示、挑提示)和测试集(最后只用一次)。
- 用一个小规模的预实验估计不一致比例 ,按 §4.3 的公式规划题数;题数不够时,事先承认只能检测多大的差别。
- 固定所有参数(模型、温度、max_tokens、系统提示),写进配置;把示例的选择当作随机因素,准备几组示例。
实验之中 5. 用前置讲 P2 的调用栈:重试、缓存、记账、预算、日志。每一次调用都留下记录。 6. 每道题、每组示例、每次采样都记下编号(seed),保证能复现。
实验之后 7. 报告每个提示的准确率和 Wilson 区间;多次采样时用聚类 SE。 8. 比较两个提示用配对的方法(McNemar 检验、配对差值的区间),报告差值和它的区间,而不只是 p 值。 9. 多个比较用 Holm 校正;在测试集上只检验最后挑出来的那个。 10. 报告差别的大小、成本(token、延迟、费用)以及换示例 / 换种子之间的波动。 11. 所有表格里的数字都能从日志重新算出来。
第 17 讲会把这份清单变成一个可复用的实验框架。
8. 小结 · Summary
- 测试集是一份样本,准确率有抽样误差:SE ,题多 4 倍误差才减半。100 道题的区间大约 ±8 个百分点。
- 用 Wilson 区间,不要用 Wald 区间(小样本、高准确率时 Wald 会严重失灵)。没有公式时用 bootstrap,按题重抽。
- 同一组题上比较两个提示,用配对的方法(McNemar、配对差值区间):两个提示的结果正相关,配对能省下一大半的题。
- 功效:小的差别需要大量的题;“不显著”不等于”一样好”。用预实验估计 ,事先规划题数。
- 试了很多个提示:开发集上的第一名会虚高(赢家诅咒),多次检验会累积假阳性。开发集 / 测试集分开,比较多个时用 Holm 校正。候选越多,开发集要越大。
- 其他随机性:每题多次采样时按题聚类计算 SE;固定预算下多出题比多采样更有用;示例的选择和顺序本身就能让准确率大幅波动,要当作随机因素来处理。
9. 常见误区 · Common pitfalls
- “B 比 A 高 4 个百分点,所以 B 更好。” 先看区间。100 道题上 4 个百分点的差别通常在误差之内。
- “两个准确率的置信区间重叠,所以没有显著差别。” 这个判断方法太保守,而且对配对的数据尤其不对。要直接看差值的区间(配对)。
- “我们没发现显著差别,说明两个提示一样好。” 可能只是功效不够。报告你能检测的最小差别。
- “我在开发集上试了 30 个版本,最好的比基线高 6 个点。” 赢家诅咒。在没参与挑选的测试集上再测一次。
- “每道题采样了 10 次,所以样本量是 10 × n,结果很精确。” 同一道题的多次采样不独立,要按题聚类;精度主要由题数决定。
- “我们精心挑了 3 个示例,准确率 85%。” 换一组示例可能是 70%。示例要当作随机因素,多组取平均,或者至少报告波动。
- “p < 0.05,所以这个改进很重要。” 显著不等于重要;看差值大小、区间和成本。
- “统计显著就说明结论在别的模型上也成立。” 统计推断只推广到”同一个题目总体、同一个模型、同样的设置”。换模型要重新测(第 1 讲 §8.6)。
10. 练习 · Exercises
练习 1(手算区间)。 一个提示在 50 道题上答对 45 道。分别用 Wald 和 Wilson 方法算 95% 区间。哪个更可信?
参考答案:。Wald:,即 [0.817, 0.983]。Wilson:,center ,half ,即 [0.786, 0.957]。用
stats_kit.wilson_ci(45, 50)可以验证。Wilson 区间的中心向 0.5 收缩、上端更低:准确率 90%、50 道题时,Wald 区间的覆盖率不足 95%(01 号脚本演示 2 里 n = 30、90% 时只有 80.9%),Wilson 更可信。
练习 2(解读一个结论)。 有人报告:“A 在 100 道题上答对 62 道,B 答对 66 道,B 更好。” 用不配对的检验得到 p = 0.56。你能得出什么结论?还需要什么信息?
参考答案:不能说 B 更好,也不能说两者一样好——100 道题上 4 个百分点的差别远在误差之内(两个准确率的区间各宽约 ±9.5 个百分点)。还需要:(1) 两个提示是不是用的同一组题?如果是,应该用配对检验(需要逐题的结果,或者至少知道两者意见不同的题数 、);(2) 这是事先计划的唯一一次比较,还是从很多版本里挑出来的?(3) 示例、温度等是否一致,换一组示例结果会不会变?
练习 3(McNemar 手算)。 两个提示在同一组题上,A 对 B 错的有 4 道,A 错 B 对的有 12 道。B 显著更好吗(α = 0.05)?
参考答案:意见不同的题 ;如果一样好,。,双侧 p 值 ,不显著。注意:16 道意见不同的题里 B 赢了 12 道,看起来差别很明显,可样本太少。用
mcnemar_exact验证:p = 0.0768。
练习 4(规划题数)。 你想检测两个提示之间 5 个百分点的差别(功效 80%、α = 0.05)。预实验显示两者在 20% 的题上意见不同。用配对检验需要多少道题?如果用不配对的方法(基础准确率 70%)呢?
参考答案:配对:。不配对:
n_unpaired(0.70, 0.75)= 1251(每组)。配对省了一半的题。对比一下:同样 ,检测 3 个百分点的差别要n_paired_mcnemar(0.03, 0.2)= 1742 道,是 626 的 2.8 倍——差别变成原来的 3/5,题数大约变成 倍。
练习 5(Holm 手算)。 5 个版本分别和基线比较,p 值是 0.001、0.012、0.03、0.04、0.2。在 α = 0.05 下,不校正、Bonferroni、Holm 各认定哪几个显著?
参考答案:不校正:前 4 个(< 0.05)。Bonferroni(门槛 0.01):只有第 1 个。Holm:排好序后,门槛依次是 0.05/5 = 0.01、0.05/4 = 0.0125、0.05/3 ≈ 0.0167、0.025、0.05。0.001 ≤ 0.01 ✓,0.012 ≤ 0.0125 ✓,0.03 > 0.0167 ✗,停下。所以 Holm 认定前 2 个显著——比 Bonferroni 多发现一个,同时仍然控制族错误率。
练习 6(聚类 SE 手算)。 3 道题,每道采样 4 次:第 1 题 [1, 1, 1, 1],第 2 题 [0, 0, 0, 0],第 3 题 [1, 0, 1, 0]。分别算朴素 SE 和聚类 SE。
参考答案:总正确率 6/12 = 0.5。朴素 SE 。聚类:每道题的平均是 1、0、0.5,均值 0.5,样本标准差 ,SE ——是朴素 SE 的 2 倍。直觉:真正”独立的信息”只有 3 道题,不是 12 次采样。
练习 7(赢家诅咒,动手)。 修改 03 号脚本演示 1,把版本数从 20 改成 5 和 100(开发集 100 道题)。第一名的虚高怎样变化?为什么?
参考答案:思路:把
for _ in range(20)里的 20 改掉。版本越多,“20 个随机变量的最大值”变成”100 个的最大值”,最大值越偏离均值,虚高越大;版本少时虚高小。粗略地说, 个独立的、标准差为 的估计值,最大值大约高出均值 (这里各版本共用同一组题、彼此相关,实际的虚高会比这个式子小一些)。具体数字以你的运行为准。这也说明:自动提示优化一次试几百个候选,开发集上的分数几乎一定是虚高的。
练习 8(设计实验)。 你要回答”在这个分类任务上,少样本提示比零样本提示好吗?“手上有 600 道带标签的题、一个能用的模型、500 美元的预算。写出你的实验设计(划分、示例、参数、分析方法、报告内容)。
参考答案(一种合理的设计):(1) 划分:200 道开发集(只用来选示例的候选池、调格式),400 道测试集(只在最后用一次)。(2) 示例:从开发集里随机抽 5 组、每组 4 个示例,作为随机因素;零样本没有示例,但可以用 5 种措辞略有不同的指令,作为对应的随机因素。(3) 参数:同一个模型、同样的温度(或模型默认)、同样的 max_tokens;全部写进配置,用 P2 的调用栈记日志和缓存,先用 20 道题试跑估计费用。(4) 分析:每组示例 × 测试集得到一个准确率;主要比较”少样本 5 组的平均”vs”零样本 5 种措辞的平均”,用按题配对的差值(每道题在两种策略下的平均正确率之差)做 bootstrap 区间;同时报告 5 组之间的最小值、最大值。(5) 报告:两种策略的准确率和区间、差值和区间、组间波动、每道题的平均 token 数和费用、所有原始日志。
练习 9(显著 vs 重要)。 一个新提示在 20000 道题上把准确率从 90.0% 提高到 90.4%,配对检验 p < 0.001;但它的提示长了 800 个 token。你会建议换成新提示吗?需要考虑什么?
参考答案:差别是真的(不太可能是运气),但很小:每 1000 道题多答对 4 道。要考虑:(1) 成本:每次调用多 800 个输入 token,按 P2 的价格算一下,一年的调用量下多花多少钱;能不能用提示缓存降低(不变的部分放在前缀);(2) 延迟:更长的输入意味着更慢;(3) 这 0.4 个百分点落在哪些题上——如果正好是业务上最重要的那类题,可能值得;(4) 稳健性:换一组示例、换模型版本后这个提升还在吗?结论取决于这些,而不是 p 值本身。
11. 延伸阅读 · Further reading
- Miller, E. (2024). Adding Error Bars to Evals: A Statistical Approach to Language Model Evaluations. arXiv:2411.00640.(聚类标准误、配对比较、功效分析在 LLM 评测里的应用)
- Zhao, Z. et al. (2021). Calibrate Before Use: Improving Few-Shot Performance of Language Models. ICML.(示例的选择和顺序带来的巨大方差,第 2 讲的核心阅读)
- Dror, R. et al. (2018). The Hitchhiker’s Guide to Testing Statistical Significance in Natural Language Processing. ACL.
- Card, D. et al. (2020). With Little Power Comes Great Responsibility. EMNLP.(NLP 实验普遍功效不足)
- Agresti, A. & Coull, B. (1998). Approximate is Better than “Exact” for Interval Estimation of Binomial Proportions. The American Statistician.(Wilson 等区间为什么比 Wald 好)
- 本仓库:CS486 第 1 讲 的研究方法部分(Wilson、bootstrap、McNemar、Holm、最小可检测差异)。
12. 下一讲预告 · Next lecture
三篇前置讲到此结束:P1 讲了文字怎样变成 token,P2 讲了怎样可靠地调用模型、记录实验,P3 讲了怎样判断一个提示是不是真的更好。
第 2 讲进入原课的第一个技术主题:上下文学习(In-Context Learning)。§6.3 已经看到,只换示例就能让准确率差二十几个百分点。第 2 讲会追问这种波动从哪里来——模型有哪些系统性的偏差(偏向示例里多数的标签、偏向最近的示例、偏向常见的词),怎样用上下文校准修正它们,示例到底在教模型什么——并且用这一篇的方法,把每一个结论都放在置信区间里检验。