33
30

More than 3 years have passed since last update.

LightGBM/XGBoostのtree構造可視化メモ

Last updated at Posted at 2021-01-04

はじめに

LightGBMとXGboostのtree構造を可視化したいと思いdtreevizとplot_treeを試したときの備忘録。

環境

実行した環境は以下の通り。


$sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G14042

Jupyter Notebookを使用しました。

The version of the notebook server is: 5.7.8
The server is running on this version of Python:
Python 3.7.3 (default, Mar 27 2019, 16:54:48) 
[Clang 4.0.1 (tags/RELEASE_401/final)]

モデル構築

tree構造の可視化が目的なので、データはscikit-learnのbostonデータセットを使用しました。 506行13列のデータで、すべてNullがなくfloat型なので、特徴量エンジニアリングなどはせず、そのままモデルを構築します。

import pandas as pd
import sklearn.datasets as skd

data = skd.load_boston()

df_X = pd.DataFrame(data.data, columns=data.feature_names)
df_y = pd.DataFrame(data.target, columns=['y'])

df_X.info()
#<class 'pandas.core.frame.DataFrame'>
#RangeIndex: 506 entries, 0 to 505
#Data columns (total 13 columns):
#CRIM       506 non-null float64
#ZN         506 non-null float64
#INDUS      506 non-null float64
#CHAS       506 non-null float64
#NOX        506 non-null float64
#RM         506 non-null float64
#AGE        506 non-null float64
#DIS        506 non-null float64
#RAD        506 non-null float64
#TAX        506 non-null float64
#PTRATIO    506 non-null float64
#B          506 non-null float64
#LSTAT      506 non-null float64
#dtypes: float64(13)
#memory usage: 51.5 KB

LightGBMのモデル構築。ハイパーパラメータなどはほぼデフォルトを使用します。


import lightgbm as lgb
from sklearn.model_selection import train_test_split

df_X_train, df_X_test, df_y_train, df_y_test = train_test_split(df_X, df_y, test_size=0.2, random_state=4)

lgb_train = lgb.Dataset(df_X_train, df_y_train)
lgb_eval = lgb.Dataset(df_X_test, df_y_test)

params = {
    'seed':4,
    'metric':'rmse'}

lgbm = lgb.train(params,
                lgb_train,
                valid_sets=lgb_eval,
                num_boost_round=200,
                early_stopping_rounds=20,
                verbose_eval=50)

#Training until validation scores don't improve for 20 rounds
#[50]   valid_0's rmse: 3.58803
#[100]  valid_0's rmse: 3.39545
#[150]  valid_0's rmse: 3.31867
#[200]  valid_0's rmse: 3.28222
#Did not meet early stopping. Best iteration is:
#[192]  valid_0's rmse: 3.27283

XGBoostのモデル構築。

import xgboost as xgb

dtrain = xgb.DMatrix(df_X_train, label=df_y_train)
dtest = xgb.DMatrix(df_X_test, label=df_y_test)

params = {
    'objective': 'reg:squarederror',
    'eval_metric': 'rmse',
}

evals = [(dtrain, 'train'), (dtest, 'eval')]
evals_result = {}

xgbm = xgb.train(params,
                dtrain,
                num_boost_round=200,
                early_stopping_rounds=20,
                evals=evals,
                evals_result=evals_result
                )

#(中略)
#[80]   train-rmse:0.05752  eval-rmse:3.96890
#[81]   train-rmse:0.05430  eval-rmse:3.96797
#[82]   train-rmse:0.05194  eval-rmse:3.96835

dtreeviz

決定木アルゴリズムの決定木を可視化するツール。
公式のGithubにインストール方法が記載されていますが、pip install dtreevizを実行した際に、内部でxgboostをインストールするようになっていて、エラーとなってしまいインストールができませんでした。
そこで、こちらを参考にしたら、xgboostを無事にインストールできました。

xgboostのインストール後に、pip install dtreevizを再度実行して、無事にdtreevizのインストール完了。

LightGBMのモデルに対してdtreevizを使用しようとすると、

from dtreeviz.trees import *

viz = dtreeviz(lgbm,
               x_data=df_X_train,
               y_data=df_y_train['y'],
               target_name='y',
               feature_names=df_X_train.columns.tolist(),
              tree_index=0)

viz.save('./lgb_tree.svg')    

#ValueError: Tree model must be in (DecisionTreeRegressor, DecisionTreeClassifier, xgboost.core.Booster, but was Booster      

ということで、そもそもdtreevizはLightGBMに対して使えないことが分かりました。

気を取り直して、XGBoostのモデルに対して可視化してみます。

from dtreeviz.trees import *

viz = dtreeviz(xgbm,
               x_data=df_X_train,      # x_dataはDataFrame
               y_data=df_y_train['y'], # y_dataはSeries
               target_name='y',
               feature_names=df_X_train.columns.tolist(), # StringのList
              tree_index=0 ) # アンサンブルモデルを使用するときはindexを指定しないとエラーになる


viz.save('./xgb_tree.svg')   

dtreevizでは出力がsvg形式なので、一度Inkscapeを起動してpdfへ変換しました。
Inkscapeはversion 1.0.1を使用しています。インストールはここを参考にしました。下図のような結果を得ました。

xgb_tree.png

plot_tree (graphviz)

LightGBMとXGBoostにplot_treeという関数が用意されていて、これでtree構造を可視化できます。
内部でgraphvizを使用するので、インストールが必要となります。
インストール方法はこちらに記載されているように、
brew install graphvizでOKのはずですが、自分の環境だと

Error: graphviz: no bottle available!
You can try to install from source with e.g.
  brew install --build-from-source graphviz
Please note building from source is unsupported. You will encounter build
failures with some formulae. If you experience any issues please create pull
requests instead of asking for help on Homebrew's GitHub, Twitter or any other
official channels.

エラーが出てインストールできなかったので、エラーメッセージにあるように


$brew install --build-from-source graphviz

を実行。これでインストールできました。
まずはLightGBMのtree構造を可視化します。


ax = lgb.plot_tree(gbm, tree_index=0, figsize=(20, 20), show_info=['split_gain'])
plt.show()
graph = lgb.create_tree_digraph(gbm, tree_index=0, format='png', name='Tree')
graph.render(view=True)

得られた出力が下図。

Tree.gv.png

続いてXGBoostの可視化もしてみます。

ax = xgb.plot_tree(xgbm, num_trees=0, figsize=(20, 20))
plt.show()
graph = xgb.to_graphviz(xgbm, num_trees=0)
graph.render(view=True,format='png')

実行すると下図を得ます。

Source.gv.png

まとめ

LightGBMとXGBoostに対して、dtreevizとplot_treeを試してみました。
dtreevizだと散布図が表示されるので、イメージしやすいと思いました。
ただ、使えるアルゴリズムが限られているので、ちょっと不便。

33
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
30