7

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

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

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

4

1 回答 1

30

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

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

类似地,当缩放连续变量时[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,所以不应该有它的专栏。

于 2019-04-04T22:27:45.427 回答