AutoML③(train_size変更)

train_size変更

訓練データの分割の割合は、setup関数の引数train_sizeで変更可能です。(6行目)

(またasilentにTrueを指定することで型確認のダイアログをスキップすることができます。)(7行目)

[Google Colaboratory]

1
2
3
4
5
6
7
ret = setup(boston_data,
target = "medv",
session_id=0,
normalize = False,
numeric_features = ["chas"],
train_size = 0.8,
asilent=True)

今回はtrain_size0.8を指定したので、訓練データが80%、テストデータが20%になります。

[実行結果]

Transformed Train SetTransformed Test Setのサイズが変わっていることが確認できます。

AutoML②(PyCaretで前処理を行う)

PyCaretで前処理

PyCaretで前処理を行います。

setup関数を使うと、データを分析し、必要な前処理を自動的に行ってくれます。(2~5行目)

引数の意味は下記の通りです。

  • 第1引数
    データセット(ボストンの住宅価格データセット)。
  • 第2引数(target)
    目的変数。
  • 第3引数(normalize)
    標準化するかどうか。
  • 第4引数(session_id)
    PyCaretの実行時の識別子で、内部的には乱数のseedとして使用。
    指定しない場合はランダム。

[Google Colaboratory]

1
2
3
4
5
from pycaret.regression import *
ret = setup(boston_data,
target = "medv",
normalize = False,
session_id=0)

[実行結果]

setup関数を実行すると、PyCaretは各変数の型を推定して、ダイアログを表示してユーザに推定結果の確認と処理の続行を促します。

型の推定結果が正しければ、ダイアログのエディットボックスでEnterキーを押下すうことで処理が続行されます。

指定された型がおかしな場合は、quitと入力することで処理を中断できます。

型の変更

chas列は、Categoricalと認識されていますがNumbericとして扱うように変更してみます。

[Google Colaboratory]

1
2
3
4
5
6
from pycaret.regression import *
ret = setup(boston_data,
target = "medv",
session_id=0,
normalize = False,
numeric_features = ["chas"])

numeric_features“chas”を指定して実行しています。(6行目)

[実行結果]

“chas”の型がNumericに変更されているのが確認できます。

setupダイアログの前処理結果を確認

ダイアログのエディットボックス上でEnterキーを押下して処理を完了すると、setupダイアログに前処理の結果が表示されます。

[実行結果]

setupでは欠損値処理、データの分割(train_test_split)などを実施しており、完了すると結果が表示されます。

この表から、データサイズや説明変数の数や、各種前処理の指定有無などを確認することができます。

  • Missing Values
    元のデータに欠損値がある場合、Trueが表示されます。
    今回はFaseになっているので、欠損値がないことを示しています。
  • Transformed Train Set / Transformed Test Set
    デフォルトで訓練データが70%、テストデータが30%になっています。
    また、元のデータセット(Oriinal Data)の説明変数は14ですが、21に増えています。
    これは、PyCaretが前処理でカテゴリ変数に変換しているためです。
    さらにCategoria Featuresが1となっており、1つの説明変数がカテゴリ変数に変換されたことが分かります。

このようにPyCaretは加工を含む前処理を自動で実施してくれるのです。

AutoML①(PyCaret)

AutoML

AutoMLを使うと、機械学習モデルを構築するために必要な以下の処理を非常に簡単に行うことができます。

  • データの前処理
  • 複数のアルゴリズムでのモデル構築
  • ハイパーパラメータチューニング
  • 精度評価
  • SHAPによるモデル解釈

PyCaret

PyCaretは、代表的な機械学習ライブラリ(scikit-learn、XgBoostなど)をラップしており、回帰、分類、クラスタリング、次元削減はもちろん、異常検知や自然言語処理にも対応可能なライブラリです。

さらに、機械学習の前処理モデルの比較もほとんど自動化でき、可視化プロットも豊富に用意され、SHAPの機能も含んでいます。

まずはPyCaretライブラリをインストールします。

[Google Colaboratory]

1
2
3
!pip install pycaret
from pycaret.utils import enable_colab
enable_colab()

2~3行目では、GoogleColab上でPyCaretを利用するために必要な関数を実行しています。

データセットの読み込み

回帰モデルを構築するために必要なボストンの住宅価格データセットを読み込みます。

[Google Colaboratory]

1
2
from pycaret.datasets import get_data 
boston_data_all = get_data("boston")

[実行結果]

次に、訓練データとテストデータを9:1の割合で分割します。

[Google Colaboratory]

1
2
3
4
5
boston_data = boston_data_all.sample(frac =0.90, random_state = 0).reset_index(drop=True)
boston_data_unseen = boston_data_all.drop(boston_data.index).reset_index(drop=True)
print("All Data: " + str(boston_data_all.shape))
print("Data for Modeling: " + str(boston_data.shape))
print("Unseen Data For Predictions: " + str(boston_data_unseen.shape))

[実行結果]

次回は、今回準備したPyCaretライブラリデータセットを使って、データ分析の前処理を自動的に行います。

説明可能なAI⑪(waterfall_plotで貢献度を可視化)

waterfall_plot

waterfall_plotは、force_plotと表現方法が違うだけで同じように具体的な貢献度を可視化することができます。

[Google Colaboratory]

1
2
3
4
5
6
7
shap.initjs()
row_index = 2
for i in range(2):
print("Class ", i)
display(shap.plots._waterfall.waterfall_legacy(explainer.expected_value[i],
shap_values[i][row_index,:],
X_test.iloc[row_index,:]))

陽性と陰性でループさせて、各カテゴリごとのSHAP値でforce_plotを実行し、貢献度を表示しています。(3~7行目)

[実行結果]

force_plotでのbase_valueは、上図(陽性判定)でE[f(X)]=0.381と表示されています。

E[f(X)]を基点として下から上へSHAP値を足し引きして、最終的にf(x)=0.027になることが確認できます。

また下図(陰性判定)ではE[f(X)]=0.619と表示されています。

E[f(X)]を基点として下から上へSHAP値を足し引きして、最終的にf(x)=0.973になることが確認できます。

force_plotwaterfall_plotは、表現方法が異なるだけなので好きな方を利用するようにしましょう。

説明可能なAI⑩(force_plotで貢献度を可視化)

force_plot

force_plotを使うと、SHAP値と特徴量の貢献度を視覚化することができます。

[Google Colaboratory]

1
2
3
4
5
shap.initjs()
row_index = 2
for i in range(2):
print("Class ", i)
display(shap.force_plot(explainer.expected_value[i], shap_values[i][row_index,:], X_test.iloc[row_index,:]))

陽性と陰性でループさせて、各カテゴリごとのSHAP値でforce_plotを実行し、貢献度を表示しています。(3~5行目)

[実行結果]

同じデータに対して陽性か陰性かという2つの分類クラスに対するスコアと、そのスコアに対する各説明変数の貢献度が表示されています。

図の上側の陽性が0.0付近で、図の下側の陰性が1.0付近になっています。

説明可能なAI⑨(dependence_plotで可視化)

dependence_plot

dependence_plotを使うと、各カテゴリごとに2つのスコア(説明変数のSHAP値とその説明変数)を可視化することができます。

今回は、worst concave points(輪郭の凹部の数の最悪値)について可視化を行います。(3行目)

[Google Colaboratory]

1
2
3
4
5
6
for i in range(2):
print("Class ", i)
shap.dependence_plot(ind="worst concave points",
interaction_index=None,
shap_values=shap_values[i],
features=X_test)

乳がんの診断データセットは二値分類なので、ループさせて各カテゴリごとのSHAP値でdependence_plotを表示しています。

[実行結果]

同じデータに対して陽性か陰性かという2つのカテゴリに対するスコアが表示されています。

上図が陽性で、下図が陰性に関するグラフになります。

縦軸がSHAP値を表し、横軸がworst concave points(輪郭の凹部の数の最悪値)を表しています。

worst concave pointsが高ければカテゴリ0(陽性)に分類するSHAP値が高くなり、カテゴリ1(陰性)はその逆になっていることが確認できます。

説明可能なAI⑧(summary_plotで可視化)

summary_plot

分類系モデルにおける各説明変数の貢献度をsummary_plotで確認します。

[Google Colaboratory]

1
2
3
4
shap.summary_plot(shap_values=shap_values,
features=X_train,
plot_type="bar",
max_display=5)

[実行結果]

worst perimeter(周囲の最悪値)やworst concave points(輪郭の凹部の数の最悪値)などの貢献度が高いことが分かります。

また、分類系モデルのsummary_plotでは、色でどのカテゴリに対する貢献度が高いのかを確認することができます。

今回は二値分類なので2色で表示されており、どの説明変数もほぼ均等に貢献していることが確認できます。

説明可能なAI⑦(分類系モデルのSHAP値)

回帰モデルと同じように分類モデルでもSHAP値を確認することができます。

分類モデルを元に、SHAPモデルを作成して、SHAP値を確認します。

分類系モデル

乳がんの診断データセットを用いた分類モデルのランダムフォレストを利用します。

今回は説明変数をすべて利用します。(8行目)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
load_data = load_breast_cancer()
tg_df = pd.DataFrame(load_data.data, columns = load_data.feature_names)
tg_df["y"] = load_data.target
X = tg_df[tg_df.columns[tg_df.columns != "y"]] # 全ての説明変数を使用
y = tg_df["y"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
print(len(X_train))
display(X_train.head(1))
print(len(X_test))
display(X_test.head(1))
print(len(tg_df))
print(tg_df["y"].unique())

rf_cls = RandomForestClassifier(max_depth=3,random_state=0).fit(X_train, y_train)

[実行結果(一部略)]

分類系のランダムフォレストモデルが作成できました。

SHAPモデル

分類系モデルを引数にして、SHAPモデルを作成します。(1行目)

決定木モデルのランダムフォレストに対してはshap.TreeExplainerを利用します。

[Google Colaboratory]

1
2
explainer = shap.TreeExplainer(rf_cls)
explainer

[実行結果]

これでSHAPモデルが作成できました。

SHAP値

SHAP値を確認します。

[Google Colaboratory]

1
2
3
shap_values = explainer.shap_values(X_test)
print(len(shap_values))
print(shap_values)

[実行結果]

分類系モデルをベースにした場合、SHAP値は各カテゴリごとの配列になり、各カテゴリに対するSHAP値を出力します。

乳がんの診断データセットは二値分類なので2つのSHAP値が出力されます。

次回は回帰系と同じように、グラフを描画してSHAP値の解釈をしていきます。

説明可能なAI⑥(具体的な貢献度を可視化)

waterfall_plot

waterfall_plotは、force_plotと表現方法が違うだけで同じように具体的な貢献度を可視化することができます。

[Google Colaboratory]

1
2
3
4
5
row_index = X_test.index.get_loc(253)
shap.plots._waterfall.waterfall_legacy(
expected_value=explainer.expected_value[0],
shap_values=shap_values[row_index,:],
features=X_train.iloc[row_index,:])

[実行結果]

force_plotでのbase_valueは、上図でE[f(X)]=22.745と表示されています。

E[f(X)]を基点として下から上へSHAP値を足し引きして、最終的にf(x)=28.55になることが確認できます。

force_plotwaterfall_plotは、表現方法が異なるだけなので好きな方を利用するようにしましょう。

説明可能なAI⑤(具体的な貢献度を可視化)

各サンプルごとの説明変数について、具体的な貢献度を可視化してみます。

force_plot

force_plot関数は、SHAP値と特徴量の貢献度を視覚化することができます。

[Google Colaboratory]

1
2
3
4
5
shap.initjs()
row_index = X_test.index.get_loc(253)
shap.force_plot(base_value=explainer.expected_value,
shap_values=shap_values[row_index,:],
features=X_test.iloc[row_index,:])

まず、force_plotを使うための前処理メソッド(initjs)を実行します。(1行目)

次に確認したいデータの位置(253行目)を指定します。(2行目)

[実行結果]

上図のbase value(横軸)は、与えられたX_test(テストデータの説明変数)における予測値の平均で、全データ共通の指標です。

それに対し、各説明変数のSHAP値を足し引きした結果、最終的に予測結果がf(x)になるという見方となります。

赤色が価格の上昇に貢献、青色が価格の減少に貢献した説明変数になります。

今回はbase valueが22.75で、各説明変数のSHAP値を足し引きした結果、28.55に予測したことが確認できます。

253行目のデータについては、RMが高くLSTATが低いので、その点では価格の上昇に貢献していますが、PTRATIOが価格の減少に貢献した結果、最終的な予測値が低くなったことが分かります。