使用 BaggingClassifier 时打印决策树和 feature_importance

Posted

技术标签:

【中文标题】使用 BaggingClassifier 时打印决策树和 feature_importance【英文标题】:Print decision tree and feature_importance when using BaggingClassifier 【发布时间】:2017-12-31 18:07:28 【问题描述】:

在 scikit learn 中使用 DecisionTreeClassifier 可以轻松获取决策树和重要特征。但是,如果我和 bagging 功能,例如 BaggingClassifier,我将无法获得它们。

由于我们需要使用 BaggingClassifier 拟合模型,因此我无法返回与 DecisionTreeClassifier 相关的结果(打印树(图)、feature_importances_、...)。

Hier 是我的脚本:

seed = 7
n_iterations = 199
DTC = DecisionTreeClassifier(random_state=seed,
                                                 max_depth=None,
                                                 min_impurity_split= 0.2,
                                                 min_samples_leaf=6,
                                                 max_features=None, #If None, then max_features=n_features.
                                                 max_leaf_nodes=20,
                                                 criterion='gini',
                                                 splitter='best',
                                                 )

#parametersDTC = 'max_depth':range(3,10), 'max_leaf_nodes':range(10, 30)
parameters = 'max_features':range(1,200)
dt = RandomizedSearchCV(BaggingClassifier(base_estimator=DTC,
                              #max_samples=1,
                              n_estimators=100,
                              #max_features=1,
                              bootstrap = False,
                              bootstrap_features = True, random_state=seed),
                        parameters, n_iter=n_iterations, n_jobs=14, cv=kfold,
                        error_score='raise', random_state=seed, refit=True) #min_samples_leaf=10

# Fit the model

fit_dt= dt.fit(X_train, Y_train)
print(dir(fit_dt))
tree_model = dt.best_estimator_

# Print the important features (NOT WORKING)

features = tree_model.feature_importances_
print(features)

rank = np.argsort(features)[::-1]
print(rank[:12])
print(sorted(list(zip(features))))

# Importing the image (NOT WORKING)
from sklearn.externals.six import StringIO

tree.export_graphviz(dt.best_estimator_, out_file='tree.dot') # necessary to plot the graph

dot_data = StringIO() # need to understand but it probably relates to read of strings
tree.export_graphviz(dt.best_estimator_, out_file=dot_data, filled=True, class_names= target_names, rounded=True, special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())

img = Image(graph.create_png())
print(dir(img)) # with dir we can check what are the possibilities in graph.create_png

with open("my_tree.png", "wb") as png:
    png.write(img.data)

我得到如下错误:“BaggingClassifier”对象没有属性“tree_”,而“BaggingClassifier”对象没有属性“feature_importances”。有谁知道我怎样才能获得它们?谢谢。

【问题讨论】:

Feature importances - Bagging, scikit-learn的可能重复 @MikhailKorobov 这不是链接中问题的重复。链接中的问题仅讨论 feature_importance 属性,而 OP 也有兴趣访问树本身。 【参考方案1】:

基于the documentation,BaggingClassifier 对象确实没有“feature_importances”属性。您仍然可以按照此问题的答案中所述自行计算:Feature importances - Bagging, scikit-learn

您可以使用属性estimators_ 访问在拟合 BaggingClassifier 期间生成的树,如下例所示:

from sklearn import svm, datasets
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import BaggingClassifier


iris = datasets.load_iris()
clf = BaggingClassifier(n_estimators=3)
clf.fit(iris.data, iris.target)
clf.estimators_

clf.estimators_ 是 3 个拟合决策树的列表:

[DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
             max_features=None, max_leaf_nodes=None,
             min_impurity_split=1e-07, min_samples_leaf=1,
             min_samples_split=2, min_weight_fraction_leaf=0.0,
             presort=False, random_state=1422640898, splitter='best'),
 DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
             max_features=None, max_leaf_nodes=None,
             min_impurity_split=1e-07, min_samples_leaf=1,
             min_samples_split=2, min_weight_fraction_leaf=0.0,
             presort=False, random_state=1968165419, splitter='best'),
 DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
             max_features=None, max_leaf_nodes=None,
             min_impurity_split=1e-07, min_samples_leaf=1,
             min_samples_split=2, min_weight_fraction_leaf=0.0,
             presort=False, random_state=2103976874, splitter='best')]

因此您可以遍历列表并访问每一棵树。

【讨论】:

感谢@Miriam Farber 拥有决策树列表,如果我想使用上面的脚本打印决策树(导入图像),我是否应该单独运行每个决策树并返回参数名单? @MauroNogueira 是的。不过,您不需要复制参数,只需执行“for t in clf.estimators_:”,然后在循环内运行您之前用于信号树的代码。循环中的每一个“t”都是一个拟合的决策树。 我已经尝试过了,但是 export_gaphviz 出错了,例如 'list' 对象在 dt.estimators_ 中没有属性 'tree_' 的 t:export_graphviz(dt.estimators_, out_file='tree .dot') dot_data = StringIO() 读取字符串 export_graphviz(dt.estimators_, out_file=dot_data,filled=True, class_names= target_names, rounded=True, special_characters=True) graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) img = Image(graph.create_png()) print(dir(img)) with open("HDAC8_tree.png", "wb") as png: png.write(img.data) @MauroNogueira 我认为您需要将 dt.estimators_ 替换为 dt.best_estimator_.estimators_ (在我的示例中,clf 是 BaggingClassifier 对象。在您的代码中,除此之外您还进行了网格搜索)。跨度> @MauroNogueira 在注释中的代码中,在 dt.estimators_: export_graphviz(dt.estimators_, out_file='tree.dot') 的行中,您应该将第二个 dt.estimators_ 替换为t(因为 t 是树,而 dt.estimators_ 是树的列表)。在其他地方也类似——一旦你没有,你需要直接使用它。

以上是关于使用 BaggingClassifier 时打印决策树和 feature_importance的主要内容,如果未能解决你的问题,请参考以下文章

将 sklearn 的 BaggingClassifier 与 GridSearchCV 一起使用时出现 ZeroDivisionError

RandomForestClassifier 与 BaggingClassifier 不同

sklearn 中 BaggingClassifier 的默认配置与硬投票的区别

BaggingClassifier 和具有分类特征的 CatBoost 无法正常工作

scikit-learn 的 BaggingClassifier 和自定义基础估计器的问题:操作数不能一起广播?

对 BaggingClassifier 参数内的参数进行网格搜索