在机器学习(ML)模型开发过程中,数据缺失问题几乎无处不在。面对不完整的数据集,数据科学家们通常会采用插补(imputation)技术来填充缺失值,从而构建完整的训练数据。然而,一个看似“省事”的做法却常被忽视:能否直接使用数据集中没有缺失值的行作为测试集,来评估插补后的ML流水线? 答案是否定的,且理由深刻,事关模型评估的科学性与可靠性。

直观误区:为何有人会这样做?

从直觉上看,使用“干净”的完整行来测试模型似乎无可厚非——因为这些行无需插补,测试结果能真实反映模型对“无缺失”数据的表现。操作上也简单:从原始数据中筛选出缺失值比率低于阈值(甚至完全无缺失)的样本,直接作为测试集。这种做法的吸引力在于回避了测试集插补的麻烦,似乎能节省一轮预处理步骤。

但机器学习领域有个基本原则:测试集必须代表模型将在真实环境中遇到的数据分布。 当缺失值并非随机出现时,“完整行”与“含缺失行”的数据分布可能存在系统性差异。直接抽取完整行会严重扭曲评估结论。

三大核心缺陷

1. 破坏数据分布的代表性

缺失值往往并非完全随机缺失(MCAR)。现实中,数据缺失通常具有某种模式:例如,在医疗数据中,收入字段的缺失常与高年龄患者相关;在用户行为数据中,设备型号的缺失多出现在低端机型上。这种“非随机缺失”(MNAR)或“随机缺失”(MAR)导致含缺失值的样本与完整样本在特征分布上显著不同。

若仅用完整行测试,模型相当于在一个“理想化”的子集上接受检验,完全忽略了真实场景中缺失值所携带的信息。结果是,测试集性能可能远高于实际部署时的表现,造成“过度乐观”的错觉。

2. 插补流程被割裂评估

一个插补后的ML流水线是一个整体:插补器(imputer)和预测模型(predictor)是串联工作的。真正的评估应该考察“插补+建模”整个链条的泛化能力。如果测试集只包含完整行,那么流水线中的插补器实际上从未在测试阶段被调用。这相当于只检验了预测模型在无缺失数据上的表现,而插补器的质量——即它对缺失数据的填补准确性——被完全忽略了。

更好的做法是:构建一个包含缺失值的测试集,并让插补器对其应用相同的填补逻辑,再交由预测模型进行推理。 只有这样,我们才能量化插补操作带来的误差累积效应。

3. 引入严重的选择偏差

统计上,从全量数据中剔除含缺失值的样本会造成选择偏差。例如,在信贷风控场景中,收入信息缺失的用户往往是高风险群体;如果只测试完整收入的样本,模型对高风险用户的判断能力将变得不可知。这种偏差不仅影响性能指标的准确性(如AUC、F1分数),也可能引致后续的算法公平性问题——模型可能对某些群体表现更差,而评估却未发现。

数据科学家的正确做法

既然不能简单抛弃缺失行,那么应该如何正确评估插补后的流水线?答案是:将整个流水线封装进交叉验证框架,并在每一折中同时对训练集和测试集进行插补。 具体步骤包括:

  • 拆分数据:先将完整数据集按比例分为训练集和测试集。注意,测试集保留原始缺失状态。
  • 在训练集上训练插补器:学习均值、中位数、KNN插补等模型的参数(如均值、近邻等)。
  • 对测试集应用相同的插补策略:利用训练集学到的参数填补测试集中的缺失值。禁止在测试集上重新拟合插补器,否则会导致数据泄漏。
  • 训练预测模型:使用插补后的训练集拟合模型。
  • 在插补后的测试集上评估:计算性能指标,确保整体流程的公平性。

对于更复杂的插补方法(如多重插补、深度学习插补),上述原则依然适用:插补器必须只在训练集上估计参数,然后外推至测试集。

业界共识与工具支持

主流机器学习框架早已提供现成方案。例如,scikit-learn中的Pipeline类允许将SimpleImputer和预测模型串联,通过cross_val_score自动在每一折内部完成插补。这类工具的设计初衷正是为了防止上述“完整行测试”的错误做法。

此外,Kaggle竞赛中也有很多案例证明:仅使用完整行作为验证集时,排行榜分数与线下表现往往存在巨大落差。顶尖选手无一例外地采用了对缺失值敏感的验证策略。

结语

数据缺失是现实世界的常态,而非需要规避的“缺陷”。在评估插补后的ML流水线时,用完整行充作测试集看似省力,实则背离了科学评估的核心原则:测试集必须忠实反映真实的、不完美的数据环境。 只有将缺失值纳入测试集,并让插补器充分工作,才能获得对模型实际效力的可靠判断。下一次当您面对缺失数据时,不妨牢记:不要逃避缺失,要拥抱它——在评估中也是如此。