我是否必须分别对训练和测试数据集进行单热编码?
Do I have to do one-hot-encoding separately for train and test dataset?
我正在处理一个分类问题,我已将我的数据分成训练集和测试集。
我的分类列很少(大约 4 -6 个),我正在考虑使用 pd.get_dummies
将我的分类值转换为 OneHotEncoding。
我的问题是我是否必须为训练和测试拆分分别执行 OneHotEncoding?如果是这样的话,我想我最好使用 sklearn OneHotEncoder,因为它支持 fit 和 transform 方法,对吗?
通常,您希望将测试集视为在训练期间没有测试集。在进行预测之前,您对训练集所做的任何转换都应该对测试集进行。所以是的,你应该单独进行转换,但要知道你正在应用相同的转换。
例如,如果测试集缺少其中一个类别,那么对于缺少的类别(可以在训练集中找到)仍然应该有一个虚拟变量,因为您训练的模型仍然期望虚拟变量。如果测试集有一个额外的类别,这可能应该用一些 "other" 类别来处理。
类似地,当将连续变量缩放为 [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
,所以不应该有它的专栏。
我正在处理一个分类问题,我已将我的数据分成训练集和测试集。
我的分类列很少(大约 4 -6 个),我正在考虑使用 pd.get_dummies
将我的分类值转换为 OneHotEncoding。
我的问题是我是否必须为训练和测试拆分分别执行 OneHotEncoding?如果是这样的话,我想我最好使用 sklearn OneHotEncoder,因为它支持 fit 和 transform 方法,对吗?
通常,您希望将测试集视为在训练期间没有测试集。在进行预测之前,您对训练集所做的任何转换都应该对测试集进行。所以是的,你应该单独进行转换,但要知道你正在应用相同的转换。
例如,如果测试集缺少其中一个类别,那么对于缺少的类别(可以在训练集中找到)仍然应该有一个虚拟变量,因为您训练的模型仍然期望虚拟变量。如果测试集有一个额外的类别,这可能应该用一些 "other" 类别来处理。
类似地,当将连续变量缩放为 [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
,所以不应该有它的专栏。