5

我试图创建一个带有 LabelEncoder 的管道来转换分类值。

cat_variable = Pipeline(steps = [
    ('imputer',SimpleImputer(strategy = 'most_frequent')),
    ('lencoder',LabelEncoder())
])
                        
num_variable = SimpleImputer(strategy = 'mean')

preprocess = ColumnTransformer (transformers = [
    ('categorical',cat_variable,cat_columns),
    ('numerical',num_variable,num_columns)
])

odel = RandomForestRegressor(n_estimators = 100, random_state = 0)

final_pipe = Pipeline(steps = [
    ('preprocessor',preprocess),
    ('model',model)
])

scores = -1 * cross_val_score(final_pipe,X_train,y,cv = 5,scoring = 'neg_mean_absolute_error')

但这会引发 TypeError:


TypeError: fit_transform() takes 2 positional arguments but 3 were given

在进一步的参考中,我发现像 LabelEncoders 这样的转换器不应该与特征一起使用,而应该只用于预测目标。

从文档:

sklearn.preprocessing.LabelEncoder 类

使用 0 和 n_classes-1 之间的值对目标标签进行编码。

这个转换器应该用于编码目标值,即 y,而不是输入 X。

我的问题是,为什么我们不能在特征变量上使用 LabelEncoder,还有其他具有这种情况的转换器吗?

4

3 回答 3

3

LabelEncoder可用于规范化标签或转换非数字标签。对于输入分类,您应该使用OneHotEncoder

区别:

le = preprocessing.LabelEncoder()
le.fit_transform([1, 2, 2, 6])
array([0, 0, 1, 2])

enc = OneHotEncoder(handle_unknown='ignore')
enc.fit_transform([[1], [2], [2], [6]]).toarray()
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
于 2020-07-14T09:58:53.290 回答
0

您可以将 OrdinalEncoder 用于分类变量

于 2022-01-29T11:30:01.790 回答
0

LabelEncoder,按照设计,必须用于目标变量而不是特征变量。这意味着方法和类的签名.fit()与旨在.transform()应用于特征的转换器之一不同。.fit_transform()LabelEncoder

适合(y)与适合(X [,y])| 变换(y)与变换(X)| fit_transform(y) 与 fit_transform(X[,y]) 或类似

适合(自我,y)与适合(自我,X,y =无)| 变换(自我,y)与变换(自我,X)| fit_transform(self, y) 与 fit_transform(self, X, y=None)

分别用于类标签编码器的转换器(即应用于目标的转换器)和应用于特征的转换器。

同样的设计也适用于LabelBinarizerMultiLabelBinarizer。我建议阅读用户指南的转换预测目标 (y)段落。

这就是说,这里有几个考虑因素来描述当您尝试LabelEncoder在 aPipeline或 a中使用时会发生什么ColumnTransformer

  • Pipelines 和ColumnTransformers 是关于转换和拟合数据,而不是目标。他们以某种方式“假设”目标已经处于估计器可以使用的状态。

  • 在这个github 问题和其中引用的问题中,您可以关注关于使管道也可以转换目标的长期讨论。这也在此 sklearn 常见问题解答中进行了总结。

  • 您得到的具体原因TypeError: fit_transform() takes 2 positional arguments but 3 were given如下(这里从 a 的角度来看ColumnTransformer):在 istance 上调用or 时,.fit_transform()在and上依次调用方法,并触发 and 的调用,此处出现错误。确实,它要求距离(您的);这里不同的方法签名开始发挥作用:.fit()ColumnTransformer._fit_transform()Xy._fit_transform_one().fit_transform()transformerLabelEncoder

     with _print_elapsed_time(message_clsname, message):
         if hasattr(transformer, "fit_transform"):
             res = transformer.fit_transform(X, y, **fit_params)
         else:
             res = transformer.fit(X, y, **fit_params).transform(X)
    

    实际上,在仅期望([...] 需要 2 个位置参数)时.fit_transform()调用([...] 3 个参数)。按照类中的代码,可以看出同样的情况。(self, X, y)(self, y)Pipeline

  • 如前所述,适用于特征变量(因此适用于管道和列转换器)的标签编码的替代方法是OrdinalEncoder(从版本 0.20 开始)。在这个提议中,我建议阅读OrdinalEncoder 和 LabelEncoder 之间的差异

于 2022-01-31T08:28:47.717 回答