graph.write_pdf("iris.pdf") 属性错误:'list'对象没有属性'write_pdf'

47

我的代码跟随google的机器学习课程的教学。这两个代码是相同的。我不知道为什么它会显示错误。可能变量类型不正确。但是Google的代码和我的一样。谁曾经遇到过这个问题?

这是一个错误。

[0 1 2]
[0 1 2]
Traceback (most recent call last):
  File "/media/joyce/oreo/python/machine_learn/VisualizingADecisionTree.py", line 34, in <module>
    graph.write_pdf("iris.pdf")
AttributeError: 'list' object has no attribute 'write_pdf'
[Finished in 0.4s with exit code 1]
[shell_cmd: python -u "/media/joyce/oreo/python/machine_learn/VisualizingADecisionTree.py"]
[dir: /media/joyce/oreo/python/machine_learn]
[path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games]

这是代码

import numpy as np
from sklearn.datasets import load_iris
from sklearn import tree

iris = load_iris()
test_idx = [0, 50, 100]

# training data
train_target = np.delete(iris.target, test_idx)
train_data = np.delete(iris.data, test_idx, axis=0)

# testing data
test_target = iris.target[test_idx]
test_data = iris.data[test_idx]

clf = tree.DecisionTreeClassifier()
clf.fit(train_data, train_target)

print test_target
print clf.predict(test_data) 

# viz code
from sklearn.externals.six import StringIO
import pydot
dot_data = StringIO()
tree.export_graphviz(clf,
        out_file=dot_data,
        feature_names=iris.feature_names,
        class_names=iris.target_names,
        filled=True, rounded=True,
        impurity=False)

graph = pydot.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf("iris.pdf")
10个回答

69

我认为您正在使用更新的Python版本。请尝试使用pydotplus。

import pydotplus
...
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf("iris.pdf")

这应该可以做到。


3
我刚才查看了一下。这张图是一个列表,其中包含一个 pydot.Dot 对象。我使用这个 pydot.Dot 对象调用函数 write_pdf("iris.pdf"),这也解决了问题。 - 乔守卿
@乔守卿 你使用了什么语法/如何使用pydot.Dot? - programmer
2
@程序员 这个列表的长度实际上是1。所以只需使用graph[0].write_pdf。顺便说一句,我猜返回一个列表的原因是在单个dot文件中可能有多棵树。 - Weizhou He
我只能使用 pip install pydotplus 安装,而不能使用 conda install pydotplus,因为后者会导致 InvalidArchiveError('Error with archive C:\\Users\\Admin\\Anaconda3\\pkgs\\openssl-1.1.1d-he774522_2xysboxfd\\pkg-openssl-1.1.1d-he774522_2.tar.zst. You probably need to delete and re-download or re-create this file. Message from libarchive was:\n\nCould not unlink') 的错误。 - questionto42

30

pydot.graph_from_dot_data() 返回一个列表,因此请尝试:

graph = pydot.graph_from_dot_data(dot_data.getvalue())
graph[0].write_pdf("iris.pdf") 

1
感谢您的回答。这是一个简单的解决方案,无需经过pydotplus的麻烦。 - maheeka

5

我曾经遇到过完全相同的问题。结果发现是我没有安装graphviz。一旦我安装了它,问题就解决了。


1

@Alex Sokolov,对于我的情况,在Windows上,我下载并安装/解压缩以下内容到一个文件夹中,然后设置Windows环境变量中的PATH。重新运行py代码对我有用。希望对你有帮助。


0

我通过conda安装了scikit-learn,但是所有的都无法工作。 首先,我必须安装libtool。

brew install libtool --universal

然后我跟着这个 scikit-learn 指南。 然后将 Python 文件更改为以下代码

clf = clf.fit(train_data, train_target)
tree.export_graphviz(clf,out_file='tree.dot') 

最后在终端中转换为png格式

dot -Tpng tree.dot -o tree.png

0

我尝试了之前的答案,但在运行脚本时仍然出现错误。因此,我只使用了pydotplus

import pydotplus

通过以下方式安装"graphviz":

sudo apt-get install graphviz

然后它对我起作用了,我添加了

graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf("iris.pdf")

感谢之前的贡献者。


0

我使用Anaconda。以下是适用于我的方法: 从终端运行:

conda install python-graphviz
conda install pydot     ## don't forget this <-----------------

然后运行

clf = clf.fit(train_data, train_target)
tree.export_graphviz(clf,out_file='tree.dot')

然后在终端中输入:

dot -Tpng tree.dot -o tree.png

0

在Python3.7上,它的运行如下,但不要忘记使用Anaconda提示安装pydot:

   from sklearn.externals.six import StringIO
   import pydot

   # viz code
   dot_data = StringIO()
   tree.export_graphviz(clf, out_file=dot_data, feature_names=iris.feature_names,
                 class_names=iris.target_names, filled=True, rounded=True,
                 impurity=False)
   graph = pydot.graph_from_dot_data(dot_data.getvalue())
   graph[0].write_pdf('iris.pdf')

0

要添加所有图表以获取您的n_estimators数量,您可以执行以下操作:

for i in range(0, n):  #n is your n_estimators number
    dot_data = StringIO()
    tree.export_graphviz(clf.estimators_[i], out_file=dot_data, feature_names=iris.feature_names,
                        class_names=iris.target_names, filled=True, rounded=True,
                        impurity=False)
    graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
    graph.write_pdf("iris%s.pdf"%i)

你也可以切换这行

graph = pydotplus.graph_from_dot_data(dot_data.getvalue())

对于这个

(graph,) = pydot.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf("iris.pdf")

而且它仍然可以工作。


-1

希望这能够帮到你,我之前也遇到过类似的问题。我决定不使用pydot/pydotplus而是使用graphviz。我稍微修改了代码,并且它运行得非常好!:)

# 2. Train classifier
# Testing Data
# Examples used to "test" the classifier's accuracy
# Not part of the training data
import numpy as np
from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
test_idx = [0, 50, 100] # Grabs one example of each flower for testing data (in the data set it so happens to be that
                        # each flower begins at 0, 50, and 100

# training data
train_target = np.delete(iris.target, test_idx)     # Delete all but 3 for training target data
train_data = np.delete(iris.data, test_idx, axis=0) # Delete all but 3 for training data

# testing data
test_target = iris.target[test_idx] # Get testing target data
test_data = iris.data[test_idx]     # Get testing data

# create decision tree classifier and train in it on the testing data
clf = tree.DecisionTreeClassifier()
clf.fit(train_data, train_target)

# Predict label for new flower
print(test_target)
print(clf.predict(test_data))

# Visualize the tree
from sklearn.externals.six import StringIO
import graphviz
dot_data = StringIO()
tree.export_graphviz(clf,
        out_file=dot_data,
        feature_names=iris.feature_names,
        class_names=iris.target_names,
        filled=True, rounded=True,
        impurity=False)
graph = graphviz.Source(dot_data.getvalue())
graph.render("iris.pdf", view=True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接