所有中间步骤都应该是变压器并实现拟合和变换

问题描述 投票:0回答:3

我正在使用重要特征选择来实现管道,然后使用相同的特征来训练我的随机森林分类器。以下是我的代码。

m = ExtraTreesClassifier(n_estimators = 10)
m.fit(train_cv_x,train_cv_y)
sel = SelectFromModel(m, prefit=True)
X_new = sel.transform(train_cv_x)
clf = RandomForestClassifier(5000)

model = Pipeline([('m', m),('sel', sel),('X_new', X_new),('clf', clf),])
params = {'clf__max_features': ['auto', 'sqrt', 'log2']}

gs = GridSearchCV(model, params)
gs.fit(train_cv_x,train_cv_y)

所以

X_new
是通过
SelectFromModel
sel.transform
选择的新功能。然后我想使用所选的新功能来训练我的 RF。

我收到以下错误:

All intermediate steps should be transformers and implement fit and transform, 
ExtraTreesClassifier ...
python machine-learning scikit-learn typeerror feature-selection
3个回答
19
投票

就像回溯所说:管道中的每个步骤都需要有一个

fit()
transform()
方法(最后一个除外,它只需要
fit()
。这是因为管道将每个步骤的数据转换链接在一起。

sel.transform(train_cv_x)
不是估算器,不符合此标准。

事实上,根据您想要执行的操作,您可以省略此步骤。 在内部,

('sel', sel)
已经完成了这种转换——这就是它被包含在管道中的原因。

其次,

ExtraTreesClassifier
(管道中的第一步)也没有
transform()
方法。 您可以在类文档字符串中验证here。 监督学习模型不是为了转换数据而设计的;它们是为适应它并据此进行预测而设计的。

什么类型的类能够进行转换?

  • 能够扩展您的数据。 请参阅预处理和标准化
  • 能够转换您的数据(以上述以外的其他方式)。 分解和其他无监督学习方法就是这样做的。

无需过多阅读字里行间的内容,这对你来说是有用的:

  1. 首先使用
    train_test_split
    分割 x 和 y。 由此产生的测试数据集将用于最终测试,
    GridSearchCV
    交叉验证中的训练数据集将进一步分解为更小的训练集和验证集。
  2. 构建一个满足您的回溯试图告诉您的内容的管道。
  3. 将该管道传递到
    GridSearchCV
    .fit()
    在 X_train/y_train 上进行网格搜索,然后
    .score()
    在 X_test/y_test 上进行搜索。

粗略地说,看起来像这样:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.33, random_state=444)

sel = SelectFromModel(ExtraTreesClassifier(n_estimators=10, random_state=444), 
                      threshold='mean')
clf = RandomForestClassifier(n_estimators=5000, random_state=444)

model = Pipeline([('sel', sel), ('clf', clf)])
params = {'clf__max_features': ['auto', 'sqrt', 'log2']}

gs = GridSearchCV(model, params)
gs.fit(X_train, y_train)

# How well do your hyperparameter optimizations generalize
# to unseen test data?
gs.score(X_test, y_test)

两个供进一步阅读的例子:


4
投票

如果您使用

imblearn
模块对数据进行过采样或欠采样并将其拟合到管道中的模型中,您也可能会收到标题中的错误。如果您收到此消息,则表示您已导入
sklearn.pipeline.Pipeline
。相反,导入
imblearn.pipeline.Pipeline
就可以了。例如,

from imblearn.pipeline import Pipeline
pipe = Pipeline([('o', SMOTE()), ('svc', SVC())])

问题是,如果你对数据进行采样,中间步骤显然也需要对数据进行采样,这不受 sklearn 的

Pipeline
支持,但受 imblearn 的
Pipeline
支持。


0
投票

发生这种情况是因为您在管道中传递的第一个变压器必须同时具有拟合和变换方法。

m = ExtraTreesClassifier(n_estimators = 10)
m.fit(train_cv_x,train_cv_y)

这里 m 没有转换方法,因为 ExtraTreesClassifier 模型没有转换方法,因此在管道中失败。

因此更改管道的顺序并为管道中的第一步添加另一个变压器

© www.soinside.com 2019 - 2024. All rights reserved.