大数据技术

大数据-训练/测试集:不平衡数据做分层抽样,训练集和测试集的正负比例是保住了,但测试集里少数类绝对数量仍然只有几十条,算出来的召回率置信区间宽到没有决策价值——分层抽样到底该保“比例”还是该保“每类最少样本数”,两者冲突时优先哪个?

👤 为我痴狂 👁 4 阅读 ❤ 0 点赞 ➦ 0 分享 📅 2026-10-22
首页› 大数据› 大数据技术› 正文
大数据训练/测试集:不平衡数据的分层抽样
该保“比例”还是保“每类最少样本数”?

比例约束与绝对样本量下限的双约束框架 · 冲突优先级判定 · 召回率置信区间可决策化路径

关键词:不平衡分类 · 分层抽样 · 少数类样本量 · 召回率置信区间 · 评估可靠性

摘要

分层抽样(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₊ 观测召回率 R 标准误 95% 区间半宽 决策可用性
20000.700.0102±2.0%可用于模型选型
5000.700.0205±4.0%可用于粗粒度对比
2000.700.0324±6.4%仅能判断量级
800.700.0512±10.0%区间重叠严重,难决策
400.700.0725±14.2%基本失去决策价值

这张表就是本文要解决的问题的“形状”。注意,当 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 区间复核。

预期召回率 R e=±10% e=±5% e=±3% e=±2%
0.509738510682401
0.70813238972017
0.80622466831537
0.9035139385865
0.951973203457

读表要点:如果业务要求召回率的 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 三种区间的选择

方法 适用场景 优点 局限
正态近似(Wald)n₊ 大、R 不接近 0/1计算简单小样本或极端 R 时失效
Wilson 得分区间中小样本、R 接近边界小样本表现稳健仍基于二项假设
Bootstrap 百分位区间指标复杂(F1、AUC)通用、易实现小样本时覆盖率偏低
贝叶斯可信区间极小样本、需先验可融入业务先验先验选择有主观性

本文评述:在 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 模拟结果(模拟数据)

策略 子群测试正类数 召回区间半宽(均值) 模型对比判定一致率
S1 纯比例≈1000(全局)±2.8%全局可用,子群不可用
S2 子群纯比例≈125±8.0%约 71%
S3 双约束≥300±5.2%约 92%

结果符合预期:双约束策略把子群召回区间半宽从 ±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])。本文预判:未来两三年,“评估样本量校验”会像“数据漂移监控”一样成为标准组件。

十二、落地操作清单

  1. 定指标:明确业务决策依赖哪些指标(召回、精确率、F1、子群召回),每个指标的目标区间半宽 e 是多少。
  2. 算 n_min:用第四节公式对每个指标、每个子群算 n_min,取最大值,乘以子群数 K。
  3. 查冲突:按比例切分后,测试集每类样本量是否 ≥ n_min。不冲突则直接保比例。
  4. 走判定树:冲突时先扩测试集,再适度提测试集占比(≤5 倍),最后才降级需求。
  5. 配套补偿:提占比的方案必须配套重加权校正与阈值迁移,报告双栏指标。
  6. 改评估口径:小样本用 Wilson 或 BCa Bootstrap 区间;模型对比用配对检验。
  7. 写进流水线:把“每类样本量 ≥ n_min”做成切分脚本的断言,不满足直接报错。
  8. 留痕:记录切分种子、n_min 计算依据、偏移倍数、补偿方式,保证可复现。

回到最初的问题:分层抽样该保“比例”还是保“每类最少样本数”?笔者的答案是——比例是默认,样本量是底线;底线不可破,比例可协商。当两者冲突时,优先保样本量,并用重加权、阈值迁移、分层报告把比例偏移的代价控制在可解释、可校正的范围内。这不是对分层抽样的否定,而是对它的目标函数做一次必要的升级:从“让分布看起来对”升级为“让决策做得动”。

🔒 复制本站文章内容需登录并达到 L3。当前:未登录

分享到

💬
微信
📷
朋友圈
🐧
QQ好友
🌐
QQ空间
👁
微博
📌
钉钉
🔗
复制链接
📑
复制图文

微信扫一扫分享

打开微信「扫一扫」,扫描二维码后在微信中分享给好友或朋友圈。

💬 评论 (0)

评论功能已关闭

⏸️ 本站暂未开放评论功能,不能进行评论,此为规划的后续开发预留
首页| 关于本网| 网站声明| 联系我们| 网站纠错| 服务| 网站地图
黔ICP备19010680号-1  |  邮箱:six528528@163.com
贵公网安备 52010302001819号
Copyright 2019-2026 http://www.databrush.com/ All rights reserved.
QQ
QQ扫一扫
Logo
DBN数据刷