機械学習の決定木分析で構築されたツリーは、コンピュータが生成した条件分岐ノードの情報が記載されます。ここではPython/scikit-learnで計算した決定木をdotファイルで出力し、Graphvizというツールをインストールして可視化する方法を紹介します。
こんにちは。wat(@watlablog)です。
ここではグラフ可視化ツールであるGraphvizのインストールとPython決定木分析結果の可視化までを紹介します!
決定木のグラフを可視化する主な理由2選
当WATLABブログでは「Python/sklearnで決定木分析!分類木の考え方とコード」で簡単なサンプルデータに対して決定木分析を行ってみました。
最終的には以下の図を得ることができ、与えたデータをしっかりと分類していることまでを確認しました。
ここではこの図が描かれる根拠を示す決定木のツリー構造を可視化する方法の例を説明しますが、可視化することでどんなメリットがあるのでしょうか。
以下に主な可視化する理由を調べてみました。
①決定木のシンプルさと精度のトレードオフを検討する
決定木は条件分岐を繰り返すことで複雑なデータも無理やり分類してしまうような条件を付けることも可能です。
しかし、あまり複雑な条件を付けると教師データに対しては問題なくても、新規テストデータに対して全く使い物にならない過学習(オーバーフィッティング)モデルが出来てしまう可能性が高くなります。
モデルはシンプルにして汎化性能を高くしたい!
でも精度も欲しい!
このように精度と汎化性能はトレードオフの関係であるため、決定木の深さや1ノードの最小データ数等のハイパーパラメータを調整したりするのですが、パラメータの探査範囲をざっくりと把握した方がより効率の良い探査(グリッドサーチ等)が可能になります。
トレードオフの関係を調べるために「決定木の素性を知る」という理由で可視化は有用です。
②他者に説明する
ディープラーニングがブラックボックス的な動作をするのに対し、決定木はツリー構造を構築して分類や回帰を行います。ツリー構造がそのままモデルの設計理由になるのでホワイトボックス的と言うことができます。
これは他者へモデルの説明をする際のエビデンスや仕様書のような役割もこなすと考えられます。
そのため、決定木で良いモデルが出来上がったら図としてツリー構造をいつでも説明できるようにしておくと組織としての仕事やクライアントとのやり取りもスムーズにいくことでしょう。
Graphvizをインストールする(Windows)
決定木の可視化方法は様々な方法がありますが、まずは基本的な内容のGraphvizによるdotファイルの可視化を紹介します。
dotファイルというのはグラフ(グラフ理論とかのグラフ)を記述したファイルで、Pythonのscikit-learnの決定木分析では自動生成する関数があります。それをグラフ可視化ツールGraphvizで可視化するという流れです。
インストール環境
このページでは以下の表に示す環境でインストールや動作を確認しています。Windows10ユーザであれば本ページと同様の操作になると思います。
OS | Windows10 Home |
ビット数 | 64bit |
メモリ | 8GB |
クロック周波数 | 1.6GHz |
Graphviz公式ページでソフトを入手
Graphvizは公式ページからダウンロードしてインストールを行います。以下の公式ページにアクセスして下さい。
Graphviz公式ページ:http://www.graphviz.org/
公式ページにアクセスできたら、ページ上部にある「Download」をクリックしダウンロードページに行きます。
ダウンロードページに遷移したら、次は画面を下にスクロールし、Windowsの項目にある「Windows install packages」をクリックします。
移動したページの先にある「~.msi」ファイルがインストールファイルなのでクリックしてダウンロードします。
(.zipファイルでも構いません。お好みでダウンロードして下さい。)
ダウンロードした.msiファイルをダブルクリックするとインストーラが起動します。数回「Next」をクリックするとインストールが始まります。
進捗バーが最後まで行くとインストールは完了です。「Close」をクリックしてインストーラを終了させます。
環境変数にパスを追加する
続いて環境変数へパスを追加します。いわゆる「パスを通す」という作業です。
Windowsであればエクスプローラの「PC」を右クリック→「プロパティ」、もしくはコントロールパネルから「システムのプロパティ」にアクセスします。
以下の画面が表示されるので「詳細設定」タブの「環境変数」をクリックして下さい。
システムの環境設定の欄に「Path」もしくは「PATH」があればクリックしてハイライトさせ、「編集」をクリックします。
なければそのまま「新規」をクリックします。
Graphvizをインストールしたフォルダの中に「bin」フォルダがあります。このbinフォルダまでのフルパスを下の画像のように登録して下さい。
開いている画面を全て「OK」で抜ければパスを通す作業は完了です。
Graphvizをインストールする(Mac)
Mac版はbrewコマンドで簡単にインストール可能です。Homebrewが必要ですが、詳しくは「macOSにPython3をインストールする方法をまとめてみた」を確認下さい。
1 |
brew install graphviz |
Python/scikit-learnの決定木を可視化する
Pythonコード(dotファイルを生成する)
以上で準備は完了したので、早速Pythonのコードから説明します。
以下のPythonコードは「Python/sklearnで決定木分析!分類木の考え方とコード」で紹介したコードからテストデータによる予測とグラフプロットを抜いた部分を基本としています。
サンプルデータを生成し、scikit-learnによる決定木分析を行う所までは一緒(max_depth=3を追加していますが)ですが、最後に「tree.export_graphviz」で構築した分類木(clf)をtree.dotというdotファイルにしている所が今回の内容です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import numpy as np import pandas as pd from sklearn import tree # データを用意する------------------------------------------ df = pd.DataFrame() # データフレーム初期化 n = 20 # 1クラス毎のデータ数 for i in range(3): # データ作成ループ if i == 0: x = pd.Series(np.random.uniform(0.5, 2.8, n)) y = pd.Series(x * np.random.uniform(0.8, 1.2, n)) elif i == 1: x = pd.Series(np.random.uniform(2.2, 3.8, n)) y = pd.Series(np.random.uniform(0.5, 1.8, n)) else: x = pd.Series(np.random.uniform(3.2, 3.8, n)) y = pd.Series(np.random.uniform(2.2, 3.8, n)) label = pd.Series(np.full(n, i)) # ラベル(クラス)を作成 temp_df = pd.DataFrame(np.c_[x, y, label]) # クラス毎のデータフレームを作成 df = pd.concat([df, temp_df]) # 作成されたクラス毎のデータを逐次結合 df.index = np.arange(0, len(df), 1) # index(行ラベル)を初期化 # クラス毎のデータフレームに分離(プロット用) class_0 = df[df[2] == 0] # ラベル0を抽出 class_1 = df[df[2] == 1] # ラベル1を抽出 class_2 = df[df[2] == 2] # ラベル1を抽出 # ---------------------------------------------------------- # 学習させる値(訓練データ)とクラス(正解ラベル)に分離 data = df[[0, 1]] # 訓練データ data_class = pd.Series(df[2]) # 正解ラベル # 決定木による学習 clf = tree.DecisionTreeClassifier(max_depth=3) # 決定木の分類木オブジェクトを定義 clf.fit(data, data_class) # フィッティング # dotファイルの生成 tree.export_graphviz(clf, out_file='tree.dot') # cmdで「dot -Tpng tree.dot -o tree.png」を打ち可視化する。 |
このコードを実行するとtree.dotというファイルが.pyが動作しているフォルダ内に生成されます。
コマンドプロンプトでdotファイルをpng画像にする
※Macのターミナルでも全く同様のコマンドです。
dotファイルのあるフォルダをカレントディレクトリにする
後の作業はdotファイルの可視化ですが、Windowsであればコマンドプロンプトで行います(プログラム的に全て実行する方法は別途)ので、Windowsの「ここに入力して検索」に「cmd」と打つ等してコマンドプロンプトを起動して下さい。
まずは先ほど生成したdotファイルがあるフォルダを以下のコマンドでカレントディレクトリにします。
1 |
cd dotファイルを生成したフォルダ |
dot.exeでdotファイルをpng画像にする
次に以下のコマンドでdot.exe(Graphvizインストール時に一緒に追加される実行ファイル)を実行し、dotファイルをpng画像に変換します。
1 |
dot -Tpng tree.dot -o tree.png |
上記コマンドを実行すると、以下の画像が生成されます。
1行目が条件式([]内の数値が特徴量の列番号)、2行目のginiがジニ係数、3行目のsamplesがノード内サンプル数、4行目のvalueにクラス毎のサンプル数が記載されています!
それぞれの意味やジニ係数の算出方法は、
「Python/sklearnで決定木分析!分類木の考え方とコード」を参照下さい!
おまけ:決定木の見た目を変更する
最後に、tree.export_graphvizはオプションで色を塗ったり角を丸めたり、特徴量名やクラス名を表示させたりが可能です。
以下のdotファイル生成部分のコードを修正するだけで見た目を変えることが可能です。
1 2 3 4 5 6 7 8 |
# dotファイルの生成 tree.export_graphviz(clf, # モデル out_file='tree.dot', # ファイル名 filled=True, # 色を塗る rounded=True, # 角を丸める feature_names=['feature1','feature2'], # 特徴量名 class_names=['0', '1', '2'] # クラス名 ) |
紹介した全コードを修正して実行、画像生成まで行うと以下の結果を得ます。
tree.export_graphvizを使った可視化結果ではよく見る形式となりました(サンプルデータがランダム値なので、先ほどの図と同じではありませんが)。
色はクラスで分かれているみたいです。また、不純度を意味するジニ係数の大小で色の濃さが変わっているようです。
白黒の論文に載せる時は色を付けるのはどうかと思いますが、特徴量やクラスが多い時は名前があった方がわかりやすいですね。
まとめ
本記事では決定木のツリー構造を可視化するメリットや理由を考え、Pythonのscikit-learnとGraphvizを使った簡単な可視化方法を紹介しました。
世の中には他にも様々な可視化方法がありますが本方法がscikit-learnの標準方法と考えられます。
その他の方法は必要に応じて実践データを扱う中で習得していこうと思います。
ツリー構造の可視化結果を眺めているとこれまで気付かなかったデータの特徴に気が付くかも知れませんね!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!
コメント