scikit-learnの決定木を表示させる方法

概要と動機

Pythonではじめる機械学習の中で出てくる決定木の解析(sklearn.datasetsのcancerデータ)でツリー表示の可視化をしたい。
だが、Ipythonを使用していないpython3.6の環境下で、scikit-learnを使って決定木を可視化しようとして、つまづいた。

使用した環境

もともとあった環境

  • python3.6
  • numpy
  • scikit-learn

今回インストールした環境

  • graphviz (pip installの後、msiにてインストール)
  • ydotplus (pip install)

Ipython・Jupyter環境下以外では

下記のコードを見てみるとgraphvizモジュールが必要で、graphvizはdot言語で書かれているようでpydotplusというモジュールも必要とのことなので、

pip install graphviz
pip install pydotplus

と、graphvizとpydotplusをpipインストールをした後、実行したスクリプトは、

file_name = "./tree.dot"
export_graphviz(tree, out_file=file_name, class_names=["malignant", "benign"],
                feature_names=cancer.feature_names, impurity=False, filled=True)
with open(file_name) as f:
    dot_graph = f.read()
graphviz.Source(dot_graph)

・・・チーン、何も表示されないし、と思っていると、Ipthon・Jupyterじゃないもんねと気がつく。
そこで、

file_name = "./tree.dot"
export_graphviz(tree, out_file=file_name, class_names=["malignant", "benign"],
                feature_names=cancer.feature_names, impurity=False, filled=True)
graph = pydotplus.graph_from_dot_file(file_name)
graph.write_png("tree.png")

のように変えたところ、

Traceback (most recent call last):
(中略)
pydotplus.graphviz.InvocationException: GraphViz's executables not found

のように、GraphViz's executable not found(GraphVizの実行ファイルが見つからないですよ)
エラーが出て動きません。

エラー対策

Python3でscikit-learnの決定木を日本語フォントで画像出力する方法のまとめ | 自調自考の旅
ここに対策が書いてあったので、これを参考に、graphviz.pyのfind_graphviz関数を下記のように書き換えます。

def find_graphviz():
    """Locate Graphviz's executables in the system.

    Tries three methods:

    First: Windows Registry (Windows only)
    This requires Mark Hammond's pywin32 is installed.

    Secondly: Search the path
    It will look for 'dot', 'twopi' and 'neato' in all the directories
    specified in the PATH environment variable.

    Thirdly: Default install location (Windows only)
    It will look for 'dot', 'twopi' and 'neato' in the default install
    location under the "Program Files" directory.

    It will return a dictionary containing the program names as keys
    and their paths as values.

    If this fails, it returns None.
    """
    #dot.exe等の実行ファイルがあるパスをハードコーディングする。
    return __find_executables("C:\\Program Files (x86)\\Graphviz2.38\\bin")

これで、エラーがが出なくなりました。が・・・あれ、描画されない??

表示方法

明示的に表示していないので、表示されるわけがないですよね。
とにかく表示したい場合は、PILのImage関数を使って

img =Image.open("ファイル名")
img.show()

と書けばいい。

最終コードと結果

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import pydotplus
from PIL import Image

dot_file_name = "./tree.dot"
png_file_name = "./tree.png"
export_graphviz(tree, out_file=dot_file_name, class_names=["malignant", "benign"],
                feature_names=cancer.feature_names, impurity=False, filled=True)
graph = pydotplus.graph_from_dot_file(dot_file_name)
graph.write_png(png_file_name)
img =Image.open(png_file_name)
img.show()

f:id:chihayaChitose:20180917170607p:plain


PATHを通す

import graphviz 

glaph = graphviz .Digraph(format="png")
(中略)
G.render("graphs")

上記で解決したと思いきや、上記のコードを実行しようとすると、下記エラーが発生します。
ExecutableNotFound: failed to execute ['dot', '-Tpng'],make sure the Graphviz executables are on your systems ' PATH
どうしたものかと悩んでいると、
Graphviz をインストールする
には、とどのつまりPATHを通さないとダメですよと書いてありました。
環境変数の変数:PATH に 値:C:\Program Files (x86)\Graphviz2.38\bin と通してあげることでrenderの問題も解決しました。
値は環境によって変わりますので、適宜変更してください。Graphvizをインストールしたフォルダにある『bin』フォルダのPathとなります。