我是不是必须对训练和测试数据集分别进行一次热编码? [关闭]

Posted

技术标签:

【中文标题】我是不是必须对训练和测试数据集分别进行一次热编码? [关闭]【英文标题】:Do I have to do one-hot-encoding separately for train and test dataset? [closed]我是否必须对训练和测试数据集分别进行一次热编码? [关闭] 【发布时间】:2019-08-26 18:08:22 【问题描述】:

我正在处理一个分类问题,我已将我的数据分成训练集和测试集。

我的分类列很少(大约 4 -6),我正在考虑使用 pd.get_dummies 将分类值转换为 OneHotEncoding。

我的问题是我是否必须分别为训练和测试拆分进行 OneHotEncoding?如果是这种情况,我想我最好使用 sklearn OneHotEncoder,因为它支持 fit 和 transform 方法,对吧?

【问题讨论】:

【参考方案1】:

通常,您希望将测试集视为在训练期间没有它。在进行预测之前,您对训练集所做的任何转换都应该对测试集进行。所以是的,您应该单独进行转换,但要知道您正在应用相同的转换。

例如,如果测试集缺少其中一个类别,则仍应有一个用于缺失类别的虚拟变量(可在训练集中找到),因为您训练的模型仍会期望该虚拟变量.如果测试集有一个额外的类别,这可能应该使用一些“其他”类别来处理。

同样,当缩放连续变量时说[0,1],您在缩放测试集时使用训练集的范围。这可能意味着新缩放的测试变量在[0,1] 之外。


为了完整起见,以下是 one-hot 编码的外观:

import pandas as pd
from sklearn.preprocessing import OneHotEncoder

### Correct
train = pd.DataFrame(['A', 'B', 'A', 'C'])
test = pd.DataFrame(['B', 'A', 'D'])

enc = OneHotEncoder(handle_unknown = 'ignore')
enc.fit(train)

enc.transform(train).toarray()
#array([[1., 0., 0.],
#       [0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 1.]])

enc.transform(test).toarray()
#array([[0., 1., 0.],
#       [1., 0., 0.],
#       [0., 0., 0.]])


### Incorrect
full = pd.concat((train, test))

enc = OneHotEncoder(handle_unknown = 'ignore')
enc.fit(full)

enc.transform(train).toarray()
#array([[1., 0., 0., 0.],
#       [0., 1., 0., 0.],
#       [1., 0., 0., 0.],
#       [0., 0., 1., 0.]])

enc.transform(test).toarray()
#array([[0., 1., 0., 0.],
#       [1., 0., 0., 0.],
#       [0., 0., 0., 1.]])

请注意,对于不正确的方法,D 有一个额外的列(仅显示在测试集中)。在训练期间,我们根本不知道D,所以不应该有它的专栏。

【讨论】:

谢谢。另外,如果测试中有一个不在火车上的新类别怎么办?会被忽略吗? 我认为在这种情况下有几个选择。您可能已经从您的火车组中获得了“其他”类别。这就像低频类别的组合,它们本身不足以让您正确训练模型(想想一个名为 color 的变量,其中有许多不常见的颜色)。如果您没有此“其他”类别,则可以安全地忽略该类别。 “忽略”是指没有一个虚拟变量会被标记为 1(这实际上与“其他”类别相同)。 如果我将火车分成火车、简历和测试。所以我必须分别对它们进行矢量化对吗? 我认为是这样,但您可能希望每个 cv 集具有相似的分类变量组合。意思是,如果类别 A 在变量中出现 20% 的时间,那么每个 cv 集应该大致有 A 出现 20% 的时间,以此类推所有类别。 假设变量有A(20%)、B(30%)、C(50%)三个类别。在拆分过程中,您应该会看到每个 cv 集的相似百分比。您通常不必担心这一点,因为随机拆分通常会解决这个问题。如果您的数据集较小,其中一个类别的频率较低(例如 5%),或者您正在执行许多交叉验证集,您只需要关注。基本上,您希望每个类别仍然出现足够的次数来拟合模型以使其有意义。

以上是关于我是不是必须对训练和测试数据集分别进行一次热编码? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn:如果经过一次热编码后它的特征少于训练/测试集,如何预测新数据

如何在 R 中对多个分类变量进行一次热编码

一次热编码多维数据

一次对多列进行一次热编码并附加到主数据集?

一次热编码后决策树中的特征解释

使用 sklearn 或 pandas 进行一次热编码后,如何在混合数据集(数值 + 分类)上应用 KNN