はじめに
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を使用しています。インストールはここを参考にしました。下図のような結果を得ました。
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)
得られた出力が下図。
続いて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')
実行すると下図を得ます。
まとめ
LightGBMとXGBoostに対して、dtreevizとplot_treeを試してみました。
dtreevizだと散布図が表示されるので、イメージしやすいと思いました。
ただ、使えるアルゴリズムが限られているので、ちょっと不便。