如何更优雅地可视化决策树续:完美中文支持


自从知道了如何更优雅地可视化决策树 后,发现中文支持很差,就一直避免使用中文,最近的项目不得不输出中文,于是下决心解决掉它。

dtreeviz[1] 基于 matplotlib, 网上关于 matplotlib 中文支持的方案很多,但没有一个能解决问题, 认真查看代码后,发现需要同时从两方面下手,

  • 修改 matplotlib 的配置
  • 修改 dtreeviz 的底层代码

修改 dtreeviz 底层代码实现中文支持

修改 matplotlib 的配置只能部分解决乱码问题,于是需要从底层代码来解决这个问题。

dtreeviz 在trees.pyclassifiers.py 使用了默认字体Arial, 我通过简单修改, 允许配置默认的字体。先附上简单的代码实现。

utils.py 添加一个变量,

import matplotlib.pyplot as plt

default_font=plt.rcParams['font.sans-serif'][0]

这样只需要修改 matplotlib 默认字体就可以达到中文的完美支持(当然日语韩语也不是问题,只要有合适的字体),修改后的代码我放在了https://Github.com/alitrack/dtreeviz

修改 matplotlib 默认字体

下面这段代码要优先执行

default_font = 'Arial Unicode MS'
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif']=[default_font]+plt.rcParams['font.sans-serif']
plt.rcParams['axes.unicode_minus']=False # 确保正常显示减号➖

这样做的好处,是它这是当前环境下修改了 matplotlib 配置,并不会影响别的程序。

不建议修改配置文件(对于 seaborn,即使修改配置文件也没有用),可能影响别的程序。

测试效果

from sklearn.datasets import *
from sklearn import tree
from dtreeviz.trees import *
classifier = tree.DecisionTreeClassifier(max_depth=3)
iris = load_iris()
classifier.fit(iris.data, iris.target)
#测试需要
feature_names=['萼片sepal length (cm)','sepal width (cm)'
,'花瓣petal length (cm)','花瓣petal width (cm)']
class_names=["山鸢尾 (부채붓꽃)""变色鸢尾(ブルーフラッグ)"
"维吉尼亚鸢尾(Iris-virginica)"]
## 画决策树
viz = dtreeviz(classifier,
               iris.data,
               iris.target,
               target_name='variety',
               feature_names=feature_names,
               class_names=class_names  # need class_names for classifier
              )

viz

输出

如何更优雅地可视化决策树续:完美中文支持

中日韩都不是问题?

如果你的系统没有中文字体,或者没有你想要的中文字体咋办?下面就介绍下如何给 matplotlib 安装中文字体。

给 matplotlib 安装中文字体

对于 macOS 和 Linux 可以使用下面两种方式来判断是否有你想要的字体

fc-list :lang=zh

或者

font_manager.fontManager.ttflist

会返回系统安装的字体以及字体所对应的字体名(不同于字体文件名)

<Font 'Arial Unicode MS' (Arial Unicode.ttf) normal normal 400 normal>,

判断 matplotlib 默认字体及安装路径

通过下面命令,可以得知 matplotlib 的默认字体是DejaVuSans.ttf,默认安装路径(具体看你的 Python 虚拟环境安装位置)是,

/Users/steven/anaconda3/envs/py39/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/
from matplotlib import pyplot as plt
plt.rcdefaults() # 恢复到初始化设置
from matplotlib.font_manager import findfont, FontProperties
findfont(FontProperties(family=FontProperties().get_family()))

返回

'/Users/steven/anaconda3/envs/py39/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf'

下载与安装字体

  • 下载想要的字体

比如 SimHei(simhei.ttf), Arial Unicode MS(Arial Unicode.ttf)

  • 下载安装

下载好的字体 copy 到对应的目录,

cp simhei.ttf /Users/steven/anaconda3/envs/py39/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/
rm -rf ~/.matplotlib
  • reset 当前 notebook(如果是在 notebook 里)

seaborn 的中文支持

seaborn 也是基于 matplotlib, 它的中文支持更加方便,但网上的方案基本都有问题

import seaborn as sns
from matplotlib import pyplot as plt

iris = sns.load_dataset('iris')

iris.columns=['萼片sepal_length''萼片sepal_width''花瓣petal_length''花瓣petal_width',
       'species']
iris.replace(["setosa","versicolor","virginica"],
           ["山鸢尾 (부채붓꽃)""变色鸢尾(ブルーフラッグ)""维吉尼亚鸢尾(Iris-virginica)"],
           inplace=True)
# sns.set_style("whitegrid",{"font.sans-serif":plt.rcParams['font.sans-serif']})
# style used as a theme of graph
# for example if we want black
# graph with grid then write "darkgrid"
sns.set_style("whitegrid")
#set_style 会 override plt.rcParams['font.serif'],我们再override回来
plt.rcParams['font.sans-serif']=[default_font]+plt.rcParams['font.sans-serif']
plt.rcParams['axes.unicode_minus']=False # 让负号也能正常显示

sns.pairplot(iris, hue="species")

输出

如何更优雅地可视化决策树续:完美中文支持

sns.set_style("whitegrid")会覆盖 matplotlib 的默认字体设置,

这里可以做个简单的验证,

default_font="Arial Unicode MS"
plt.rcdefaults()
print("matplotlib默认:",plt.rcParams['font.sans-serif'])
sns.set_style('darkgrid')
print("被seaborn修改后:",plt.rcParams['font.sans-serif'])
plt.rcParams['font.sans-serif']=[default_font]+plt.rcParams['font.sans-serif']
print("再改回来:",plt.rcParams['font.sans-serif'])

如何更优雅地可视化决策树续:完美中文支持

而我们要做就是在这个代码之后,改为我们希望的字体即可。

plt.rcParams['font.sans-serif']=[default_font]+plt.rcParams['font.sans-serif']

从上面 dtreeviz 和 seaborn 来看,关键是看字体配置啥时候被修改,记得改回来,使用你希望的字体。

字体资源

Google Noto Fonts[2]

Google 开源的字体,Notono more tofu 的缩写(别再显示豆腐块,就是那种无法显示的字体以方块形式出现,像豆腐),noto-cjk 的 GitHub 网址是https://github.com/googlefonts/noto-cjk。

其它的网上自己搜索吧。

参考资料

[1]

dtreeviz: https://github.com/alitrack/dtreeviz

[2]

Google Noto Fonts: https://www.google.com/get/noto/


原文始发于微信公众号(alitrack):如何更优雅地可视化决策树续:完美中文支持

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/62929.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!