将GridSearchCV和StackingClassifier相结合

9

我想使用StackingClassifier将一些分类器组合起来,然后使用GridSearchCV来优化参数:

clf1 = RandomForestClassifier()
clf2 = LogisticRegression()
dt = DecisionTreeClassifier()
sclf = StackingClassifier(estimators=[clf1, clf2],final_estimator=dt)

params = {'randomforestclassifier__n_estimators': [10, 50],
          'logisticregression__C': [1,2,3]}

grid = GridSearchCV(estimator=sclf, param_grid=params, cv=5)

grid.fit(x, y)

但是这会导致一个错误:

'RandomForestClassifier' object has no attribute 'estimators_'

我使用了 n_estimators。为什么会警告我没有 estimators_?

通常 GridSearchCV 应用于单个模型,所以我只需要在字典中写入单个模型的参数名称。

我参考了这个页面 https://groups.google.com/d/topic/mlxtend/5GhZNwgmtSg ,但它使用早期版本的参数。即使我更改了新的参数,也不起作用。

顺便问一下,我在哪里可以学习这些参数命名规则的细节?


如果你执行sclf.fit(X,y),你会得到什么? - seralouk
'RandomForestClassifier' 对象没有 'estimators_' 属性。 - xiaoluohao
希望我的回答能够帮到你。 - seralouk
请注意,estimators_ 是在完整的 X 上拟合的,而 final_estimator_ 则是使用基本估计器的交叉验证预测进行训练的,使用了 cross_val_predict 来自此处。我猜想基本估计器的网格搜索是在每个折叠中执行的,然后最佳预测器为 final_estimator_ 的训练提供预测,但是...这个 final_estimator_ 的网格搜索是如何执行的呢? - makpalan
2个回答

11

首先,estimators需要是一个列表,其中包含用相应的名称分配的元组中的模型。

estimators = [('model1', model()), # model() named model1 by myself
              ('model2', model2())] # model2() named model2 by myself

接下来,您需要按照sclf.get_params()中显示的名称使用它们。同时,该名称与您在上面的estimators列表中为特定模型指定的名称相同。因此,在这里,对于model1参数,您需要:

params = {'model1__n_estimators': [5,10]} # model1__SOME_PARAM 

工作示例:

from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import StackingClassifier
from sklearn.model_selection import GridSearchCV


X, y = make_classification(n_samples=1000, n_features=4, 
                            n_informative=2, n_redundant=0,
                            random_state=0, shuffle=False)


estimators = [('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
              ('logreg', LogisticRegression())]

sclf = StackingClassifier(estimators= estimators , final_estimator=DecisionTreeClassifier())

params = {'rf__n_estimators': [5,10]}

grid = GridSearchCV(estimator=sclf, param_grid=params, cv=5)
grid.fit(X, y)

3

经过一些尝试,也许我找到了一个可用的解决方案。

解决这个问题的关键是使用 get_params() 来了解 StackingClassifier 的参数。

我使用另一种方法来创建 sclf:

clf1 = RandomForestClassifier()
clf2 = LogisticRegression()
dt = DecisionTreeClassifier()
estimators = [('rf', clf1),
              ('lr', clf2)]
sclf = StackingClassifier(estimators=estimators,final_estimator=dt)
params = {'rf__n_estimators': list(range(100,1000,100)),
          'lr__C': list(range(1,10,1))}
grid = GridSearchCV(estimator=sclf, param_grid=params,verbose=2, cv=5,n_jobs=-1)
grid.fit(x, y)

这样,我就可以给每个基本分类器命名,然后用它们的名称设置参数。


请查看我上面的回答。 - seralouk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接