Forester’s Notebook

🤸‍♂️生活座右铭:勤而拂拭,莫染尘埃。
📚学习座右铭:一切烦恼来源于定义不清。
🙌留言:有任何问题欢迎交流学习,直接私信即可,一定会回!👌

精耕笔记自然搞懂深度学习(基于Pytorch)


测试集是否应参与到预处理阶段?

这是一个关于机器学习实践中数据泄露 (Data Leakage) 的核心问题。

一、明确含义

这里提到的测试集,是指起到验证模型效果作用的数据集,如有验证集也应包含。

预处理阶段可分为清洗和预处理两部分:
在这里插入图片描述

清洗阶段:将”脏“数据清洗干净。存在的问题对后续所有流程都造成困扰,是工作进行的基础。

预处理阶段:面向具体问题及应用模型,对数据集做必要处理。

二、答案

简短的回答是:

原则上,测试集(Test Set) 不应该 参与到任何需要从数据中“学习”或“估算”的预处理步骤中。

依次来看,每个操作都会对数据集原本“真实性”进行削减。

换句话说,这些操作仅是为用到的模型服务的,希望模型能达到最优效果;而训练完成后,进行验证(选取哪个模型/超参数最优)和测试(看看最终模型效果如何)追求的是模拟最真实的应用场景。

三、详细解释与例外情况

1、不允许测试集参与预处理的情况 (关键)

任何基于数据集统计量(均值、标准差、分位数等)的预处理步骤,都只能在**训练集(Training Set)**上进行计算和拟合,然后将拟合好的参数应用到训练集、验证集和测试集上。

预处理操作原则说明
标准化 (Standardization)只用训练集的均值 ( μ ) (\mu) (μ) 和标准差 ( σ ) (\sigma) (σ)错误做法: 用整个数据集(包括测试集)计算 μ \mu μ σ \sigma σ,然后进行转换。这会导致模型在训练过程中“偷窥”到了测试数据的分布。
归一化 (Normalization)只用训练集的最大值 ( max ⁡ ) (\max) (max) 和最小值 ( min ⁡ ) (\min) (min)错误做法: 用测试集的 max ⁡ \max max min ⁡ \min min 来缩放测试集。
缺失值填充 (Imputation)只用训练集的中位数、均值或众数来填充。错误做法: 用整个数据集的中位数来填充测试集中的缺失值。
特征选择 (Feature Selection)只在训练集/验证集上评估特征重要性。错误做法: 在所有数据上运行特征选择算法(如相关性分析),然后只用选定的特征训练模型。
编码 (Encoding)通常允许,但需注意如果是 One-Hot 编码等简单的转换,测试集可以进行。但如果是基于频率或目标变量的复杂编码,则必须严格在训练集上学习映射。

2、允许测试集参与预处理的情况 (一般转换)

对于不涉及从数据中学习统计信息的简单、确定性的转换,测试集可以参与:

  1. 确定性的格式转换:
    • 将日期字符串转换为日期时间对象。
    • 将文本转换为小写或去除标点符号。
  2. 简单的特征工程:
    • 将两个特征相加、相乘等,只要转换的规则是事先确定的,不依赖于数据的分布。
  3. 重新整形和清理:
    • 删除明显的重复行(但更好的做法是在划分之前就进行)。

三、推荐的预处理工作流 (Pipeline)

为了避免数据泄露,最佳实践是遵循以下步骤:

  1. 原始数据 (Raw Data)

  2. 划分数据集

    将数据划分为:

    • 训练集 (Training Set)
    • 验证集 (Validation Set) (可选,用于调参)
    • 测试集 (Test Set) (严格保留,绝不动用!)
  3. 拟合预处理器 (在训练集上)
    使用 sklearn.preprocessing 中的变换器(如 StandardScalerSimpleImputer)在训练集上调用 fit() 方法。

  4. 转换数据 (在所有集合上)
    使用步骤 3 中拟合好的变换器,在训练集、验证集和测试集上调用 transform() 方法。

这种工作流确保了测试集是真正“盲测”的,从而得到对模型泛化能力最公正的评估。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐