LLM评测:置信区间怎么算

黎 浩然/ 14 10 月, 2026/ 大语言模型/LARGELANGUAGEMODEL/LLM, 机器学习/MACHINELEARNING, 研究生/POSTGRADUATE, 计算机/COMPUTER/ 0 comments

LLM 在一批题上从88分涨到90分,值得检查,但还不够支持“新方案更好”。先看题目从哪里来、成功如何判定、样本是否独立,再给分数配上不确定性;同题比较还要保留每道题的变化,而不是只剩两个平均数。

文章目录
  1. 先问这个百分比想代表谁
  2. 同样80%,25题与100题不同
  3. 为什么不直接用对称误差条
  4. 把样本数和区间一起输出
  5. 88分到90分,要回到那100道题
  6. 同一道题重复十次,不等于多了十道题
  7. 别让分母在失败时悄悄变化
  8. 让一次评测留下可复查的记录
  9. 参考资料

先问这个百分比想代表谁

固定题集上的正确率,是这一批题的描述。若100题里答对80题,80%本身没有统计歧义。真正需要区间的时刻,是想用这批题推断未来相似请求的表现;这时就引入了抽样、目标分布与评测协议的假设。

例如,用一个人为构造的客服问答集合检查提示词。题目全是精心挑选的短问句,却把结论写成“全部用户请求成功率80%”,问题并不在小数点精度,而在覆盖范围。区间再窄,也不能把没出现过的长上下文、多轮状态或边缘需求补进样本。

先写一句可检查的目标:“估计某种请求来源、某个时间窗口、固定评分规则下的一次回答成功概率。”再决定抽样单位。模型版本、提示词、工具和检索数据若同时变化,分数变化就不能归因给其中一个因素。这里讨论二元成功率,不把它直接套到任意连续评分上。

同样80%,25题与100题不同

两组虚构样本分别是20/25与80/100,点估计都是80%。在独立、同一成功概率的伯努利试验模型下,使用名义双侧95%的 Wilson 区间,前者约为60.9%–91.1%,后者约为71.1%–86.7%。第二组更窄,但仍不代表没有抽样误差。

20/25 → 60.9%–91.1%
80/100 → 71.1%–86.7%
0%50%100%
原创 Wilson 区间图:两组人工样本都为80%,样本数不同。横轴为0–100%。

“95%”描述的是区间构造方法在重复抽样框架中的名义覆盖水平,不是观察到这个区间后,固定真值有95%的概率在里面。Wilson 是近似方法,其实际覆盖也不保证在每个参数和样本量上都恰好95%。想严谨地讨论业务总体,首先还得满足前面的抽样假设。

样本变多通常有助于减少随机不确定性,但没有一个“评测至少100题就可靠”的通用门槛。问题差异、希望识别的提升幅度、错误成本和预算都影响设计。尤其是1–2个百分点的小变化,比大幅错误更需要充分、相关且预先确定的测试。

为什么不直接用对称误差条

常见的简式是 p̂±1.96√[p̂(1-p̂)/n]。它容易计算,但在小样本或接近0、1时可能给出不合理边界。25次全部成功时,这个简式甚至给出零宽度,显然不能据此断言未来永不失败。

NIST 统计手册列出了 Wilson 区间的构造。把其中的双侧形式写成中心与半宽,比较容易实现:

p_hat = k / n
denominator = 1 + z²/n
center = (p_hat + z²/(2n)) / denominator
half = z × sqrt(p_hat(1-p_hat)/n + z²/(4n²)) / denominator
interval = [center - half, center + half]
z ≈ 1.959964   # nominal two-sided 95%

这里 k 是成功次数,n 是总次数,z 对应所选双侧名义覆盖水平。中心并不一定等于原始正确率,所以图上的区间不必围绕80%对称。25次全成功时,Wilson 下界约86.7%;25次全失败时,上界约13.3%。二者都保留了有限样本的不确定性。

这些是方法算例,不是真实模型测评。更小样本或少量失败的场景也可能采用精确二项区间等其他方法;选择应与推断目标一起说明,不能在看过结果后只挑最有利的一种算法。

把样本数和区间一起输出

import math

def wilson95(k, n):
    if type(k) is not int or type(n) is not int:
        raise ValueError("Counts must be integers")
    if n <= 0 or not 0 <= k <= n:
        raise ValueError("Expected 0 <= k <= n and n > 0")
    z = 1.959963984540054
    p = k / n
    denominator = 1 + z * z / n
    center = (p + z * z / (2 * n)) / denominator
    half = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / denominator
    low = 0.0 if k == 0 else max(0.0, center - half)
    high = 1.0 if k == n else min(1.0, center + half)
    return low, high

def paired_counts(rows):
    gains = losses = same = 0
    for a, b in rows:
        if a not in (0, 1) or b not in (0, 1):
            raise ValueError("Expected binary scores")
        if a == b:
            same += 1
        elif b == 1:
            gains += 1
        else:
            losses += 1
    return gains, losses, same

for k, n in ((20, 25), (80, 100), (0, 25), (25, 25)):
    low, high = wilson95(k, n)
    assert 0 <= low <= k / n <= high <= 1
    print(k, n, f"[{low:.4f}, {high:.4f}]")
small = wilson95(20, 25)
large = wilson95(80, 100)
assert large[1] - large[0] < small[1] - small[0]
assert wilson95(0, 25)[0] == 0
assert wilson95(25, 25)[1] == 1
for bad in ((0, 0), (26, 25), (-1, 25), (1.5, 25)):
    try:
        wilson95(*bad)
    except ValueError:
        pass
    else:
        raise AssertionError("Invalid counts accepted")

rows = [(1, 1)] * 84 + [(0, 0)] * 6 + [(1, 0)] * 4 + [(0, 1)] * 6
assert len(rows) == 100
assert sum(a for a, b in rows) == 88
assert sum(b for a, b in rows) == 90
assert paired_counts(rows) == (6, 4, 90)
print("gains, losses, unchanged:", paired_counts(rows))

try:
    paired_counts([(1, 2)])
except ValueError:
    pass
else:
    raise AssertionError("Nonbinary score accepted")

这段原创 Python 代码已执行:核对两组80%样本的区间、区间宽度变化、全成功与全失败,以及非法计数。输出依次约为 [0.6087,0.9114]、[0.7112,0.8666]、[0,0.1332]、[0.8668,1]。一次 Wilson 计算使用常数次算术操作,后面的逐题统计对 n 条记录为 O(n) 时间、O(1) 额外空间,不计已存输入。

实际报告不要只留“80%±若干”。同时保存 k、n、区间方法、名义水平和评分协议。公式能处理边界,并不表示题目独立性、评分质量或代表性也已经通过验证;代码不会替你识别这些设计问题。

88分到90分,要回到那100道题

现在换一个独立的教学例子:A与B都做同样100题,84题都对、6题都错、4题A对B错、6题A错B对。于是A正确88题,B正确90题。净提升2个百分点的背后,是6次收益和4次退步,而非只有两道题变化。

同一批100道题
↓
新增正确6题:A错 → B对
退步4题:A对 → B错
不变90题:84题都对、6题都错
↓
净变化:(6 − 4) / 100 = +2个百分点
原创逐题变化图,使用虚构二元评分。它是描述性分解,不是显著性检验。

这一分解能把下一步工作变具体:检查新正确的题是否符合目标需求,退步的题是否集中在关键类别。若4道退步题都属于必须保住的行为,单看总分会遗漏部署风险。是否上线还需结合预先定义的约束,不能让平均值替你决定。

统计比较也要保留配对结构。把同一题上的A、B结果当成完全无关的两组,会丢掉信息;仅凭两个区间重叠或不重叠,也不能代替与设计相符的差异检验或差值区间。图和代码只做描述性统计,没有输出显著性结论。

同一道题重复十次,不等于多了十道题

重复生成可以帮助观察某道题在采样随机性下的稳定性,但它没有扩展题目覆盖范围。同一条会话、同一份文档派生出的多道题,也可能共享难度或信息。若把这些相关记录全部当独立抽样,公式里很大的 n 容易让区间显得过于精确。

先根据使用场景分开两个问题:想知道某道题重复回答的成功情况,还是想知道未来不同请求上的表现。前者围绕该题和生成设置,后者还要覆盖请求差异。需要按会话或文档分组分析时,应采用匹配设计的方法,而不是把相关性藏进汇总表。

自动评分也会引入另一层误差。若评分器偏爱较长答案,方案B只是变啰嗦就可能得分更高。固定评分标准,抽取有代表性的成功、失败与分歧样本人工复核,比先把区间算到小数点后四位更有价值。有关失败环节的定位,可结合RAG评测中的错误分解。

别让分母在失败时悄悄变化

评测记录至少要能连接题目ID、输入版本、模型配置、输出、评分结果与执行状态。成功率的分母在运行前确定,超时、接口错误、无法解析和拒答也要留下状态。只导出能成功解析的答案,会把最需要检查的一部分请求消失在报表外。

是否把基础设施故障算作任务失败,取决于目标。如果评估整条服务链,可把按时交付纳入成功定义;如果隔离考察模型能力,也可预先规定基础设施排除条件。但两种口径应分别报告总请求数、有效评分数与排除数,不能结果不好时才更换规则。

多次尝试的评测同样需要固定预算。一次回答成功与多次尝试中任意一次成功,是不同指标;增加尝试次数可能提高后者,却同时增加调用成本与时延。不能拿新方案的多次机会,对比旧方案的一次机会,再把差值全算成模型进步。相关指标可参照pass@k的定义。

保留失败案例不只是统计习惯。它能让下一轮开发回答:究竟该修模型、提示词、解析器还是服务链。没有这条证据链,即使增加样本量,往往也只是更精确地描述了一个含糊指标。

让一次评测留下可复查的记录

对一次提示词或检索改动,保留同一份冻结测试集、逐题标识、A/B版本与配置、输出和评分依据。把调试集与最终评估集分开;反复看同一批题并调参后,那批题已经参与选择,不能再当作完全未见过的检验。

预先决定主指标与关键子类,先检查回归,再看收益。准确率之外还有时延、成本、格式约束与任务覆盖等条件。HELM 的原始论文强调标准化条件与多指标评估;它最初发表于2022年、2023年发表于TMLR,这里借用其评测视角,不复述模型排名,也不把它包装成新论文。

如果一次评测只能留下一个更好的习惯,就让每个漂亮百分比旁边都能找到分母和原始证据。它能帮助你区分“在这批题上发生了变化”“对目标请求可能有效”与“已足以支持发布”这三个不同层次。分数有了解释,才值得为后续决策投入时间。

Read the English version

参考资料

补发说明:本文实际于2026年10月14日晚补发,文章日期保留原计划北京时间09:00;引用材料早于计划时段,图中数值均为教学算例。

支持

如果文中的解释或示例帮你解决了问题、节省了时间,欢迎自愿打赏支持本站。

微信支持二维码,点击查看大图
微信
支付宝支持二维码,点击查看大图
支付宝
Buy Me a Coffee,点击支持本站
Buy Me a Coffee

二维码可点击放大。更多支持方式见支持页面。

Share this Post

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注

*
*