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

use*_*396 2 python machine-learning

我正在研究分类问题,并且已经将火车数据分为火车和测试集。

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

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

mic*_*key 5

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

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

同样,当缩放连续变量为时[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.]])
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为在这种情况下有几个选择。您的火车集中可能已经有“其他”类别。这就像低频类别的组合,它们本身不足以提供足够的信息来正确训练模型(想象一个名为“颜色”的变量,其中包含许多不常见的颜色)。如果您没有此“其他”类别,您可以安全地忽略该类别。我所说的“忽略”是指没有一个虚拟变量会被标记为 1(这实际上与“其他”类别相同)。 (2认同)
  • 假设变量具有 A (20%)、B (30%) 和 C (50%) 三个类别。在拆分过程中,您应该会看到每个简历集的相似百分比。您通常不必担心这个问题,因为随机分割通常会解决这个问题。仅当您的数据集较小、其中一个类别出现频率较低(例如 5%)或者您正在进行许多交叉验证集时,您才需要担心。基本上,您希望每个类别仍然出现足够的次数以使模型拟合有意义。 (2认同)