Python生成决策树的.dot文件以及使用graphviz将其转化为png等图片格式(附本人自己编写的具体函数源码) |
您所在的位置:网站首页 › 视图怎么导出结构图片文件 › Python生成决策树的.dot文件以及使用graphviz将其转化为png等图片格式(附本人自己编写的具体函数源码) |
最近因为大创的事情,开始学习机器学习。在学习决策树的过程中,看到了有关决策树可视化的相关操作。 首先,使用的是sklearn库的tree对象进行建树与模型训练,我用的数据集是sklearn.datasets.load_breast_cancer(): from sklearn import tree # 建立决策树分类器 dtc = tree.DecisionTreeClassifier() # 训练决策树模型 dtc.fit(x_train, y_train)当然,这个不是本文关注的重点,由于这样生成的训练模型,内部信息并不直观,只能够调用一些诸如.score()(查看对于某一数据集适应性的决定系数)的数值来粗略地判断模型对于新的数据集的适应程度,显然不太符合当下可视化的潮流,因此tree对象自身定义了一些导出(export)的方法,来将本来是抽象数据矩阵的决策树算法,转化为了可读性较高的文字语言。 先来看一看第一种方法: tree.export_text(dtc)这种方法所做的和它的名称一样,是将原来的tree对象(代码中叫作dtc)表达为一段文本(text),下面是打印出来的实际效果 还是很不直观,每个feature是什么并没有体现在文本上。这个问题我尝试解决,虽然在这个方法里面有一个feature_names的参数,但是我设置了一下,结果给我报了个这样的错: 我拿着它的源码来来回回看了几遍,都没发现问题出在哪里。辛亏急中生智,去搜了一下报错最后的a.any()和a.all()的含义,隐隐约约感觉是数据类型出了问题(我的feature_names参数指定的是一个ndarray数组),于是将ndarray数组类型转化成了list试一下: tree.export_text(dtc, feature_names=list(feature_names))结果: Nice! 但是这样的表示方法还是过于冗长,可读性上也不是很好,因此我还是决定采用第二种方法: # 导出一个可视化的决策树图 with open('breast_cancer_tree_graph.dot', 'w') as dot_file: tree.export_graphviz(dtc, out_file=dot_file, feature_names=feature_names)这种方法会生成一个.dot文档,里面保存了关于决策树的信息。由于Windows本身会按照文档的格式对.dot进行打开,因此看到的是这样的一个文档: 这样显然不是我所想要的直观的表示方式。想要用图像化的形式来对决策树进行解析的话,还需要安装Graphviz库 (其实我所使用的pycharm professional可以下载解析.dot文档的扩展,但是毕竟是用的教育邮箱,还是要以防万一,而且通过扩展加载出来的效果并不是很好,清晰度很低,而且还不能缩放和保存) 提示:使用pycharm中包管理工具下载的Graphviz库好像并不包含我们之后所要使用的工具,因此建议大家还是到官网下载安装包。 Graphviz下载地址下面是Graphviz库的官方网站: Graphviz下载地址 从上面的信息来看,Linux系统好像是可以通过sudo命令直接下载,但是Windows就只能老老实实下载安装包了。这里我下载的是最新的2.50.0版本的。 之后就是按照提示进行安装,这里就不再赘述过程。安装完后,需要对安装文件夹中的bin文件夹进行path路径环境变量配置: 环境变量配置:Graphviz2.50是总的安装目录,打开应该是有下面四个文件夹,我们需要将第一个bin文件夹添加到path环境变量中,具体方法可以自行查找环境变量配置的相关文章教程,总的来说就是新建一行,然后将bin文件夹的绝对路径填入输入框中,如上图所示。 配置好之后,我们可以到命令行输入dot -version来检查是否成功安装了和配置了Graphviz库: 成功安装了之后,我们便可以开始最后一步转化了: 在命令行中先切换目录到.dot文档所在目录,再输入如下的指令: dot -Tpng breast_cancer_tree_graph.dot -o tree.pngbreast_cancer_tree_graph.dot:.dot文档名 tree.png:要生成的图片文件名,可以是别的类型,不一定要是png 然后就得到了我们想要的可以自由缩放的图片文件: 可以看到,这样的图像化表示方式,就要比之前的纯文本形式清晰多了 但是仔细想想,总觉得有哪里不太对劲…… 对了! 每次生成一张图片,我们都需要进入命令行,切换directory,然后再输入上面那串冗长的命令。漆黑一片的命令行里,一不小心就会输错字母,十分搞人心态。要是能够在IDE中直接通过一行简单的代码调用,就能生成这样一张图片,那该多好啊! 这就是我真正想做的。 由.dot文档自动生成.png图片源码:现在是凌晨一点二十五,废话少说,先上代码: # _*_ coding utf-8 _*_ # Designer: はなちゃん # Time: 2022/1/29 19:20 # Name: dot2png.py from pathlib import Path import subprocess def check_valid_path(path): """检查文件路径是否有效,并返回以'/'分割的文件路径""" if '\\' in path: elements = str(Path(path)).split(sep='\\') final_path = Path('/'.join(elements)) elif '/' in path: final_path = Path(path) else: if not Path(path).exists(): raise Exception("Error: File path pattern is not correct.") else: final_path = Path(path) if not final_path.exists(): raise Exception("Error: Your file path does not exist.") if final_path != '': return final_path else: return None def dot2png(dot_file_path=None, img_path=None): """决策树可视化中.dot文件转化为.png图片的函数""" if not dot_file_path: raise Exception(".dot file is not given.") elif not dot_file_path.endswith('.dot'): raise Exception("file provided is not '.dot' type.") DOT_PATH = check_valid_path(dot_file_path) if not img_path: img_path = 'dt_png.png' elif not img_path.endswith('.png'): raise Exception("image file not end with '.png'.") IMG_PATH = img_path cmd_args = ['dot', '-Tpng', DOT_PATH, '-o', IMG_PATH] cmd_pro = subprocess.Popen(args=cmd_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) retval = cmd_pro.stdout.read().decode('gbk') if retval == '': print("successfully create file " + IMG_PATH) else: print("The program encountered some error: ") print(retval)使用了subprocess库来在后台开启子进程(今天临时抱佛脚刚学的。哦不,是昨天),文件路径处理方面采用了Path类,这是一个被我遗忘了很久,但确实很好用的文件路径处理模块。 第一个check_valid_path函数没有什么好说的,就是一些处理路径,并在合适的时候抛出异常,用来应付一下用户们千奇百怪的文件路径错误;dot2png函数是由.dot文档生成图片的主调函数,给定了两个参数: dot_file_path:.dot文档的路径,绝对相对都可以,但是一定要正确指向文件,不然不出意外的话,应该会出现异常 img_path:生成图片的路径,可选参数,如果不写的话会默认在当前的cwd下新建一张名为dt_png的图片 最后是通过Popen调用命令行,我测试了一下,好像一般正常执行的话,得到的返回值retval是不会有内容的,反之若发生了异常,则会返回描述异常的字符串。因此通过这一标识来判定是否生成成功了。 当然,这个小程序肯定还存在很多没有被发现和测试到的漏洞。如果大家在使用过程中遇到了什么问题,欢迎在评论区提出来。虽然提出来了我也不一定会想回答——因为我懒 ╯︿╰。 小插曲:写这篇博客是晚上十一点多,我写到一半的时候,因为打错了个回车不小心按了下ctrl+z,结果一瞬间整篇博客回到了差不多刚开头的地方,惊慌失措的我马上下意识地按了下ctrl+y,结果是重做的框也没了……我在原地怔了一会,想着是不是太久没写东西了,电脑都嫌我文风太啰嗦了。 最后祝大家新年快乐! |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |