大家在画决策树的过程中,一定非常希望能画出带有中文特征名称或类别名称的决策树。但我们直接用graphviz画图时,中文却会出现乱码。如下图所示,相信大家都遇见过:在红酒数据集中,将feature_names和class_name是设为中文的后果
于是乎,本人在网上搜索了一些攻略,但很多博客复制黏贴,且错误百出,我在综合了好几篇博客后,才成功画出中文的决策树。所以想重新梳理下解决办法,供各位参考。
1、修改graphviz配置文件
我们首先要找到你电脑中的graphviz文件夹中叫做"fonts"的文件,你可能会发现有两个文件夹都有fonts,分别是C:\Program Files (x86)\Graphviz2.38\etc\fonts和C:\ProgramFiles (x86)\Graphviz2.38\fonts。请将两个fonts文件分别用记事本打开。如果有
则将其修改为
。此处可能会有一个fonts文件已经正确,则请忽略改文件。此外,保存可能需要管理员权限,我自己是将这个fonts文件另存在桌面后,再复制到原路径替换,才成功的。2、将决策树dot_data文件保存下来,修改字体并保存为 UTF-8格式
保存下来的目的是为了dot_data文件的字体,并将其转换为UTF-8格式。例如: dot_data = tree.export_graphviz(clf,out_file = None ,feature_names= feature_name,class_names=["琴酒","雪莉","贝尔摩德"] ,filled=True,rounded=True) with open(r'C:\Users\86186\Desktop\AI-利率定价\dot测试.txt', 'w') as f:
f.writelines(dot_data)
我们成功将dot格式的文件保存在txt文件中。打开该文件后,原始状态如下图:未修改前
我们可以手动进行如下修改:步骤1:将两处helvetica,修改为"Microsoft YaHei",注意helvetica没有引号,但修改好的中文字体一定一定要加引号,否则会画不出图!!!!步骤2,另存为UTF-8格式,注意在另存的时候在新的文件名的下方有选择保存的格式,调整为UTF-8即可。调整好的状态为下图:修改好字体和编码格式后的样子
3、重新加载这个dot文件并画图
进行上述修改后,有两种方法可以画出中文图。
一是将另存为的这个txt重新读取,并绘图,代码如下:
with open((r'C:\Users\86186\Desktop\AI-利率定价\dot测试1.txt',"r",encoding='utf-8') as f:
text = f.read()
graph = pydotplus.graph_from_dot_data(text)
graph.write_png("试试.png")
如要保存为pdf格式,此处可改为graph.write_pdf("iris.pdf") 。pydotplus要先pip安装后,在程序中import。
二是在CMD命令行窗口,将路径切换成存放这个dot文件的文件夹,然后运行以下命令:
dot -Tpng dot测试1.txt -o example.png
如要保存为pdf格式,此处将后缀名改为pdf即可。
4、懒人的方法
如果嫌本攻略的2和3手工操作繁琐,可运用codecs库将原dot文件自动改为UTF-8格式,并将讨厌的helvetica自动改为"Microsoft YaHei"(请千万注意字体加引号,并重新加载画图,从而实现一次性运行(首次画中文图,第一步仍然需要):
with open(r'C:\Users\86186\Desktop\AI-利率定价\dot测试.txt', 'w') as f:
f.writelines(dot_data)
import codecs
txt_dir = r'C:\Users\86186\Desktop\AI-利率定价\dot测试.txt'
txt_dir_utf8 = r'C:\Users\86186\Desktop\AI-利率定价\dot测试1.txt'
with codecs.open(txt_dir, 'r') as f, codecs.open(txt_dir_utf8, 'w', encoding='utf-8') as wf:
for line in f:
lines = line.strip().split('\t')
if 'label' in lines[0]:
newline = lines[0].replace('\n', '').replace(' ', '')
else:
newline = lines[0].replace('\n','').replace('helvetica', '"Microsoft YaHei"')
wf.write(newline + '\t')
with open(txt_dir_utf8, "r",encoding='utf-8') as f:
text = f.read()
graph = pydotplus.graph_from_dot_data(text)
graph.write_png("试试.png")
特别说明:本人使用的开发环境是VS code,画图命令通过pydotplus库进行,可能不如Jupter notebook方便,但改成中文的原理是一样的。