结合 GridSearchCV 和 StackingClassifier

Posted

技术标签:

【中文标题】结合 GridSearchCV 和 StackingClassifier【英文标题】:Combine GridSearchCV and StackingClassifier 【发布时间】:2020-08-25 22:37:57 【问题描述】:

我想用 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)你会得到什么? 'RandomForestClassifier' 对象没有属性 'estimators_' 看我的回答。希望有帮助 请注意,estimators_ 拟合在完整的 X 上,而 final_estimator_ 是使用使用 cross_val_predictfrom here 的基本估计器的交叉验证预测进行训练的。我猜想在每个折叠中执行基本估计器的网格搜索,然后最好的预测器给出final_estimator_ 训练的预测,但是......如何执行这个网格搜索? 【参考方案1】:

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

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)

【讨论】:

【参考方案2】:

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

解决这个问题的关键是使用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)

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

【讨论】:

看我上面的回答

以上是关于结合 GridSearchCV 和 StackingClassifier的主要内容,如果未能解决你的问题,请参考以下文章

Scikit GridSearchCV - fit() 和 predict() 如何与 ColumnTranformers 和 Pipelines 结合使用

将 OneClassSVM 与 GridSearchCV 结合使用

sklearn GridsearchCV 结合流水线是如何工作的?

pipeline结合GridSearchCV的一点小介绍

如何使用 GridSearchCV 在嵌套管道中测试预处理组合?

XGBoost 与 GridSearchCV、缩放、PCA 和 sklearn 管道中的 Early-Stopping