目录
这篇文章整理自我在 2024 年 7 月留下的一份分析记录。当时的数据只有 6 个样本,却有约 90 个候选基因特征。逻辑回归和弹性网络给出了看起来极其漂亮的结果:AUC 为 1。
现在回头看,这个结果最值得记录的不是“模型效果完美”,而是它迫使我重新检查整个建模过程。
AUC=1 为什么需要先怀疑
AUC=1 只表示在当前用于评估的样本中,模型把正负样本完全排开。它并不自动证明模型能够推广到新的患者或新的实验批次。
在只有 6 个样本的场景中,任意一次样本划分都会显著改变训练集。与此同时,候选特征数远大于样本数,模型有足够空间记住当前数据中的偶然差异。即使加入 L1 或 L2 正则化,也无法凭空补足样本所缺少的信息。
这类结果至少需要检查以下问题:
- 样本是否真正独立,还是包含技术重复或来自同一对象的重复测量。
- 标准化、缺失值处理和特征筛选是否在拆分训练集与测试集之前完成。
- 测试样本的信息是否以任何形式参与了参数选择。
- 两类样本是否严重失衡,以至于指标由极少数样本决定。
- 更换随机种子或留出某一个样本后,结果是否发生剧烈变化。
最容易忽视的是特征选择泄漏
在组学分析中,常见做法是先用全部样本筛出差异基因,再把这些基因送入交叉验证。这个流程看似合理,实际已经让测试样本参与了特征选择。
正确的验证单元应当包含整个建模流水线:
外层训练集
→ 仅在训练集内做预处理
→ 仅在训练集内筛选特征
→ 在训练集内选择超参数
→ 用外层测试集做一次最终评估
换句话说,特征选择也必须发生在每个训练折内部。关于小样本基因组数据中的模型选择偏差,较早的研究已经指出:测试集不能用于模型选择或特征选择,普通的准确率也不足以稳定比较小样本分类器(Bioinformatics, 2006)。
在 6 个样本上,交叉验证也不是万能药
交叉验证能够减少一次随机拆分带来的偶然性,但它不会让 6 个样本自动变成一个可靠的验证队列。
在这个规模下:
- 每个测试折只有一两个样本,指标呈现明显的离散跳变。
- 单个异常样本就可能改变全部结论。
- 超参数和特征集合可能在不同折之间完全不同。
- 很难获得有解释力的置信区间。
因此,重复交叉验证、嵌套交叉验证、置换检验和 bootstrap 可以帮助描述不确定性,却不能替代外部验证。面向医疗预测模型的综述也将“小样本与大量候选特征的组合”列为过拟合的重要来源,并强调应明确报告防止过拟合的措施(npj Digital Medicine, 2022)。
这次分析可以支持什么结论
更诚实的说法是:
当前数据证明分析流程能够运行,并产生了值得后续验证的候选信号;它不能证明模型已经具备稳定的预测性能。
如果继续推进,我会把工作拆成三层:
- 探索层:描述当前样本的差异和候选特征,不把训练集表现当作泛化能力。
- 稳定性层:记录不同重采样下入选特征、系数方向和性能指标的变化。
- 验证层:在独立队列、独立实验批次或后续新增样本中检验候选结果。
留给以后分析的检查清单
- 在拆分数据之后再做所有有监督预处理。
- 把特征选择纳入交叉验证流水线。
- 同时报告样本数、特征数和类别分布。
- 报告性能波动,而不是只保留最好的一次结果。
- 区分探索性发现、内部验证和外部验证。
- 当数据不足时,宁可降低结论强度,也不使用复杂模型掩盖不确定性。
这次 AUC=1 最终没有成为一个值得庆祝的数字,却成为了一个很好的方法学提醒:小样本研究中,最重要的结果往往不是模型分数,而是我们能否准确说明这个分数的边界。
讨论
评论使用 GitHub Discussions。首次加载需要访问 GitHub。