使用 OneHotEncoder 忽略看不见的列

数据挖掘 机器学习 Python scikit-学习
2022-03-01 12:19:24

我正在解决一个问题,其中我是 OneHot 编码来自数据帧的一组特征,例如:

from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y)
oh = OneHotEncoder(handle_unknown='ignore')

print(X)

      a     b     c   
1    one    m     y 
2    two    m     n  
36   three  f     n  
113  one    f     n  
31   two    m  other  
....

oh.fit(X_train)

但是,可能并非所有特征都存在于测试集中。对于这个例子,假设我只有前两列。在这种情况下,编码器将引发错误:

oh.transform(X_test.loc[:,:'b'])

X 中的特征数与拟合数据的特征数不同。拟合数据有 3 个特征,X 有 2 个特征。

有没有办法解决这个问题?理想情况下,我希望丢失的列被忽略(输出中不存在)或设置为NaN.

1个回答

这不可能。而这与OHE无关,如果您选择其他任何编码方式,您仍然面临同样的问题!训练和测试之间没有相似的特征集与使用训练/测试开发 ML 模型的基础相矛盾。这已经在stats.stackexchange question中详细讨论过,或者在这里简明扼要地讨论过。

我的两分钱:

  • 我首先建议弄清楚测试数据中缺失列的性质。他们有时会想念还是从未在场?如果他们有时会错过,他们在场时的样子如何?如果它们从未出现在测试中,那么您别无选择,只能将它们放入训练集中。但是,如果它们不时出现在测试中,并且它们包含与火车相似的内容,则可能将它们归为某种可能,并且在测试中不存在时在测试中使用 NaN 是一种有效的尝试方法。我仍然建议您这样做,因为您可能会添加可能无法代表现实甚至扭曲现实的人工制品(信息)。

  • OHE:请注意,OHE 对其成员非常敏感。正如其中一个答案中提到的那样,我相信您也知道,OHE 为其每个成员创建新列并用 0 或 1 填充它们。例如,对于您的列 a,您将有 a_one、a_two、和 OHE 之后的 a_three 列。如果即使其中一个成员(一、二、三)不在您的测试集中的 a 列中,您的管道也会引发错误。OHE 适用于每个特性都有一组已知成员的情况,否则最好选择其他分类编码方法,如散列、二进制,甚至最近引入的实体编码。

祝你好运!