Scikit learn 一次热编码后如何对测试数据进行预处理

Scikit learn 一次热编码后如何对测试数据进行预处理,scikit-learn,data-science,one-hot-encoding,Scikit Learn,Data Science,One Hot Encoding,我在这里有点困惑,我对所有

我在这里有点困惑,我对所有<10个唯一值
low\u cardinality\u cols
的分类列进行了热编码,并删除了培训和验证数据的其余分类列

现在,我的目标是将我的模型应用于
test.csv中的新数据。预处理测试数据以匹配训练/验证格式的最佳方法是什么

我关心的是:
1.Test_data.csv对于这些列肯定具有不同的基数
2.如果我使用训练中的低基数列对测试数据进行热编码,我得到的
输入包含NaN
,但我的训练、有效和测试列都是相同的数字

下面的一个热编码示例,这是用于kaggle竞赛/中级课程的


据我所知,有两种可能的解决方案,我将在这里说明这两种方法,您可以选择适合您的方法

解决方案1

如果您可以获得您计划编码的分类变量的所有可能级别/值,当您执行
类别
的默认值为
auto
时,您可以将它们作为
类别
参数传递,该值根据训练数据自动确定类别,并且不会考虑测试数据中发现的新类别。强制执行
类别
作为所有可能类别的列表将帮助我们解决此问题。即使您的测试数据有培训/验证数据中不存在的新类别,它们也将被正确编码,您将无法获得
NaN
s

解决方案2

如果您无法收集分类列的所有可能类别,您可以继续按照您所做的方式安装one hot编码器,并且当您尝试转换测试数据以处理发现新类时将遇到的
NaN
s时,您可以使用诸如或之类的插补技术来插补缺失值并进一步处理


希望这有帮助

我建议两件事:

  • onehotcoder
    是一个默认参数
    handle\u unknown=“error”
    。如果您提到(培训期间不知道测试中的类别),则应转到
    handle\u unknow=“ignore”
  • 使用包含预测器的scikit学习管道,而不是调用
    fit_transform
    transform
    ,然后将数据提供给预测器
解决方案1是一种变通方法(您在培训期间泄露了一些测试信息,我想)。不应使用溶液2。在这里,插补没有任何意义。
# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[low_cardinality_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[low_cardinality_cols]))

# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

# Remove categorical columns (will replace with one-hot encoding)
# This also saves us the hassle of dropping columns 

num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)