【发布时间】:2024-04-30 14:50:02
【问题描述】:
我有一个训练有素的 DecisionTreeClassifier 实例,我实际上对底层决策树本身的谓词很感兴趣。所以我需要一种干净的方式来遍历这棵树。
因为获得可遍历表示的唯一官方方法是使用 scikit 的 export_graphviz 函数导出到 graphviz/dot 文件。之后,我可以使用例如解析和分析树的图形表示。 networkx 和 pydot 的组合。
但是……
我的特定点文件的内容如下:
digraph Tree {
node [shape=box] ;
0 [label="X[0] <= 15.0\ngini = 0.75\nsamples = 8\nvalue = [2, 2, 2, 2]"] ;
1 [label="X[1] <= 3.0\ngini = 0.5\nsamples = 4\nvalue = [2, 0, 2, 0]"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="gini = 0.0\nsamples = 2\nvalue = [0, 0, 2, 0]"] ;
1 -> 2 ;
3 [label="gini = 0.0\nsamples = 2\nvalue = [2, 0, 0, 0]"] ;
1 -> 3 ;
4 [label="X[1] <= 3.0\ngini = 0.5\nsamples = 4\nvalue = [0, 2, 0, 2]"] ;
0 -> 4 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
5 [label="gini = 0.0\nsamples = 2\nvalue = [0, 0, 0, 2]"] ;
4 -> 5 ;
6 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0, 0]"] ;
4 -> 6 ;
}
所以这看起来一切都很好,但为什么只有连接到父节点的边正确地用布尔值标记?该图中的所有边不应该都附有适当的布尔标签/属性吗??
或者,如果有一些奇怪的 graphviz/dot 约定可以帮助我区分后续的兄弟边,那么规则是什么?
我从 scikit 的 documentation on the decision tree classifier 中注意到,示例渲染的 graphviz 决策树实际上也缺少布尔标签。就我对决策树的了解而言,这遗漏了有关决策树的重要信息。还有什么我在这里遗漏的约定吗?例如。左边缘总是隐含地为真吗?由于它是垂直组织的,我如何从 dot 文件中分辨出来?
【问题讨论】:
-
我可以建议您删除
graphviz和dot标签吗?graphviz只做它被告知的事情,只要源代码不包含边缘标签,它就不会显示任何东西,正如人们所期望的那样。 -
但是我为什么要删除更多的标签呢?标签包含我的树的实际相关元数据。如果有的话,我想要更多的标签,而不是更少:)
-
添加或删除,关键是如果您的代码生成应用程序不为您执行此操作,您将不得不手动执行此操作。
graphviz遵循它得到的说明,你的问题在之前的水平上。 -
啊,好的。我现在明白你的意思了。但我只对点文件感兴趣,因为我认为这是获得树的(尽管是序列化的)表示的唯一官方方式。我并不关心最终用 graphviz 渲染我的树。我现在明白有一种不同的 Pythonic 方法可以从 DecisionTreeClassifier 中获取结构。是的,如果我真的想要,我现在可以自己将这些额外的布尔标签添加到点文件中。
标签: scikit-learn graphviz decision-tree dot