具有OneHotEncoder的管道可在train_test_split上运行,但即使实际测试数据相同也返回错误

问题描述

一般来说,我是机器学习和编程的新手,所以请放轻松。

我正在kaggle上执行此Titanic任务,并在使用train_test_split()之后尝试使用make_column_transformer()和管道。我的代码如下。

    preprocess = make_column_transformer(
        (StandardScaler(),['Age','fare']),(OneHotEncoder(),['Pclass','SibSp','Parch','Family_size','Sex','Embarked','Initial','fare_cat']))


    model = make_pipeline(preprocess,LogisticRegression())
    
    model.fit(X_train,y_train)
    predictions = model.predict(X_test)

这很好用。但是,当我在提交的测试数据集上尝试过

y_train_submit = train_data.Survived.values
X_train_submit = train_data[['Pclass','Age','fare','fare_cat']]
X_test_submit = test_data[['Pclass','fare_cat']]

model.fit(X_train_submit,y_train_submit)

predictions_submit = model.predict(X_test_submit)

它在predicts_submit行上给出了此错误

ValueError: Found unkNown categories [9] in column 2 during transform

经过一些实验,我发现错误来自OneHotEncoder()。列和数据类型都完全相同,我对两个DataFrame进行了完全相同的操作,所以为什么它不能与测试数据集一起使用?在这种情况下,我应该如何应用OneHotEncoder?

解决方法

您应该在此处添加make_column_transformer函数,如果您不共享它,人们将不知道它的作用。

我的感觉是,您制作了两个“热编码器”对象,一个用于训练,一个用于测试,这是错误的。您应该将一个用于训练集,以便同时进行训练和测试。如果您在测试集中有一个未出现在训练集中的元素,则还应该添加handle_unknown参数。

from sklearn.preprocessing import OneHotEncoder

enc = OneHotEncoder(handle_unknown='ignore')
enc.fit(X_train_submit)

X_train_submit = enc.transform(X_train_submit)
X_test_submit = enc.transform(X_test_submit)

,

该错误告诉您分类功能之一具有新的类别。当您训练OneHotEncoder时,它会将所有唯一值保存在这些列中,并为每个列创建一个虚拟列。但是在训练(或测试)数据的其中一列中没有看到9,但是在提交数据中却有9

您可以在编码器中设置handle_unknown='ignore',以静默忽略看不见的电平,将它们编码为全零。

handle_unknown: {“错误”,“忽略”},默认值=“错误”
在转换过程中是否引发错误或忽略是否存在未知分类特征(默认为引发)。如果将此参数设置为“忽略”,并且在转换过程中遇到未知类别,则此功能生成的一键编码列将全为零。在逆变换中,未知类别将表示为“无”。