【问题标题】:Building an ensemble of Random Forest models with VotingClassifier()使用 VotingClassifier() 构建随机森林模型的集合
【发布时间】:2021-07-11 11:34:50
【问题描述】:

我正在尝试使用 Sklearn 中的 VotingClassifier() 构建一些模型的集合,以查看它是否比单个模型更好。我正在尝试两种不同的方式。

  1. 我正在尝试使用单独的随机森林、梯度提升和 XGBoost 模型来实现。
  2. 我正在尝试使用许多随机森林模型的集合来构建它(对 n_estimators 和 max_depth 使用不同的参数。

在第一个条件下,我正在这样做

estimator = []
estimator.append(('RF', RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,
                       criterion='gini', max_depth=8, max_features='auto',
                       max_leaf_nodes=None, max_samples=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, n_estimators=900,
                       n_jobs=-1, oob_score=True, random_state=66, verbose=0,
                       warm_start=True)))
estimator.append(('GB', GradientBoostingClassifier(ccp_alpha=0.0, criterion='friedman_mse', init=None,
                           learning_rate=0.03, loss='deviance', max_depth=5,
                           max_features=None, max_leaf_nodes=None,
                           min_impurity_decrease=0.0, min_impurity_split=None,
                           min_samples_leaf=1, min_samples_split=2,
                           min_weight_fraction_leaf=0.0, n_estimators=1000,
                           n_iter_no_change=None, presort='deprecated',
                           random_state=66, subsample=1.0, tol=0.0001,
                           validation_fraction=0.1, verbose=0,
                           warm_start=False)))
estimator.append(('XGB', xgb.XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
              colsample_bynode=1, colsample_bytree=1, gamma=0,
              learning_rate=0.1, max_delta_step=0, max_depth=9,
              min_child_weight=1, n_estimators=1000, n_jobs=1,
              nthread=None, objective='binary:logistic', random_state=0,
              reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
              silent=None, subsample=1, verbosity=1)))

当我这样做时

ensemble_model_churn = VotingClassifier(estimators = estimator, voting ='soft')

并显示 ensemble_model_churn,我得到了输出中的所有内容。

但在第二种情况下,我正在这样做

estimator = []
estimator.append(('RF_1',RandomForestClassifier(n_estimators=500,max_depth=5,warm_start=True)))
estimator.append(('RF_2',RandomForestClassifier(n_estimators=500,max_depth=6,warm_start=True)))
estimator.append(('RF_3',RandomForestClassifier(n_estimators=500,max_depth=7,warm_start=True)))
estimator.append(('RF_4',RandomForestClassifier(n_estimators=500,max_depth=8,warm_start=True)))

等等。我有 30 种不同的型号。

但这一次,当我这样做时

ensemble_model_churn = VotingClassifier(estimators = estimator, voting ='soft')

并显示它,我只得到第一个,而不是其他的。

print(ensemble_model_churn)
>>>VotingClassifier(estimators=[('RF_1',
                              RandomForestClassifier(bootstrap=True,
                                                     ccp_alpha=0.0,
                                                     class_weight=None,
                                                     criterion='gini',
                                                     max_depth=5,
                                                     max_features='auto',
                                                     max_leaf_nodes=None,
                                                     max_samples=None,
                                                     min_impurity_decrease=0.0,
                                                     min_impurity_split=None,
                                                     min_samples_leaf=1,
                                                     min_samples_split=2,
                                                     min_weight_fraction_leaf=0.0,
                                                     n_estimators=500,
                                                     n_jobs=None,
                                                     oob_score=...
                                                     criterion='gini',
                                                     max_depth=5,
                                                     max_features='auto',
                                                     max_leaf_nodes=None,
                                                     max_samples=None,
                                                     min_impurity_decrease=0.0,
                                                     min_impurity_split=None,
                                                     min_samples_leaf=1,
                                                     min_samples_split=2,
                                                     min_weight_fraction_leaf=0.0,
                                                     n_estimators=500,
                                                     n_jobs=None,
                                                     oob_score=False,
                                                     random_state=None,
                                                     verbose=0,
                                                     warm_start=True))],
                 flatten_transform=True, n_jobs=None, voting='soft',
                 weights=None)

为什么会这样?不能运行相同模型的集成吗?

【问题讨论】:

  • 在第二个estimator 案例中,您是从only 随机森林分类器构建的吗? VotingClassifier 实例克隆原始估计器,如果两个分类器属于同一类型,则假设它们是重复的,它可能会丢弃它们。
  • @AlexanderL.Hayes 是否有替代 VotingClassifier() 的方法来处理这种类型的集合?
  • 通常你不会想要。在您的超参数中:max_depth 被初始化为 5、6、7、8。深度 5 决策树是深度 6 的严格子集,深度 7 树的严格子集是深度 7 的严格子集depth-8 决策树。
  • @AlexanderL.Hayes 我只是想找出这样的集合是否比在一堆估计器上使用 GridSearchCV 效果更好。只是无法使用 VotingClassifier() 来做到这一点。
  • 如果你想“滚动你自己的”投票分类器,你可以列附加每个 RF 的 y_pred,给你一个 Nx30 矩阵。然后每一行的模式将是一个硬投票。

标签: python machine-learning scikit-learn ensemble-learning


【解决方案1】:

您看到的估算器不止一个,只是有点难以判断。请注意第一个 oob_score 参数之后的省略号 (...),并且在这些之后重复了一些超参数。 Python 只是不想打印如此巨大的文本墙,并且已经修剪掉了中间的大部分内容。你可以查看len(ensemble_model_churn.estimators) > 1

另一个注意事项:sklearn 非常反对在模型启动时进行任何验证,更愿意在拟合时进行此类检查。 (这是因为他们在网格搜索等中克隆估算器的方式。)因此,在您调用 fit 之前,您的显式输入不太可能发生任何更改。

【讨论】:

  • 这是有道理的len(ensemble_model_churn.estimators) 确实给出了 30(这是我想要的答案)。我在这里发帖是因为我确实适合模型并且得到了完全相同的结果。
  • “完全相同的结果”在什么意义上?准确度、其他一些指标、预测类别、预测概率……?
  • 我使用的是 ROC 曲线下的面积,因为我的数据不平衡。基于此。
猜你喜欢
  • 2017-08-11
  • 2017-05-14
  • 2019-07-10
  • 2018-09-26
  • 2016-04-09
  • 2020-02-25
  • 2013-10-10
  • 2015-04-13
  • 2017-01-26
相关资源
最近更新 更多