为什么sklearn中的LabelEncoder只能用于目标变量



我试图用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: fit_transform() takes 2 positional arguments but 3 were given

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

来自文档:

类sklearn.preprrocessing.LabelEncoder

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

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

我的问题是,为什么我们不能在功能变量上使用LabelEncoder,还有其他转换器具有这样的条件吗?

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.]])

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

fit(y(vs fit(X[,y](| transform(y(vs transform(X(| fit_transform(y(vsfit_transfer(X[、y](或类似

fit(self,y(vs fit(self,X,y=None

分别用于LabelEncoder类变换器(即应用于目标的变换器(和应用于特征的变换器。

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

也就是说,这里有几个注意事项描述了当您尝试在PipelineColumnTransformer:中使用LabelEncoder时会发生什么

  • Pipelines和ColumnTransformers是关于变换和拟合数据的,而不是目标。他们不知怎的";假定";目标已经处于估计器可以使用的状态。

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

  • 获得TypeError: fit_transform() takes 2 positional arguments but 3 were given的具体原因如下(从ColumnTransformer的角度来看(:当在ColumnTransformer距离上调用.fit_transform().fit()时,方法._fit_transform()会在Xy上依次调用,它会触发对._fit_transform_one()的调用,此时会出现错误。事实上,它在transformer距离(您的LabelEncoder(上调用.fit_transform();在这里,不同的方法签名开始发挥作用:

    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)
    

    事实上,.fit_transform()是在(self, X, y)上调用的([…]给出了3个自变量(,而只期望(self, y)([…]取2个位置自变量(。根据Pipeline类中的代码,可以看出同样的情况也会发生。

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

您可以将OrdinalEncoder用于分类变量。

最新更新