对整个数据集进行标签编码会导致数据泄漏吗?

数据挖掘 机器学习 数据清理 数据泄露
2021-10-10 17:08:16

我有一个数据集,其中一个特征有很多不同的分类值。尝试使用 LabelEncoder、OrdinalEncoder 或 OneHotEncoder 会导致错误,因为在拆分数据时,测试集最终会包含一些训练集中不存在的值。

我的问题是:如果我选择在拆分数据之前对变量进行编码,这会导致数据泄漏吗?

我知道在拆分数据集之前我不应该对数据执行任何规范化或有根据的转换,但我在 scikit-learn 中找不到解决这个问题的方法。

提前感谢您的任何回复。

编辑:这个特殊的特性具有非常高的基数,大约有 60k 的可能值。因此,使用 scikit-learnOneHotEncoderhandle_unknownset toignore会在数据集中引入太多新列。

3个回答

最干净的解决方案是应用 scikit 的OneHotEncoder并将handle_unknown参数设置为"ignore"

处理未知{'错误','忽略'},默认='错误'

如果在转换期间存在未知的分类特征,是否引发错误或忽略(默认为引发)。当此参数设置为 'ignore' 并且在转换过程中遇到未知类别时,此功能的生成的 one-hot 编码列将全为零。在逆变换中,未知类别将表示为无。

例如,在这个Stackoverflow 上的这个问题中描述了其他手动解决方案。

在拆分数据集之前对标签进行编码不应导致泄漏,尤其是在序数编码的情况下。序数编码只是从“标签空间”到“整数空间”的转换。更改我们用于标签的名称不会添加任何可能更改分类结果的有用信息,因此不会泄漏数据。

这样想:假设您有 3 个标签“红色”、“蓝色”、“绿色”。但是,出于某种原因,您使用的软件包仅适用于西班牙语。因此,您将标签更改为“Rojo”、“Azul”和“Verde”。没有发生数据泄漏 - 您刚刚开始将标签称为不同的东西。这几乎完全类似于序数编码*。

我认为您可以提出一个论点,即一次性编码允许一些非常非常小的泄漏。假设您有标签“红色”、“蓝色”、“绿色”,但只有前两个出现在您的训练集中。通过在拆分之前对标签进行 one-hot 编码,您可以隐式声明存在三个可能的标签,而不是两个。根据定义,这可以描述为数据泄漏,因为您可以导出一些实际上未包含在训练集中的信息。但是,我无法想象 ML 算法如何在这种情况下获得人为的好处,所以我认为这没什么好担心的。


*如果你忽略了一些算法可以找到数字之间的虚假关系,但不能找到字符串标签的事实。

首先,这里没有数据泄漏,因为您正在编码一个特征而不是目标变量。其次,您可以考虑其他有用的编码方案,例如target encoding,不会像 onehot 编码那样创建大量列。事实上,它只创建了一个列。还要尝试减少类别中的值数量,60k 太多了。