新模型高了 1 个点,先别急着问是不是显著。先确认:比的是不是同一批样本、同一套候选(candidate)和同一个预算?如果这些没对齐,误差条画得再漂亮,也可能在回答另一个问题。
下面用合成例子演示一份最小实验记录。没有真实业务结果,也不把离线变化当成线上收益。
先写一句能被推翻的话
“更多信息应该更好”太宽了。换成:“在相同候选池和推理预算下,加入字段 X 能改善历史稀疏样本的检索(retrieval),同时不明显损害其他样本。”
它至少给了我们四件事:改哪个变量、在哪些样本上看、固定什么、怎样才算没达到预期。阈值和主要指标应在看结果之前确定。
给比较双方锁住相同条件
| 项目 | 要记录什么 | 不一致时会怎样 |
|---|---|---|
| 数据 | 版本、时间切分、过滤、去重 | 换了人群,可能把数据差异当成模型差异 |
| 候选 | 池子、采样规则、正例定义 | 难度和分母变了,Recall 不能直接比 |
| 计算 | 训练预算、推理预算、种子 | 更多计算可能解释所谓架构收益 |
| 指标 | 公式、聚合单位、切片(slice) | 同名指标也可能不是同一把尺子 |
| 不确定性 | 重训次数、抽样方式、误差范围 | 一次幸运训练容易被讲成稳定结论 |
改标签和改架构最好先分开。预算允许时,再做一个小型组合实验,检查两者是否互相影响。
平均分上涨,也可能有人变差
这个例子只有两组,权重固定:
| 切片 | 权重 | 旧版本 | 新版本 | 变化 |
|---|---|---|---|---|
| 历史充分 | 80% | 0.60 | 0.66 | +0.06 |
| 历史稀疏 | 20% | 0.50 | 0.30 | −0.20 |
| 加权平均 | 100% | 0.58 | 0.588 | +0.008 |
平均分确实涨了,但稀疏人群退步很大。这里没有证明原因;它只告诉我们值得往哪儿查。
weights = [0.8, 0.2]
baseline = [0.60, 0.50]
candidate = [0.66, 0.30]
change = sum(weight * (new - old)
for weight, old, new in zip(weights, baseline, candidate))
assert abs(change - 0.008) < 1e-12
跨人群比较时,还要检查正例数量、候选难度和观察窗口。人群 A 的 Recall 更高,不自动说明模型对 A 的理解更好;“匹配过”也不等于消除了所有混杂因素。这组权重怎么定、换一套权重结论怎样反过来,见指标稳健性:平均值按谁的比例算。
先算配对差值,别只报两个均值
同一批测试样本上,先逐单位计算新旧差值,再汇总。单位如果是用户,就按用户统计;同一用户有许多相关事件时,不要把这些事件当成互相独立的样本。
Bootstrap 可以按独立抽样单位重采样,估计这个测试集合上的不确定性。但它不能替代重新训练,也不能告诉你换个数据分布后会怎样。抽样波动、训练波动和分布变化,是三件不同的事。配对差值和精确检验的算例见指标稳健性。
切片也不是越多越好。先写下主要切片;看完结果才发现的模式可以记录为探索发现,再用新的留出集复核,避免从几十张表里挑最漂亮的一张。
从发现到下一步
flowchart TD
A["固定协议,跑新旧版本"] --> B["看配对差值与主要切片"]
B --> C["查样本和失败类型"]
C --> D["一次只检验一个解释"]
D --> E["在独立留出集复核"]
E --> F["必要时进入受控线上验证"]
没有变化时,检查实验有没有足够灵敏、改动是否真的进入计算路径。出现变化时,问它有没有跨种子、跨时间或跨环境复现。两种情况下,都不要只拿一张总分表收尾。
继续读:指标稳健性 · Judge 的偏差与验证。
本页术语 3
- 候选 candidate
- 召回阶段捞出来、等待精排挑选的内容
- 检索 retrieval
- 从外部语料里找出相关内容
- 切片 slice
- 按内容或用户属性划分的子群体,用来检查平均值掩盖了什么