【问题标题】:Plot trees for a Random Forest in Python with Scikit-Learn使用 Scikit-Learn 在 Python 中绘制随机森林的树
【发布时间】:2022-01-12 01:59:55
【问题描述】:

我想绘制一个随机森林的决策树。所以,我创建了以下代码:

clf = RandomForestClassifier(n_estimators=100)
import pydotplus
import six
from sklearn import tree
dotfile = six.StringIO()
i_tree = 0
for tree_in_forest in clf.estimators_:
if (i_tree <1):        
    tree.export_graphviz(tree_in_forest, out_file=dotfile)
    pydotplus.graph_from_dot_data(dotfile.getvalue()).write_png('dtree'+ str(i_tree) +'.png')
    i_tree = i_tree + 1

但它不会产生任何东西.. 您知道如何从随机森林中绘制决策树吗?

谢谢,

【问题讨论】:

    标签: python tree scikit-learn random-forest pydot


    【解决方案1】:

    除了上面给出的解决方案,你可以试试这个(希望将来可能需要这个的人)。

    from sklearn.tree import export_graphviz
    from six import StringIO 
    
    i_tree = 0
    dot_data = StringIO()
    for tree_in_forest in rfc.estimators_:#rfc random forest classifier
        if (i_tree ==3):        
            export_graphviz(tree_in_forest, out_file=dot_data)
            graph = pydotplus.graph_from_dot_data(dot_data.getvalue())        
        i_tree = i_tree + 1
    Image(graph.create_png())
    

    【讨论】:

      【解决方案2】:

      要在 scikit-learn 中访问随机森林中的单个决策树,请使用 estimators_ 属性:

      rf = RandomForestClassifier()
      # first decision tree
      rf.estimators_[0]
      

      然后你可以使用标准的方式来可视化决策树:

      • 您可以使用 sklearn export_text 打印树表示
      • 导出到 graphiviz 并使用 sklearn export_graphviz 方法绘图
      • 使用 matplotlib 和 sklearn plot_tree 方法绘图
      • 使用dtreeviz 包进行树图绘制

      post 中描述了带有示例输出的代码。

      从随机森林中绘制单个决策树时,重要的是它可能已完全生长(默认超参数)。这意味着树可以很深。对我来说,深度大于 6 的树很难阅读。因此,如果需要树可视化,我将使用max_depth post 中查看示例可视化。

      【讨论】:

        【解决方案3】:

        在 scikit-learn 中拟合随机森林模型后,您可以可视化随机森林中的单个决策树。下面的代码首先适合随机森林模型。

        import matplotlib.pyplot as plt
        from sklearn.datasets import load_breast_cancer
        from sklearn import tree
        import pandas as pd
        from sklearn.ensemble import RandomForestClassifier
        from sklearn.model_selection import train_test_split
        
        # Load the Breast Cancer Dataset
        data = load_breast_cancer()
        df = pd.DataFrame(data.data, columns=data.feature_names)
        df['target'] = data.target
        
        # Arrange Data into Features Matrix and Target Vector
        X = df.loc[:, df.columns != 'target']
        y = df.loc[:, 'target'].values
        
        # Split the data into training and testing sets
        X_train, X_test, Y_train, Y_test = train_test_split(X, y, random_state=0)
        
        # Random Forests in `scikit-learn` (with N = 100)
        rf = RandomForestClassifier(n_estimators=100,
                                    random_state=0)
        rf.fit(X_train, Y_train)
        

        您现在可以可视化单个树。下面的代码可视化了第一个决策树。

        fn=data.feature_names
        cn=data.target_names
        fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (4,4), dpi=800)
        tree.plot_tree(rf.estimators_[0],
                       feature_names = fn, 
                       class_names=cn,
                       filled = True);
        fig.savefig('rf_individualtree.png')
        

        下图是保存的。

        因为这个问题要求的是树,所以如果您愿意,您可以可视化随机森林中的所有估计量(决策树)。下面的代码可视化了上面随机森林模型拟合的前 5 个。

        # This may not the best way to view each estimator as it is small
        fn=data.feature_names
        cn=data.target_names
        fig, axes = plt.subplots(nrows = 1,ncols = 5,figsize = (10,2), dpi=900)
        for index in range(0, 5):
            tree.plot_tree(rf.estimators_[index],
                           feature_names = fn, 
                           class_names=cn,
                           filled = True,
                           ax = axes[index]);
        
            axes[index].set_title('Estimator: ' + str(index), fontsize = 11)
        fig.savefig('rf_5trees.png')
        

        下图是保存的。

        代码改编自post

        【讨论】:

          【解决方案4】:

          你可以这样查看每棵树,

          i_tree = 0
          for tree_in_forest in FT_cls_gini.estimators_:
              if (i_tree ==3):        
                  tree.export_graphviz(tree_in_forest, out_file=dotfile)
                  graph = pydotplus.graph_from_dot_data(dotfile.getvalue())        
              i_tree = i_tree + 1
          Image(graph.create_png())
          

          【讨论】:

          • 您能否添加更多解释,说明这与其他答案有何不同?比转储代码效果更好
          【解决方案5】:

          你可以画一棵树:

          from sklearn.tree import export_graphviz
          from IPython import display
          from sklearn.ensemble import RandomForestRegressor
          
          m = RandomForestRegressor(n_estimators=1, max_depth=3, bootstrap=False, n_jobs=-1)
          m.fit(X_train, y_train)
          
          str_tree = export_graphviz(m, 
             out_file=None, 
             feature_names=X_train.columns, # column names
             filled=True,        
             special_characters=True, 
             rotate=True, 
             precision=0.6)
          
          display.display(str_tree)
          

          【讨论】:

          • 你知道“draw_tree”函数中的参数比和精度是什么意思吗?
          • 此方法不再起作用,因为.structured 包已从库中删除
          【解决方案6】:

          假设您的随机森林模型已经拟合, 首先你应该先导入export_graphviz函数:

          from sklearn.tree import export_graphviz
          

          在您的 for 循环中,您可以执行以下操作来生成 dot 文件

          export_graphviz(tree_in_forest,
                          feature_names=X.columns,
                          filled=True,
                          rounded=True)
          

          下一行生成一个png文件

          os.system('dot -Tpng tree.dot -o tree.png')
          

          【讨论】:

          • 我认为随机森林中没有树的属性,不是吗?
          • @LKM,随机森林是树的列表。您可以使用estimators_ 属性获取该列表。例如,您可以使用random_forest.estimators_[0] 导出第一棵树。
          • "export_graphviz" 只能用于决策树,不能用于随机森林。
          • @LKM 一棵树是列表中的一个元素clf.estimators_
          • len(random_forest.estimators_) 给出树的数量。
          猜你喜欢
          • 2017-03-26
          • 2015-03-28
          • 2017-12-10
          • 2015-12-01
          • 2013-04-26
          • 2016-05-18
          • 2017-03-01
          • 2016-06-22
          相关资源
          最近更新 更多