Cloud AI Platform にデプロイされた財務 ML モデルを What-if ツールを使用して分析する

1. 概要

このラボでは、What-if ツールを使用して、財務データでトレーニングされ Cloud AI Platform にデプロイされた XGBoost モデルを分析します。

学習内容

次の方法を学習します。

  • AI Platform Notebooks の一般公開住宅ローンデータセットで XGBoost モデルをトレーニングする
  • XGBoost モデルを AI Platform にデプロイする
  • What-If ツールを使用してモデルを分析する

このラボを Google Cloud で実行するための総費用は約 $1 です。

2. XGBoost の概観

XGBoost: ディシジョン ツリー勾配ブーストを使用して予測モデルを構築する ML フレームワーク。ツリー内の異なるリーフノードに関連付けられたスコアに基づいて、複数のディシジョン ツリーをアンサンブルします。

下の図は、天気予報に基づいてスポーツの試合を行うかどうかを評価するシンプルなディシジョン ツリー モデルを可視化したものです。

308a0bfc70733abf.png

このモデルに XGBoost を使用する理由従来のニューラル ネットワークは、画像やテキストなどの非構造化データに対して最高のパフォーマンスを発揮することがわかっていますが、ディシジョン ツリーは多くの場合、この Codelab で使用する住宅ローンのデータセットのような構造化データに対して非常に効果的です。

3. 環境を設定する

この Codelab を実行するには、課金が有効になっている Google Cloud Platform プロジェクトが必要です。プロジェクトを作成するには、こちらの手順に沿って操作してください。

ステップ 1: Cloud AI Platform Models API を有効にする

まだ有効になっていない場合は、Cloud コンソールの [AI Platform モデル] セクションに移動して [有効にする] をクリックします。

d0d38662851c6af3.png

ステップ 2: Compute Engine API を有効にする

まだ有効になっていない場合は、[Compute Engine] に移動して [有効にする] を選択します。これはノートブック インスタンスを作成するために必要です。

ステップ 3: AI Platform Notebooks インスタンスを作成する

Cloud コンソールの [AI Platform Notebooks] セクションに移動し、[新しいインスタンス] をクリックします。次に、最新の TF Enterprise 2.x インスタンス タイプ(GPU なし)を選択します。

7d16190440ab2e9c.png

デフォルトのオプションを使用して、[作成] をクリックします。インスタンスが作成されたら、[JupyterLab を開く] を選択します。

772f8868d3841ba0.png

ステップ 4: XGBoost をインストールする

JupyterLab インスタンスが開いたら、XGBoost パッケージを追加する必要があります。

ランチャーから [ターミナル] を選択します。

28dcf2790ce77c96.png

次のコマンドを実行して、Cloud AI Platform でサポートされている XGBoost の最新バージョンをインストールします。

pip3 install xgboost==0.90

完了したら、ランチャーから Python 3 ノートブック インスタンスを開きます。これで、ノートブックで作業を開始する準備ができました。

ステップ 5: Python パッケージをインポートする

ノートブックの最初のセルに次の import を追加してセルを実行します。実行するには、上部のメニューで右矢印ボタンを押すか、Command+Enter キーを押します。

import pandas as pd
import xgboost as xgb
import numpy as np
import collections
import witwidget

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.utils import shuffle
from witwidget.notebook.visualization import WitWidget, WitConfigBuilder

4. データをダウンロードして処理する

ここでは、ffiec.gov の住宅ローン データセットを使用して、XGBoost モデルをトレーニングします。元のデータセットに対して前処理を行い、モデルのトレーニングに使用する小さなバージョンを作成しました。このモデルは、特定の住宅ローンの申し込みが承認されるかどうかを予測します。

ステップ 1: 前処理されたデータセットをダウンロードする

Google Cloud Storage で、このデータセットのバージョンをご利用いただけるようになりました。Jupyter ノートブックで次の gsutil コマンドを実行してダウンロードできます。

!gsutil cp 'gs://mortgage_dataset_files/mortgage-small.csv' .

ステップ 2: Pandas でデータセットを読み取る

Pandas DataFrame を作成する前に、Pandas がデータセットを正しく読み取れるように、各列のデータ型のディクショナリを作成します。

COLUMN_NAMES = collections.OrderedDict({
 'as_of_year': np.int16,
 'agency_code': 'category',
 'loan_type': 'category',
 'property_type': 'category',
 'loan_purpose': 'category',
 'occupancy': np.int8,
 'loan_amt_thousands': np.float64,
 'preapproval': 'category',
 'county_code': np.float64,
 'applicant_income_thousands': np.float64,
 'purchaser_type': 'category',
 'hoepa_status': 'category',
 'lien_status': 'category',
 'population': np.float64,
 'ffiec_median_fam_income': np.float64,
 'tract_to_msa_income_pct': np.float64,
 'num_owner_occupied_units': np.float64,
 'num_1_to_4_family_units': np.float64,
 'approved': np.int8
})

次に、DataFrame を作成し、上記で指定したデータ型を渡します。元のデータセットが特定の順序に並べ替えられている場合に備えて、データをシャッフルすることが重要です。そのために shuffle という sklearn ユーティリティを使用し、これを最初のセルにインポートしました。

data = pd.read_csv(
 'mortgage-small.csv',
 index_col=False,
 dtype=COLUMN_NAMES
)
data = data.dropna()
data = shuffle(data, random_state=2)
data.head()

data.head() を使用すると、Pandas でデータセットの最初の 5 行をプレビューできます。上記のセルを実行すると、次のように表示されます。

29106b71103235a6.png

これらは、モデルのトレーニングに使用する特徴です。一番下までスクロールすると、最後の列 approved が表示されます。これが予測の対象です。値 1 は特定の申請が承認されたことを示し、0 は拒否されたことを示します。

データセット内の承認済み値 / 拒否値の分布を表示して、ラベルの numpy 配列を作成するには、次のコマンドを実行します。

# Class labels - 0: denied, 1: approved
print(data['approved'].value_counts())

labels = data['approved'].values
data = data.drop(columns=['approved'])

データセットの約 66% に承認済みの申請書が含まれています。

ステップ 3: カテゴリ値用のダミー列を作成する

このデータセットにはカテゴリ値と数値が混在していますが、XGBoost ではすべての特徴が数値であることが必要です。XGBoost モデルでは、ワンホット エンコーディングでカテゴリ値を表現する代わりに、Pandas の get_dummies 関数を利用します。

get_dummies は、取り得る複数の値を含む列を、それぞれ 0 と 1 のみを持つ一連の列に変換します。たとえば「color」という列があり値には「blue」を指定できます。「red」がget_dummies はこれを「color_blue」という 2 つの列に変換しますと「color_red」すべてのブール値の 0 と 1 が返されます。

カテゴリ特徴量のダミー列を作成するには、次のコードを実行します。

dummy_columns = list(data.dtypes[data.dtypes == 'category'].index)
data = pd.get_dummies(data, columns=dummy_columns)

data.head()

今回データをプレビューすると、1 つの特徴(下の図の purchaser_type など)が複数の列に分割されています。

83aacfaad626e538.png

ステップ 4: データをトレーニング セットとテストセットに分割する

ML の重要なコンセプトの一つに、トレーニングとテストの分割があります。データの大部分をモデルのトレーニングに使用し、残りは未知のデータでモデルをテストするために取っておきます。

ノートブックに次のコードを追加し、Scikit Learn 関数 train_test_split を使用してデータを分割します。

x,y = data,labels
x_train,x_test,y_train,y_test = train_test_split(x,y)

これで、モデルを構築してトレーニングする準備が整いました。

5. XGBoost モデルの構築、トレーニング、評価

ステップ 1: XGBoost モデルを定義してトレーニングする

XGBoost でモデルを作成するのは簡単です。モデルの作成には XGBClassifier クラスを使用します。必要なのは、特定の分類タスクに適した objective パラメータを渡すことだけです。ここでは、2 項分類の問題があり、モデルが(0,1)の範囲の単一の値を出力するために reg:logistic を使用します。未承認の場合は 0、承認済みの場合は 1 です。

次のコードは、XGBoost モデルを作成します。

model = xgb.XGBClassifier(
    objective='reg:logistic'
)

1 行のコードでモデルをトレーニングできます。fit() メソッドを呼び出して、トレーニング データとラベルを渡します。

model.fit(x_train, y_train)

ステップ 2: モデルの精度を評価する

これで、トレーニング済みモデルを使用し、predict() 関数でテストデータの予測を生成できます。

次に、Scikit Learn の accuracy_score 関数を使用して、テストデータに対するモデルのパフォーマンスに基づき、モデルの精度を計算します。テストセットの各サンプルに、グラウンド トゥルース値とモデルの予測値を渡します。

y_pred = model.predict(x_test)
acc = accuracy_score(y_test, y_pred.round())
print(acc, '\n')

精度は約 87% になるはずですが、ML には常にランダム性の要素があるため、精度は若干異なります。

ステップ 3: モデルを保存する

モデルをデプロイするには、次のコードを実行してローカル ファイルに保存します。

model.save_model('model.bst')

6. Cloud AI Platform にモデルをデプロイする

モデルをローカルで動作させることができましたが、このノートブックだけでなく、どこからでもモデルに対して予測を実行できれば便利です。このステップでは、クラウドにデプロイします。

ステップ 1: モデル用の Cloud Storage バケットを作成する

まず、この Codelab の残りの部分で使用する環境変数を定義しましょう。Google Cloud プロジェクトの名前、作成する Cloud Storage バケットの名前(グローバルに一意であることが必要)、モデルの最初のバージョンのバージョン名を以下の値に入力します。

# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
VERSION_NAME = 'v1'
MODEL_NAME = 'xgb_mortgage'

これで、XGBoost モデルファイルを保存するストレージ バケットを作成する準備が整いました。デプロイ時に、Cloud AI Platform にこのファイルを指定します。

ノートブック内から次の gsutil コマンドを実行して、バケットを作成します。

!gsutil mb $MODEL_BUCKET

ステップ 2: モデルファイルを Cloud Storage にコピーする

次に、XGBoost の保存済みモデルファイルを Cloud Storage にコピーします。次の gsutil コマンドを実行します。

!gsutil cp ./model.bst $MODEL_BUCKET

Cloud コンソールの Storage ブラウザに移動して、ファイルがコピーされたことを確認します。

31e2567fa0117214.png

ステップ 3: モデルを作成してデプロイする

モデルをデプロイする準備がほぼ整いました。次の ai-platform gcloud コマンドを実行すると、プロジェクトに新しいモデルが作成されます。これを xgb_mortgage とします。

!gcloud ai-platform models create $MODEL_NAME --region='global'

次に、モデルをデプロイします。そのためには、次の gcloud コマンドを使用します。

!gcloud ai-platform versions create $VERSION_NAME \
--model=$MODEL_NAME \
--framework='XGBOOST' \
--runtime-version=2.1 \
--origin=$MODEL_BUCKET \
--python-version=3.7 \
--project=$GCP_PROJECT \
--region='global'

その間に、AI Platform コンソールの [モデル] セクションを確認します。新しいバージョンがデプロイされていることを確認します。

342875ba92becad1.png

デプロイが正常に完了すると、読み込み中アイコンがある場所に緑色のチェックマークが表示されます。デプロイには 2 ~ 3 分かかります。

ステップ 4: デプロイしたモデルをテストする

デプロイしたモデルが機能していることを確認するには、gcloud を使用してテストし、予測を行います。まず、テストセットの最初の例を使用して JSON ファイルを保存します。

%%writefile predictions.json
[2016.0, 1.0, 346.0, 27.0, 211.0, 4530.0, 86700.0, 132.13, 1289.0, 1408.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0]

次のコードを実行してモデルをテストします。

prediction = !gcloud ai-platform predict --model=xgb_mortgage --region='global' --json-instances=predictions.json --version=$VERSION_NAME --verbosity=none

print(prediction)

モデルの予測が出力に表示されます。このサンプルは承認されたため、1 に近い値が表示されるはずです。

7. What-if ツールを使用してモデルを解釈する

ステップ 1: What-if ツールの可視化を作成する

What-if ツールを AI Platform モデルに接続するには、テストサンプルのサブセットを、それらのサンプルの正解値とともに渡す必要があります。500 個のテストサンプルとその正解ラベルからなる Numpy 配列を作成しましょう。

num_wit_examples = 500
test_examples = np.hstack((x_test[:num_wit_examples].values,y_test[:num_wit_examples].reshape(-1,1)))

What-if ツールは、WitConfigBuilder オブジェクトを作成して分析対象の AI Platform モデルに渡すだけで簡単にインスタンス化できます。

What-if ツールはモデル内の各クラス(この場合は 2)のスコアのリストを想定しているため、ここではオプションの adjust_prediction パラメータを使用します。このモデルは 0 ~ 1 の単一の値のみを返すため、この関数で正しい形式に変換します。

def adjust_prediction(pred):
  return [1 - pred, pred]

config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
  .set_ai_platform_model(GCP_PROJECT, MODEL_NAME, VERSION_NAME, adjust_prediction=adjust_prediction)
  .set_target_feature('mortgage_status')
  .set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)

ビジュアリゼーションの読み込みに 1 分ほどかかることに注意してください。読み込まれたら、次のように表示されます。

4c0b00e6afcdbe01.png

Y 軸はモデルの予測を示しています。1 は信頼度の高い approved 予測、0 は信頼度の高い denied 予測です。X 軸は、読み込まれたすべてのデータポイントの広がりを示すものです。

ステップ 2: 個々のデータポイントを調べる

What-if ツールのデフォルト ビューは、[データポイント エディタ] タブです。ここでは、個々のデータポイントをクリックすると、その特徴の表示、特徴値の変更、その変更が個々のデータポイントでのモデルの予測にどのように影響するかを確認できます。

以下の例では、しきい値 0.5 に近いデータポイントを選択しています。この特定のデータポイントに関連する住宅ローンの申し込みは、CFPB から行われています。その特徴を 0 に変更し、agency_code_Department of Housing and Urban Development (HUD) の値を 1 に変更して、このローンが HUD から発生した場合にモデルの予測がどのようになるかを確認しました。

717620d6a1330479.png

What-if ツールの左下にあるように、この機能を変更すると、モデルの approved 予測が 32% 大幅に減少しました。これは、ローンの元となった代理店がモデルの出力に強い影響を及ぼしていることを示しています。ただし、これを確認するにはさらなる分析が必要です。

UI の左下では、各データポイントのグラウンド トゥルース値を表示して、モデルの予測と比較することもできます。

60ff20ae80ed5e27.png

ステップ 3: 反事実分析

次に、任意のデータポイントをクリックして、[最も近い反事実的データポイントを表示] スライダーを右に移動します。

ae64fd7abefe5449.png

これを選択すると、選択した元の特徴値と最も類似した特徴値を持つデータポイントが表示されますが、予測は逆になります。その後、特徴値をスクロールして、2 つのデータポイントの違い(違いは緑色と太字で強調表示)を確認できます。

ステップ 4: Partial Dependence Plot を確認する

各特徴量がモデルの予測全体にどう影響するかを確認するには、[Partial Dependence Plots] ボックスをオンにして、[Global Partial Dependence plots] を選択します。

72117b5ceb683841.png

このグラフから、HUD からのローンは拒否される可能性が若干高いことがわかります。交通機関コードはブール型の特徴量であり、値は 0 または 1 のみであるため、グラフはこの形状になっています。

applicant_income_thousands は数値特徴量であり、Partial Dependence Plot では、所得が高いほど申請が承認される可能性がわずかに高まりますが、最大で 20 万ドル程度であることがわかります。$200, 000 以降、この機能はモデルの予測に影響しません。

ステップ 5: 全体的なパフォーマンスと公平性を調べる

次に [パフォーマンスと公平性タブ。ここには、混同行列、PR 曲線、ROC 曲線など、提供されたデータセットでのモデルの結果に関する全体的なパフォーマンス統計が表示されます。

混同行列を表示するには、正解特徴として mortgage_status を選択します。

fe1384ee47699498.png

この混同行列は、モデルの正しい予測と誤った予測を合計に対する割合で示します。実際のはい / 予測されたはい実際のいいえ / 予測されたいいえの正方形を合計すると、モデルと同じ精度(約 87%)になります。

また、しきい値スライダーを試し、ローンの予測 approved を決定する前にモデルが返す必要がある陽性分類スコアを増減して、精度、偽陽性、偽陰性がどのように変化するかを確認することもできます。この場合、しきい値 .55 付近で精度が最も高くなります。

次に、左側の [スライス条件] プルダウンで loan_purpose_Home_purchase を選択します。

f3f1858d627d57ab.png

これで、2 つのデータ サブセット「0」のパフォーマンスが表示されます。スライスは、ローンが住宅購入ではない場合に示され、「1」はスライスは、ローンが住宅購入の場合に使用されます。2 つのスライスの精度、偽陽性、偽陰性率を確認し、パフォーマンスの違いを探します。

行を開いて混同行列を確認すると、モデルが「承認済み」と予測したことがわかります。住宅購入のためのローン申請の約 70%、住宅購入以外のローンの 46% のみ(正確な割合はモデルによって異なります):

318a8d5a8ffc6bea.png

左側のラジオボタンから [ユーザー属性の同等性] を選択すると、モデルが両方のスライスの同程度の応募者に対して approved と予測するように 2 つのしきい値が調整されます。各スライスの精度、偽陽性、偽陰性にはどう影響するでしょうか。

ステップ 6: 特徴分布を調べる

最後に、What-if ツールの [Features] タブに移動します。これにより、データセット内の各特徴の値の分布が表示されます。

48ab3c4879793324.png

このタブを使用すると、データセットのバランスがとれていることを確認できます。たとえば、データセット内のローンは農業サービス庁から発行されたものはほとんどないように見えるでしょう。モデルの精度を向上させるため、データが利用可能であれば、その機関からのローンを追加することを検討できます。

ここでは、What-If ツールの調査に関するアイデアのいくつかを説明しました。このツールは他にもたくさんありますので、いろいろと自由に使ってみてください。

8. クリーンアップ

このノートブックを引き続き使用する場合は、未使用時にオフにすることをおすすめします。Cloud コンソールの Notebooks UI で、ノートブックを選択して [停止] を選択します。

879147427150b6c7.png

このラボで作成したすべてのリソースを削除する場合は、ノートブック インスタンスを停止するのではなく削除します。

Cloud コンソールのナビゲーション メニューで [ストレージ] に移動し、モデルアセットを保存するために作成した両方のバケットを削除します。