【问题标题】:Plot decision tree over dataset in scikit-learn在 scikit-learn 中的数据集上绘制决策树
【发布时间】:2019-01-25 11:58:15
【问题描述】:

我一直在尝试将我的数据集随机分为测试集和训练集,并在 5 层深度决策树上进行训练并绘制决策树。

附:我不允许使用 pandas 这样做。

这是我尝试做的:

import numpy
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn import tree
from sklearn.model_selection import train_test_split
filename = 'diabetes.csv'
raw_data = open(filename, 'rt')
data = numpy.loadtxt(raw_data, delimiter=",", skiprows=1)
print(data.shape)

X = data[:,0:8] #identify columns as data sets
Y = data[:, 9] #identfy last column as target
print(X)
print(Y)
X_train, X_test, Y_train, Y_test = train_test_split(
X, Y, test_size=0.25)
treeClassifier = DecisionTreeClassifier(max_depth=5)
treeClassifier.fit(X_train, Y_train)
with open("treeClassifier.txt", "w") as f:
 f = tree.export_graphviz(treeClassifier, out_file=f)

我的输出是:

(768, 10)
[[  6.    148.     72.    ...  33.6     0.627  50.   ]
[  1.     85.     66.    ...  26.6     0.351  31.   ]
[  8.    183.     64.    ...  23.3     0.672  32.   ]
 ...
[  5.    121.     72.    ...  26.2     0.245  30.   ]
[  1.    126.     60.    ...  30.1     0.349  47.   ]
[  1.     93.     70.    ...  30.4     0.315  23.   ]]
[1. 0. 1. 0. 1. 0. 1. 0. 1. 1. 0. 1. 0. 1. 1. 1. 1. 1. 0. 1. 0. 0. 1. 1.
 1. 1. 1. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 1. 0. 1. 0. 0.
 1. 0. 0. 0. 0. 1. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1. 0. 1. 0. 0. 0. 1. 0.
 1. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0.
 0. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 1. 1. 1. 0. 0. 0.
 1. 0. 0. 0. 1. 1. 0. 0. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.
 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 1. 1. 0. 0. 0. 1. 0. 0. 0. 0. 1. 1. 0. 0.
 0. 0. 1. 1. 0. 0. 0. 1. 0. 1. 0. 1. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1. 0. 0.
 1. 1. 0. 1. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0. 1. 1. 0. 1. 0. 0. 0. 1. 1. 1.
 1. 0. 1. 1. 1. 1. 0. 0. 0. 0. 0. 1. 0. 0. 1. 1. 0. 0. 0. 1. 1. 1. 1. 0.
 0. 0. 1. 1. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 1. 0. 1. 0. 0.
 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 1. 1. 0. 0. 1.
 0. 0. 0. 1. 1. 1. 0. 0. 1. 0. 1. 0. 1. 1. 0. 1. 0. 0. 1. 0. 1. 1. 0. 0.
 1. 0. 1. 0. 0. 1. 0. 1. 0. 1. 1. 1. 0. 0. 1. 0. 1. 0. 0. 0. 1. 0. 0. 0.
 0. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 1. 1. 1. 0. 1.
 1. 0. 0. 1. 0. 0. 1. 0. 0. 1. 1. 0. 0. 0. 0. 1. 0. 0. 1. 0. 0. 0. 0. 0.
 0. 0. 1. 1. 1. 0. 0. 1. 0. 0. 1. 0. 0. 1. 0. 1. 1. 0. 1. 0. 1. 0. 1. 0.
 1. 1. 0. 0. 0. 0. 1. 1. 0. 1. 0. 1. 0. 0. 0. 0. 1. 1. 0. 1. 0. 1. 0. 0.
 0. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1. 1. 1. 0. 0. 1. 0. 0. 1. 0. 0. 0. 1.
 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.
 1. 0. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 0. 1. 0.
 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 1. 1. 1. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.
 0. 1. 0. 1. 1. 0. 0. 0. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 0. 1. 0. 0. 1. 0.
 0. 0. 0. 1. 1. 0. 1. 0. 0. 0. 0. 1. 1. 0. 1. 0. 0. 0. 1. 1. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 1. 1.
 1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 1. 0. 1. 1. 1. 1. 0. 1. 1. 0. 0. 0. 0.
 0. 0. 0. 1. 1. 0. 1. 0. 0. 1. 0. 1. 0. 0. 0. 0. 0. 1. 0. 1. 0. 1. 0. 1.
 1. 0. 0. 0. 0. 1. 1. 0. 0. 0. 1. 0. 1. 1. 0. 0. 1. 0. 0. 1. 1. 0. 0. 1.
 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 1.
 0. 0. 1. 0. 1. 1. 1. 0. 0. 1. 1. 1. 0. 1. 0. 1. 0. 1. 0. 0. 0. 0. 1. 0.]

这是我希望生成的树看起来像的示例:

我遇到的问题是,在我的树中,我没有得到 'class=0\ class=1' 属性。我认为问题可能出在Y = data[:, 9] 部分,第 9 列对它是 0 还是 1 进行分类——这是类属性,但我看不到任何方法可以更改它以使其出现在树中;也许tree.export_graphviz 函数中有什么东西?我错过了一个参数吗?任何帮助将不胜感激。

【问题讨论】:

    标签: python numpy scikit-learn decision-tree


    【解决方案1】:

    如果你替换

    tree.export_graphviz(treeClassifier, out_file=f)
    

    tree.export_graphviz(treeClassifier, class_names=['0', '1'], out_file=f)
    

    你应该很好。

    例如,

    import graphviz
    import numpy as np
    from sklearn.tree import DecisionTreeClassifier
    from sklearn import tree
    from sklearn.model_selection import train_test_split
    
    np.random.seed(42)
    X = np.random.random((100, 8))
    Y = np.random.randint(2, size=100)
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.25)
    tree_classifier = DecisionTreeClassifier(max_depth=5)
    tree_classifier.fit(X_train, Y_train)
    
    dot_data = tree.export_graphviz(tree_classifier, class_names=['0', '1'], out_file=None)
    graph = graphviz.Source(dot_data)
    graph
    

    为了让它看起来更像你提到的例子,你可以使用

    tree.export_graphviz(treeClassifier, class_names=['0', '1'],
                         filled=True, rounded=True, out_file=f)
    

    【讨论】:

      【解决方案2】:

      这是另一个不使用熊猫的答案。除了此处列出的其他方法之外,从 scikit-learn 版本 21.0(大约 2019 年 5 月)开始,现在可以使用 scikit-learn 的 tree.plot_tree 使用 matplotlib 绘制决策树,而无需依赖 graphviz。

      import matplotlib.pyplot as plt
      from sklearn.datasets import load_iris
      from sklearn.tree import DecisionTreeClassifier
      from sklearn import tree
      
      X, y = load_iris(return_X_y=True)
      
      # Make an instance of the Model
      clf = DecisionTreeClassifier(max_depth = 5)
      
      # Train the model on the data
      clf.fit(X, y)
      
      fn=['sepal length (cm)','sepal width (cm)','petal length (cm)','petal width (cm)']
      cn=['setosa', 'versicolor', 'virginica']
      
      # Setting dpi = 300 to make image clearer than default
      fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (4,4), dpi=300)
      
      tree.plot_tree(clf,
                 feature_names = fn, 
                 class_names=cn,
                 filled = True);
      
      fig.savefig('imagename.png')
      

      下图是保存的内容。

      代码改编自post

      【讨论】:

        【解决方案3】:

        我知道有 4 种绘制 scikit-learn 决策树的方法:

        • 使用 sklearn.tree.export_text 方法打印树的文本表示
        • 使用 sklearn.tree.plot_tree 方法绘图(需要 matplotlib)
        • 使用 sklearn.tree.export_graphviz 方法绘图(需要 graphviz)
        • 使用 dtreeviz 包绘图(需要 dtreeviz 和 graphviz)

        最简单的就是导出为文本表示。示例决策树如下所示:

        |--- feature_2 <= 2.45
        |   |--- class: 0
        |--- feature_2 >  2.45
        |   |--- feature_3 <= 1.75
        |   |   |--- feature_2 <= 4.95
        |   |   |   |--- feature_3 <= 1.65
        |   |   |   |   |--- class: 1
        |   |   |   |--- feature_3 >  1.65
        |   |   |   |   |--- class: 2
        |   |   |--- feature_2 >  4.95
        |   |   |   |--- feature_3 <= 1.55
        |   |   |   |   |--- class: 2
        |   |   |   |--- feature_3 >  1.55
        |   |   |   |   |--- feature_0 <= 6.95
        |   |   |   |   |   |--- class: 1
        |   |   |   |   |--- feature_0 >  6.95
        |   |   |   |   |   |--- class: 2
        |   |--- feature_3 >  1.75
        |   |   |--- feature_2 <= 4.85
        |   |   |   |--- feature_1 <= 3.10
        |   |   |   |   |--- class: 2
        |   |   |   |--- feature_1 >  3.10
        |   |   |   |   |--- class: 1
        |   |   |--- feature_2 >  4.85
        |   |   |   |--- class: 2
        

        如果你安装了matplotlib,你可以用sklearn.tree.plot_tree绘图:

        tree.plot_tree(clf) # the clf is your decision tree model
        

        示例输出与export_graphviz 得到的输出非常相似:

        你也可以试试dtreeviz 包。它会给你更多的信息。例子:

        您可以在这篇博文中找到 sklearn 决策树的不同可视化与代码 sn-ps 的比较:link

        【讨论】:

          猜你喜欢
          • 2016-08-12
          • 2017-02-23
          • 2020-04-05
          • 1970-01-01
          • 2015-03-05
          • 2017-03-26
          • 2016-12-31
          • 2017-01-21
          相关资源
          最近更新 更多