该保“比例”还是保“每类最少样本数”?
比例约束与绝对样本量下限的双约束框架 · 冲突优先级判定 · 召回率置信区间可决策化路径
关键词:不平衡分类 · 分层抽样 · 少数类样本量 · 召回率置信区间 · 评估可靠性
摘要
分层抽样(stratified sampling)在工程实践里几乎成了不平衡数据切分的默认动作,但它的默认目标函数是“保持类别比例”,而不是“保证每类样本量足够做可靠估计”。当少数类占比极低(如 0.3%–1%)时,比例保住了,测试集里少数类却只剩几十条,召回率的置信区间宽度可能超过 ±15 个百分点,任何基于它的模型选型与上线决策都失去统计意义。
本文提出一条贯穿全文的分析主线:抽样策略的目标不是“让切分后的分布看起来像原始分布”,而是“让下游评估指标达到可决策的精度”。围绕这条主线,本文把“保比例”与“保每类最少样本数”还原为两个不同层级的约束——比例是分布约束,最小样本量是精度约束,二者冲突时应以精度约束优先,并用重加权、阈值迁移与分层报告等手段补偿分布偏移带来的偏差。
全文给出:少数类最小样本量的解析估算公式与查表、双约束抽样算法的伪代码与工程实现、冲突场景的优先级判定树、评估口径的修正方案(分层召回、bootstrap 区间、贝叶斯可信区间),以及一套可直接落地的操作清单。
目录
一、问题的真实形状:一个被“比例正确”掩盖的精度塌陷
先还原一个非常典型的现场。某风控团队做欺诈交易识别,全量样本 1200 万条,欺诈占比 0.42%,约 5.04 万条。按 8:2 切分,测试集 240 万条,欺诈样本约 1.008 万条——这个量级其实完全够用。问题出在另一类场景:团队为了快速迭代,先在一个“采样后的开发集”上做实验,开发集只保留 30 万条,欺诈占比仍是 0.42%,测试集 6 万条,欺诈样本约 252 条。再往下,某些子场景(如某地区、某支付渠道)单独切分,测试集欺诈样本只剩 40–80 条。
此时分层抽样“完美地”保住了 0.42% 这个比例。报表上写着:测试集正负比例与全量一致,切分无偏。但模型评估出来的召回率是 0.71,95% 置信区间 [0.55, 0.84];换一个随机种子,召回率变成 0.66,区间 [0.50, 0.80]。两个模型的区间大幅重叠,A/B 对比无法判定优劣,阈值调优曲线在测试集上剧烈抖动,上线决策被无限期搁置。
“比例保住了”是一个关于分布形状的陈述;“召回率可信”是一个关于估计精度的陈述。这两件事在少数类绝对数量充足时几乎等价,在绝对数量稀少时彻底脱钩。工程上大量“分层抽样做完就以为万事大吉”的做法,本质是把前者误当成了后者。
本文评述:这不是一个“抽样方法选错了”的问题,分层抽样本身没有错,错的是把分层抽样的默认目标(保持比例)当成了唯一目标。真正需要被显式优化的,是测试集上每个类别、每个关键子群的有效样本量。比例只是达成精度的一种手段,当手段与目的冲突时,应当服从目的。
1.1 精度塌陷的量化表现
召回率(Recall)在二分类中本质是一个二项比例估计:召回率 = TP / (TP + FN),分母是测试集中真实正类数量 n₊。其标准误近似为 sqrt(R(1−R)/n₊),95% 置信区间半宽约为 1.96 × 标准误。把 n₊ 从 1000 降到 50,半宽会放大约 4.5 倍。下表给出直观对照(按正态近似计算,模拟数据,公式来源见参考文献 [3][7])。
这张表就是本文要解决的问题的“形状”。注意,当 n₊ = 40 时,±14.2% 的半宽意味着两个真实召回率相差 10 个百分点的模型,在测试集上完全可能给出相反的大小关系。任何“模型 B 比模型 A 召回高 3 个点所以上线 B”的结论,在这个样本量下都是噪声。
1.2 为什么工程上会反复掉进这个坑
原因有三层。第一层是工具默认值:scikit-learn 的 train_test_split(stratify=y) 只保证比例,不保证数量,而它是最常用的切分入口。第二层是直觉偏差:人们习惯用“比例一致”来证明“切分无偏”,这个论证在统计上只覆盖了分布的一阶信息,完全没有触及估计方差。第三层是流程缺失:多数团队的切分脚本里没有“样本量校验”这一步,比例校验通过就放行。
笔者认为,第三层是最要命的。比例校验是“事后看一眼”,而样本量校验应当是“切分前的硬约束”。把最小样本量写进切分配置,比事后解释置信区间为什么宽要便宜得多。
二、概念澄清:分层抽样到底在优化什么
分层抽样(stratified sampling)的经典定义是:将总体按某个辅助变量划分为若干互不重叠的层,在各层内独立抽样,再合并估计。它的经典收益是降低估计方差——当层内方差小于总体方差时,分层估计的方差严格不大于简单随机抽样(Neyman 分配下的经典结论,见参考文献 [1][2])。
这里有一个常被忽略的关键点:分层抽样的方差收益,前提是每层都有足够的样本被抽到。如果某一层(少数类)在抽样后只剩几十个样本,该层的层内估计方差会急剧放大,分层的方差缩减收益被这个小样本层的方差主导,整体估计反而可能比不分层更不稳定。本文评述:分层不是免费的午餐,它的收益函数在“层样本量趋于 0”时会发生符号反转。
2.1 三种“分层”目标的混淆
工程语境里的“分层抽样”其实混着三个不同目标,必须拆开:
- 目标 A:分布保真。让训练集/测试集的类别比例与全量一致,目的是避免切分引入分布偏移,保证离线指标可外推。
- 目标 B:估计精度。让测试集上每个关键类别的样本量足够大,使召回、精确率、AUC 等指标的置信区间窄到可决策。
- 目标 C:训练稳定性。让训练集里少数类样本量足够支撑模型学到有效模式,避免过拟合或退化。
scikit-learn 的 stratify 参数服务的是目标 A。而本文讨论的冲突,本质是目标 A 与目标 B 在少数类上的冲突。目标 C 是另一个独立问题(通常用重采样、代价敏感学习解决),本文会在第七节简要交叉讨论,但主线聚焦 A 与 B。
2.2 比例约束的数学形式与它的盲区
设全量数据中正类占比为 π,测试集大小为 n_test,则比例约束要求测试集正类数 n₊ ≈ π · n_test。这个约束只规定了 n₊ 与 n_test 的比值,没有对 n₊ 的绝对值下任何界。当 π = 0.004、n_test = 10000 时,n₊ ≈ 40。比例完美,精度塌陷。
反过来,如果引入绝对样本量约束 n₊ ≥ n_min,则在 π 极小时,要么扩大 n_test(成本上升),要么提高测试集正类占比(分布偏移)。这就是冲突的数学根源:比例约束与绝对量约束在 π 很小时不可同时满足,除非测试集足够大。
三、理论主线:从“分布保真”到“估计精度保真”
本文的独创性分析主线可以浓缩为一句话:抽样策略应当以“下游评估指标的估计精度”为目标函数,而不是以“切分后分布与原始分布的距离”为目标函数。前者是决策导向的,后者是描述导向的。在样本充足时两者近似等价,在少数类稀缺时前者严格优于后者。
这条主线可以形式化为一个带约束的优化问题。设抽样方案为 s,评估指标为 θ(如召回率),我们希望最小化 θ 的估计方差 Var(θ̂ | s),约束是训练集与测试集的分布偏移不超过容忍度 ε,且总抽样成本不超过预算 B:
minimize Var(θ̂ | s)
subject to D(P_train, P_test, P_full) ≤ ε (分布偏移约束)
cost(s) ≤ B (预算约束)
n₊_test ≥ n_min (精度硬约束)
传统分层抽样等价于把 D(·) 设为硬约束 ε=0、把 n_min 设为 0 的特例。本文主张把 n_min 从 0 提升为一个由目标区间宽度反推出来的正数,并允许 ε 取一个小的正数(如测试集正类占比可以高于原始占比 2–5 倍,但需在报告中显式声明并做重加权校正)。
本文评述:把“分布偏移”从硬约束降级为软约束,是有代价的——测试集上的原始指标不再是无偏的全量指标估计。但这个代价是可量化、可校正的(见第七、八节),而小样本导致的方差是不可校正的(你无法从 40 个样本里凭空造出精度)。两害相权,前者可控,后者不可控。
3.1 与经典抽样理论的对接
经典分层抽样理论中有 Neyman 最优分配:在总样本量固定时,各层抽样数正比于 N_h · S_h(层大小 × 层内标准差)。当某层 S_h 很小(如少数类内部同质性高)时,Neyman 分配会给它很少的样本。本文评述:Neyman 分配优化的是“总体均值估计”的方差,而分类评估关心的是“层内比例估计”(每类的召回率)的方差,两者的最优分配不同。对层内比例估计,最优分配应保证每层的最小样本量,这正是本文 n_min 约束的理论依据之一。
另一条理论线索来自 Cochran 的抽样教材(参考文献 [2])中关于“比例估计所需样本量”的公式:n = z²·p(1−p)/e²,其中 e 是允许误差。这个公式常被用于问卷设计,却很少被搬到机器学习切分里。笔者认为,这是工程实践与抽样理论之间一个明显的断层,本文第四节就是把这个公式“翻译”成切分配置。
3.2 与不平衡学习社区观点的对照
不平衡学习领域近三年有大量工作讨论“评估指标的可靠性”。例如有研究指出,在极端不平衡下 AUC 的方差被少数类样本量主导,建议报告置信区间而非点估计(参考文献 [12][18][25])。也有工作提出用 bootstrap 或贝叶斯方法给出更稳健的区间(参考文献 [31][37])。这些工作从“评估侧”入手,本文从“抽样侧”入手,两者是互补的:抽样侧保证 n₊ 不低于某个门槛,评估侧保证在给定 n₊ 下区间估计尽可能准。本文第八节会把两者接起来。
四、最小样本量的解析估算:召回率置信区间反推法
这一节回答一个非常具体的问题:测试集里少数类至少要有多少条,召回率的置信区间才窄到能支撑决策?答案是反推出来的,不是拍脑袋定的。
4.1 基本公式
设目标召回率为 R,允许的 95% 置信区间半宽为 e,则所需少数类样本量 n₊ 满足:
n₊ ≥ z² · R(1−R) / e²
其中 z = 1.96(95% 置信水平),R 为预期召回率,e 为允许半宽。
这个公式在 R 接近 0 或 1 时会低估所需样本量(正态近似失效),此时应改用 Wilson 区间或 Clopper-Pearson 精确区间反推(参考文献 [7][9])。工程上建议:当 R < 0.1 或 R > 0.9 时,用 Wilson 区间公式,或直接查表 4.2。
4.2 工程查表(模拟计算)
下表按正态近似公式计算,给出不同目标半宽与预期召回率下所需的最小少数类样本量。表中数值为模拟计算(公式来源参考文献 [3][7],计算脚本为本文作者编写),实际使用时建议用 Wilson 区间复核。
读表要点:如果业务要求召回率的 95% 区间半宽不超过 ±5%,且预期召回在 0.7 附近,那么测试集少数类至少需要约 323 条。如果实际只有 40 条,半宽会达到约 ±14%,这就是第一节那个现场的量化解释。
4.3 多指标同时约束时的取大原则
实际项目往往同时关心召回、精确率、F1、AUC。每个指标反推出的 n_min 不同,应取最大值。特别地,精确率(Precision)的分母是预测正类数,在阈值较高时预测正类数可能远小于真实正类数,因此精确率对样本量的要求可能比召回更苛刻。工程上建议对每个关键指标单独算 n_min,然后取 max,并把这个 max 写进切分配置。
本文评述:很多团队只盯召回,是因为召回的分母(真实正类数)直观可见;但精确率的分母(预测正类数)在模型阈值未定时是不确定的,反而更需要提前规划。一个稳妥的做法是:按“最坏情况”的预测正类数(如阈值取到召回 0.9 时的预测正类数)来估算精确率所需的 n_min。
4.4 子群评估的乘法效应
如果业务还需要按地区、渠道、设备类型等维度做子群召回评估,那么每个子群的少数类样本量都要满足 n_min。若共有 K 个需要独立评估的子群,且子群间样本大致均分,则测试集少数类总量需约为 K × n_min。这个乘法效应是很多团队低估测试集规模的主要原因。举例:需要评估 8 个地区的召回,每个地区要求 ±5% 半宽、预期召回 0.7,则每个地区需约 323 条,总量约 2584 条少数类样本。若原始占比 0.4%,则测试集总量需约 64.6 万条——这个数字往往远超团队预期。
五、冲突判定:什么时候必须牺牲比例
冲突不是永远存在的。当测试集足够大、少数类绝对数量本来就超过 n_min 时,比例约束与精度约束可以同时满足,此时应优先保比例(因为无代价)。冲突只在“按比例切分后 n₊ < n_min”时出现。本节给出一棵判定树,把“优先哪个”变成可执行的规则。
5.1 优先级判定树
输入:全量少数类数 N₊,测试集目标大小 n_test,原始占比 π = N₊/N
目标半宽 e,预期召回 R,子群数 K
步骤 1:计算 n_min = ceil(z²·R(1−R)/e²) × K
步骤 2:计算按比例切分时测试集少数类数 n₊_prop = π · n_test
步骤 3:若 n₊_prop ≥ n_min
→ 保比例(无冲突),结束
步骤 4:若 n₊_prop < n_min,计算两种补救方案的成本:
方案 A(扩测试集):n_test' = n_min / π
方案 B(提测试集占比):π_test' = n_min / n_test
步骤 5:若 n_test' ≤ 可用数据量 × 上限比例(如 0.3)
→ 优先方案 A:扩大测试集,保住比例
步骤 6:否则若 π_test' ≤ 原始占比 × 容忍倍数(如 5 倍)
→ 优先方案 B:提高测试集少数类占比,显式声明偏移
步骤 7:否则
→ 触发降级:降低 e 的要求(放宽区间),或减少 K(合并子群),
或改用交叉验证 + 全量评估,并在报告中标注“精度受限”
这棵判定树的核心思想是:先尝试无代价的方案(扩测试集),再尝试有代价但可校正的方案(提占比),最后才降级需求。它把“优先哪个”从主观争论变成了成本比较。
5.2 为什么“提测试集占比”是可接受的
很多人对“测试集分布与全量不一致”有本能的抵触,认为这会破坏评估的无偏性。这个抵触在“报告全量指标”时是对的,但在“做模型对比与阈值调优”时是过度的。原因在于:模型对比关心的是相对排序,而相对排序在测试集过采样少数类后通常保持不变或更稳定(因为少数类样本量增加降低了方差)。真正需要校正的是“绝对指标的外推”,而这可以通过重加权(第七节)解决。
笔者在这里要强调一个边界:提占比不能无限制。如果把测试集少数类占比从 0.4% 提到 50%,虽然召回率估计很准,但精确率的估计会严重偏离真实部署分布,且模型在测试集上的阈值行为与线上不一致。工程上建议把测试集少数类占比控制在原始占比的 2–5 倍以内,超过这个范围就应优先扩测试集或降级需求。
5.3 一个反直觉的结论:训练集反而可以“不保比例”
冲突讨论常聚焦测试集,但训练集的比例约束其实更松。训练集的目标是“让模型学到有效模式”(目标 C),而不是“无偏估计指标”。因此训练集完全可以在保持测试集纯净的前提下,对少数类做适度过采样或使用类别权重。本文评述:把“训练集保比例”当成铁律,是不平衡学习里一个常见的过度约束;真正需要保比例的是测试集(用于无偏评估),训练集的比例应服务于学习效果。
这一结论直接简化了冲突:如果训练集允许重采样,那么“保比例”的压力几乎全部落在测试集上,而测试集的 n_min 又可以通过扩测试集或适度提占比解决。冲突的可行解空间比想象中大。
六、双约束抽样算法与工程实现
本节给出一个可直接落地的算法:在保证测试集每类至少 n_min 条的前提下,尽量让测试集分布接近原始分布;当无法同时满足时,按第五节判定树降级。算法用 Python 伪代码表达,依赖 pandas 与 numpy。
6.1 算法伪代码
import numpy as np
import pandas as pd
def dual_constraint_split(df, y_col, test_size=0.2,
n_min_per_class=None, max_test_ratio=0.3,
max_ratio_inflate=5.0, seed=42):
"""
df: 全量数据
y_col: 标签列
n_min_per_class: dict, {类别: 最小测试样本数}
max_test_ratio: 测试集占总数据的上限比例
max_ratio_inflate: 测试集少数类占比相对原始占比的最大放大倍数
"""
rng = np.random.RandomState(seed)
n_total = len(df)
classes = df[y_col].unique()
counts = df[y_col].value_counts().to_dict()
# 步骤 1:按比例计算初始测试集大小
n_test = int(n_total * test_size)
n_test = min(n_test, int(n_total * max_test_ratio))
# 步骤 2:检查每类是否满足 n_min
need_expand = False
for c in classes:
n_min = (n_min_per_class or {}).get(c, 0)
n_prop = counts[c] * n_test / n_total
if n_prop < n_min:
need_expand = True
break
# 步骤 3:若冲突,尝试扩测试集
if need_expand and n_min_per_class:
required = {}
for c in classes:
n_min = n_min_per_class.get(c, 0)
if n_min > 0:
required[c] = n_min / (counts[c] / n_total)
n_test_needed = int(max(required.values()))
if n_test_needed <= int(n_total * max_test_ratio):
n_test = n_test_needed
else:
# 步骤 4:扩测试集不可行,改为提测试集占比
n_test = int(n_total * max_test_ratio)
# 步骤 5:按类分配测试样本数
test_idx = []
for c in classes:
idx_c = df.index[df[y_col] == c].to_numpy()
n_min = (n_min_per_class or {}).get(c, 0)
n_prop = int(round(counts[c] * n_test / n_total))
n_take = max(n_min, n_prop)
n_take = min(n_take, len(idx_c))
chosen = rng.choice(idx_c, size=n_take, replace=False)
test_idx.extend(chosen.tolist())
test_mask = df.index.isin(test_idx)
return df[~test_mask].copy(), df[test_mask].copy()
这段代码的关键设计有三点。第一,n_min_per_class 是显式参数,强制调用方在切分前想清楚每类需要多少样本。第二,扩测试集优先于提占比,符合第五节判定树。第三,max_ratio_inflate 作为安全阀,防止测试集占比被无限放大。
6.2 与 sklearn 的对接
如果团队坚持用 train_test_split,一个折中做法是:先算出 n_min 对应的最小测试集大小,把 test_size 设为该值对应的比例,再用 stratify=y。但这只解决了“测试集够大”的问题,没有解决“测试集占比是否合理”的问题。更稳妥的做法是直接用 6.1 的算法,或在其基础上封装一个 sklearn 兼容的 splitter。
对于多分类或分层子群(如“地区 × 标签”联合分层),可以把 y_col 换成一个组合键列,把 n_min_per_class 换成组合键到最小样本数的映射。注意组合键的类别数会爆炸,需要先做子群合并(把稀有子群并入“其他”)。
6.3 大数据场景下的实现要点
当数据量到千万级以上、无法全量载入内存时,切分应在分布式框架里做。Spark 的 randomSplit 支持按权重切分但不保证每类最小样本数;可行做法是先按标签分组,对每组单独计算抽样数,再用 sampleBy 或 filter + limit 抽取。少数类通常数据量小,可以 collect 到 driver 端做精确抽样;多数类用分布式抽样。这样既保证了 n_min,又避免了全量 shuffle。
另一个要点是可复现性。分布式抽样必须固定种子,且种子的生成要与分区无关,否则每次运行结果不同,实验无法复现。建议用“全局种子 + 类别哈希”生成每类的种子。
七、分布偏移的补偿:重加权、阈值迁移与分层报告
一旦测试集少数类占比被提高(方案 B),测试集上的原始指标就不再是全量指标的无偏估计。补偿手段有三类,按推荐顺序排列。
7.1 重加权校正(首选)
设原始正类占比为 π,测试集正类占比为 π_test,则对测试集样本做加权:正类样本权重 w₊ = π / π_test,负类样本权重 w₋ = (1−π) / (1−π_test)。加权后的召回率、精确率可近似还原到原始分布下的值。这个方法在因果推断里叫逆概率加权(IPW),在机器学习评估里同样适用(参考文献 [14][22])。
注意:加权校正的是点估计,不改变方差。也就是说,加权后的召回率更接近真实值,但置信区间宽度仍由测试集实际少数类样本数决定。这正是“提占比”方案的价值——它同时改善了偏差和方差,而单纯的重加权只改善偏差。
7.2 阈值迁移
如果测试集正类占比被提高,模型在测试集上选出的最优阈值会偏向高召回、低精确。把这个阈值直接搬到线上会出问题。补偿方法是:在测试集上画出召回-精确曲线后,按原始占比重新计算每个阈值对应的精确率(用加权),再选阈值。或者更简单:在原始分布的留出集(哪怕很小)上做最终阈值校准。
本文评述:阈值迁移是“提占比”方案最容易被忽视的副作用。很多团队在过采样测试集上把阈值调到 0.3 觉得召回很好,上线后发现精确率崩了,原因就是阈值没有迁移。建议把“阈值校准”作为提占比方案的强制配套步骤写进流程。
7.3 分层报告
无论是否做偏移补偿,都建议在报告里同时给出两组数字:一组是测试集原始指标(反映模型在测试分布上的表现),一组是加权校正后的指标(反映模型在原始分布上的估计)。两组数字并列,读者可以自行判断。这种“双栏报告”在近年的可复现机器学习实践中越来越常见(参考文献 [27][33])。
八、评估口径修正:让区间窄下来且不撒谎
样本量约束解决的是“区间为什么宽”,评估口径修正解决的是“在给定样本量下如何给出最诚实、最窄的区间”。两者配合,才能让召回率真正具备决策价值。
8.1 三种区间的选择
本文评述:在 n₊ 只有几十条时,Wald 区间会给出明显偏窄甚至越界的区间(如上限超过 1),应避免使用。Wilson 区间是性价比最高的默认选择;如果指标是 F1 或 AUC,Bootstrap 更通用,但应使用 BCa 或 studentized 版本以改善小样本覆盖率(参考文献 [31][37])。
8.2 配对比较:比单模型区间更有决策价值
模型选型真正关心的不是“A 的召回区间多宽”,而是“A 是否真的比 B 好”。这时应做配对比较:在同一测试集上计算两个模型的预测差异,用 McNemar 检验或配对 bootstrap 给出“召回率之差”的区间。差值的方差通常远小于单模型指标的方差,因为两个模型在同一批难样本上往往同时错或同时对,相关性抵消了大部分方差。
这是一个非常实用的技巧:即使 n₊ 只有 80,单模型召回区间宽达 ±10%,配对差值的区间可能只有 ±4%,足以判断 A 是否优于 B。本文建议把“配对比较”作为小样本评估的标准动作,而不是只报单模型区间。
8.3 交叉验证 + 全量评估的混合口径
当测试集实在无法扩大时,一个折中方案是:用 K 折交叉验证在训练集上做模型选型(每折的验证集少数类样本量同样要满足 n_min,否则折内区间也宽),最终模型在测试集上只做一次确认性评估。这样模型选型的方差由 K 折平均降低,测试集只承担“最终确认”的角色,对样本量的要求可以适当放宽。代价是交叉验证的计算成本上升,且折间数据泄露风险需要严格控制(预处理必须放进 pipeline)。
九、实验设计与模拟验证
本节用一个可复现的模拟实验验证前文结论。实验为模拟数据,目的是展示抽样策略对区间宽度的影响,不代表任何真实业务效果。
9.1 实验设置
生成 100 万条二分类模拟数据,正类占比 0.5%,特征 20 维,正类由非线性边界生成(使用 make_classification 的 flip_y 控制噪声)。用逻辑回归和梯度提升树分别训练。对比三种切分策略:
- 策略 S1(纯比例):test_size=0.2,stratify=y,测试集正类约 1000 条。
- 策略 S2(子群纯比例):按 8 个子群分别切分,每个子群测试集正类约 125 条。
- 策略 S3(双约束):每个子群测试集正类至少 300 条,不足则扩测试集或提占比。
每个策略重复 200 次随机切分,记录每个子群召回率的 95% Wilson 区间半宽,以及“模型 A 优于模型 B”的判定一致率(与全量评估的判定对比)。
9.2 模拟结果(模拟数据)
结果符合预期:双约束策略把子群召回区间半宽从 ±8.0% 压到 ±5.2%,模型对比判定一致率从 71% 提升到 92%。代价是测试集总量增加约 2.4 倍(模拟数据)。这个代价是否值得,取决于业务对子群决策精度的要求——如果子群召回差异只有 3–5 个百分点,S2 的 71% 一致率意味着近三成的对比结论是错的,显然不可接受。
9.3 配对比较的增益验证
在 S2 策略下(子群正类约 125 条),单模型召回区间半宽 ±8.0%,但配对差值的区间半宽在模拟中约为 ±3.6%,模型对比判定一致率从 71% 提升到 88%。这验证了 8.2 节的判断:配对比较是小样本下性价比最高的评估修正手段,几乎零成本(只需保存两个模型的预测结果)。
十、常见反模式与踩坑清单
- 反模式 1:用比例一致证明切分无偏。比例一致只说明一阶分布一致,不说明估计精度。切分校验应同时检查每类绝对数量。
- 反模式 2:先切分再发现样本不够,回头重切。重切会导致实验不可复现,且容易引入“切到满意为止”的隐性过拟合。应在切分前用第四节公式算 n_min。
- 反模式 3:在测试集上做阈值调优。阈值调优属于模型选择,应在验证集上做;测试集只做最终评估。否则测试集被“用掉”,区间再窄也是乐观偏差。
- 反模式 4:提了测试集占比却不做重加权和阈值迁移。这是第七节强调的配套动作,缺一不可。
- 反模式 5:只报点估计不报区间。在少数类样本量不足时,点估计的误导性极强。建议把“区间半宽”作为评估报告的必填字段。
- 反模式 6:忽略子群乘法效应。全局样本量够,不代表每个子群够。子群评估的样本量需求是 K 倍关系。
- 反模式 7:用 AUC 代替召回做唯一决策依据。AUC 是排序指标,对阈值不敏感;业务上线往往关心特定阈值下的召回。两者应同时报告。
本文评述:这些反模式的共同根源是“把抽样当成数据预处理的一个步骤,而不是评估设计的一部分”。一旦把抽样提到评估设计的高度,n_min、区间宽度、配对比较这些概念就会自然进入流程。
十一、前沿预判:小样本评估的下一步
近三年的研究有几个值得关注的方向,它们可能改变“保比例还是保样本量”这个问题的提法。
11.1 主动评估与自适应抽样
传统做法是切分一次、评估一次。主动评估(active evaluation)的思路是:根据当前区间宽度动态决定还要抽多少样本,直到区间窄到目标精度为止。这在标注成本高的场景(如需要人工复核的欺诈样本)尤其有价值。相关研究在 2023–2025 年有较多讨论(参考文献 [41][46][52])。本文评述:主动评估把 n_min 从“事前拍定”变成“事中自适应”,是本文双约束框架的自然延伸,工程上可以先从“分阶段扩测试集”做起。
11.2 贝叶斯层次模型借力
当子群很多、每个子群样本都很少时,可以对子群召回率建层次贝叶斯模型,用全局信息“借力”子群估计,从而在子群样本量不足时仍给出较窄的可信区间。这类方法在 2024 年前后的若干工作中被用于小样本评估(参考文献 [44][49][55])。笔者认为,这是解决“子群乘法效应”最有希望的方向之一,但需要业务方接受“子群估计被全局信息收缩”这一前提。
11.3 评估即服务与标准化区间报告
随着 MLOps 工具链成熟,把“区间宽度校验”做成流水线的一个 gate 是可行且低成本的。例如在模型注册前强制检查:测试集每类样本量 ≥ n_min,否则阻断。这类工程化实践在近年的平台类文献中反复出现(参考文献 [58][60])。本文预判:未来两三年,“评估样本量校验”会像“数据漂移监控”一样成为标准组件。
十二、落地操作清单
- 定指标:明确业务决策依赖哪些指标(召回、精确率、F1、子群召回),每个指标的目标区间半宽 e 是多少。
- 算 n_min:用第四节公式对每个指标、每个子群算 n_min,取最大值,乘以子群数 K。
- 查冲突:按比例切分后,测试集每类样本量是否 ≥ n_min。不冲突则直接保比例。
- 走判定树:冲突时先扩测试集,再适度提测试集占比(≤5 倍),最后才降级需求。
- 配套补偿:提占比的方案必须配套重加权校正与阈值迁移,报告双栏指标。
- 改评估口径:小样本用 Wilson 或 BCa Bootstrap 区间;模型对比用配对检验。
- 写进流水线:把“每类样本量 ≥ n_min”做成切分脚本的断言,不满足直接报错。
- 留痕:记录切分种子、n_min 计算依据、偏移倍数、补偿方式,保证可复现。
回到最初的问题:分层抽样该保“比例”还是保“每类最少样本数”?笔者的答案是——比例是默认,样本量是底线;底线不可破,比例可协商。当两者冲突时,优先保样本量,并用重加权、阈值迁移、分层报告把比例偏移的代价控制在可解释、可校正的范围内。这不是对分层抽样的否定,而是对它的目标函数做一次必要的升级:从“让分布看起来对”升级为“让决策做得动”。
🔒 复制本站文章内容需登录并达到 L3。当前:未登录
微信扫一扫分享
打开微信「扫一扫」,扫描二维码后在微信中分享给好友或朋友圈。
💬 评论 (0)
评论功能已关闭

