我试图用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,还有其他转换器具有这样的条件吗?
区别:
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类变换器(即应用于目标的变换器(和应用于特征的变换器。
同样的设计也适用于LabelBinarizer
和MultiLabelBinarizer
。我建议阅读《用户指南》中的"转换预测目标(y("一段。
也就是说,这里有几个注意事项描述了当您尝试在Pipeline
或ColumnTransformer
:中使用LabelEncoder
时会发生什么
Pipeline
s和ColumnTransformer
s是关于变换和拟合数据的,而不是目标。他们不知怎的";假定";目标已经处于估计器可以使用的状态。在这个github问题以及其中提到的问题中,您可以关注关于使管道也能够转换目标的长期讨论。这也在sklearn常见问题解答中进行了总结。
获得
TypeError: fit_transform() takes 2 positional arguments but 3 were given
的具体原因如下(从ColumnTransformer
的角度来看(:当在ColumnTransformer
距离上调用.fit_transform()
或.fit()
时,方法._fit_transform()
会在X
和y
上依次调用,它会触发对._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
用于分类变量。