我是否必须对训练和测试数据集分别进行一种热编码?

时间:2019-04-04 21:29:53

标签: python machine-learning

我正在处理分类问题,并将火车数据分为火车和测试集。

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

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

1 个答案:

答案 0 :(得分:4)

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

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

类似地,当缩放连续变量为[0,1]时,在缩放测试集时将使用训练集的范围。这可能意味着新缩放的测试变量不在[0,1]之外。


为完整起见,这是一键编码的外观:

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,因此不应为此专栏。