LoginSignup
8
7

More than 1 year has passed since last update.

AutoML(AutoGluon)とSHAP を組合せて使ってみた

Posted at
  • 製造業出身のデータサイエンティストがお送りする記事
  • 今回はAutoML ライブラリー(AutoGluon)とSHAP を組合せてを使ってみました。

はじめに

過去に他のAutoML ライブラリーやツールについては、別の記事に纏めておりますので下記をご参照ください。

また、過去にSHAP やLIME の記事は、別の記事に纏めておりますので下記をご参照ください。

AutoGluon とSHAP を組合せて使ってみた

ライブラリーのインストールは下記です(Google Colab 使用前提)。

!pip install --upgrade pip
!pip install --upgrade setuptools
!pip install --upgrade "mxnet<2.0.0"
!pip install --pre autogluon
!pip install shap

今回もUCI Machine Learning Repositoryで公開されているボストン住宅の価格データを用いて実施します。

# ライブラリーのインポート
from autogluon.tabular import TabularDataset, TabularPredictor
import pandas as pd
import numpy as np

import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline

# ボストンの住宅価格データ
from sklearn.datasets import load_boston

# 前処理
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

import sklearn
import shap
import time

shap.initjs()

import warnings
warnings.filterwarnings('ignore')

# データセットの読込み
boston = load_boston()

# 説明変数の格納
df = pd.DataFrame(boston.data, columns=boston.feature_names)
# 目的変数の追加
df["MEDV"] = boston.target

# ランダムシード値
RANDOM_STATE = 10

# 学習データと評価データの割合
TEST_SIZE = 0.2

# 学習データと評価データを作成
x_train, x_test, y_train, y_test = train_test_split(
    df.iloc[:, 0 : df.shape[1] - 1],
    df.iloc[:, df.shape[1] - 1],
    test_size=TEST_SIZE,
    random_state=RANDOM_STATE,
)

# trainのデータセットの2割をモデル学習時のバリデーションデータとして利用する
x_train, x_valid, y_train, y_valid = train_test_split(
    x_train, y_train, test_size=TEST_SIZE, random_state=RANDOM_STATE
)

df_train = pd.concat([x_train, y_train], axis=1)
df_valid = pd.concat([x_valid, y_valid], axis=1)

今回は、オプション指定無しで実行してみます。

predictor = TabularPredictor(
    label='MEDV',
    problem_type='regression', 
    eval_metric='root_mean_squared_error',
)

predictor.fit(
            train_data=df_train,
            tuning_data=df_valid,
            time_limit=None,
)

y_pred = predictor.predict(x_test)

ここから、SHAP を使っていきます。
まず、AutoGluon のラッパークラスを作成して、SHAP パッケージ内で予測のために呼び出すことができるように設定します。

class AutogluonWrapper:
    def __init__(self, predictor, feature_names):
        self.ag_model = predictor
        self.feature_names = feature_names

    def predict(self, X):
        if isinstance(X, pd.Series):
            X = X.values.reshape(1,-1)
        if not isinstance(X, pd.DataFrame):
            X = pd.DataFrame(X, columns=self.feature_names)
        return self.ag_model.predict(X)

次に特徴量のベースライン参照値を定義します。

x_train_summary = shap.kmeans(x_train, 10)
print("Baseline feature-values: \n", x_train_summary)

特定のAutoGluon 予測を説明するカーネルSHAP 値を返すKernelExplainer を作成します。

ag_wrapper = AutogluonWrapper(predictor, boston.feature_names)
print_accuracy(ag_wrapper.predict)

explainer = shap.KernelExplainer(ag_wrapper.predict, x_train_summary)

NSHAP_SAMPLES = 100  
N_VAL = 30  

NSHAP_SAMPLES は、各SHAP 値を計算するために使用するサンプルの数であり、値が大きいほど遅くなります。
N_VAL は、予測結果を解釈する際に必要となるデータポイントの数であり、値が大きいほど遅くなります。

特定の行に対しての予測結果は下記のように確認します。

ROW_INDEX = 0  # index of an example datapoint
single_datapoint = x_train.iloc[[ROW_INDEX]]
single_prediction = ag_wrapper.predict(single_datapoint)

shap_values_single = explainer.shap_values(single_datapoint, nsamples=NSHAP_SAMPLES)
shap.force_plot(explainer.expected_value, shap_values_single, x_train.iloc[ROW_INDEX,:]) 

カーネルSHAP に関する表示は以下のように実施します。

shap_values = explainer.shap_values(x_valid.iloc[0:N_VAL,:], nsamples=NSHAP_SAMPLES)
shap.force_plot(explainer.expected_value, shap_values, x_valid.iloc[0:N_VAL,:])

次に、SHAP value とFeature value の関係性を確認します。

shap.summary_plot(shap_values, x_valid.iloc[0:N_VAL,:])

image.png

特徴量の値とShapley Value の散布図は下記のように描画できます。

shap.dependence_plot("LSTAT", shap_values, x_valid.iloc[0:N_VAL,:])

image.png

さいごに

最後まで読んで頂き、ありがとうございました。
一部、AutoGluon とSHAP の活用で上手く理解できていない部分もありますが、AutoML とSHAP を組合せることができるのは良いなと思いました。

訂正要望がありましたら、ご連絡頂けますと幸いです。

8
7
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
8
7