我是不是必须对训练和测试数据集分别进行一次热编码? [关闭]
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%),或者您正在执行许多交叉验证集,您只需要关注。基本上,您希望每个类别仍然出现足够的次数来拟合模型以使其有意义。以上是关于我是不是必须对训练和测试数据集分别进行一次热编码? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章