使用 What-If Tool 和 Vertex AI 建構金融機器學習模型

1. 總覽

在本研究室中,您將使用 What-if Tool 分析以財務資料訓練的 XGBoost 模型。分析模型後,請將模型部署至 Cloud 新推出的 Vertex AI。

課程內容

您將學習下列內容:

  • 在託管筆記本中的公開貸款資料集,訓練 XGBoost 模型
  • 使用 What-if Tool 分析模型
  • 將 XGBoost 模型部署至 Vertex AI

在 Google Cloud 中執行這個研究室的總費用約為 $1 美元。

2. Vertex AI 簡介

這個研究室使用 Google Cloud 最新的 AI 產品服務。Vertex AI 將 Google Cloud 中的機器學習產品整合到流暢的開發體驗中。先前使用 AutoML 訓練的模型和自訂模型,都能透過不同的服務存取。這項新產品會與其他新產品一起合併為一個 API。您也可以將現有專案遷移至 Vertex AI。如有任何意見,請參閱支援頁面

Vertex AI 提供許多不同的產品,可支援端對端機器學習工作流程。本研究室將著重介紹下列產品:預測與筆記本。

Vertex 產品總覽

3. 快速 XGBoost 入門

XGBoost 是機器學習架構,會使用決策樹狀圖梯度提升來建構預測模型。其運作方式是依據與樹狀結構中不同分葉節點相關聯的分數,將多個決策樹聚在一起。

下圖是簡易決策樹狀圖模型的視覺化流程,可根據天氣預報評估運動賽事是否應進行:

樹狀模型範例

為什麼這個模型採用 XGBoost?根據研究顯示,在圖片和文字等非結構化資料中,傳統類神經網路的執行效果最佳,但決策樹通常在本程式碼研究室會使用的貸款資料集等結構化資料上提供極佳的效率。

4. 設定環境

您需要已啟用計費功能的 Google Cloud Platform 專案,才能執行這個程式碼研究室。如要建立專案,請按照這裡的操作說明進行。

步驟 1:啟用 Compute Engine API

前往「Compute Engine」,並選取「啟用」 (如果尚未啟用)。建立筆記本執行個體時會用到。

步驟 2:啟用 Vertex AI API

前往 Cloud 控制台的 Vertex 專區,然後按一下「啟用 Vertex AI API」

Vertex 資訊主頁

步驟 3:建立 Notebooks 執行個體

在 Cloud 控制台的 Vertex 專區中,按一下「Notebooks」(筆記本):

選取筆記本

接著選取「New Instance」。接著選取「TensorFlow 企業版 2.3」執行個體類型,但「不含 GPU」

TFE 執行個體

使用預設選項,然後點選「建立」。執行個體建立完成後,請選取「Open JupyterLab」

步驟 4:安裝 XGBoost

開啟 JupyterLab 執行個體後,您需要新增 XGBoost 套件。

方法是在啟動器中選取「Terminal」:

接著執行下列指令,安裝 Vertex AI 支援的最新版 XGBoost:

pip3 install xgboost==1.2

完成後,從啟動器開啟 Python 3 筆記本執行個體。現在可以開始使用筆記本了!

步驟 5:匯入 Python 套件

在筆記本的第一個儲存格中新增下列匯入項目,然後執行儲存格。按下頂端選單中的向右箭頭按鈕,或按下 Command 鍵,即可開啟模式:

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

5. 下載及處理資料

我們會使用 ffiec.gov 的貸款資料集訓練 XGBoost 模型。我們已對原始資料集進行一些預先處理作業,並建立了較小的版本供您用來訓練模型。模型會預測特定抵押貸款申請是否獲得核准

步驟 1:下載預先處理的資料集

我們已在 Google Cloud Storage 中為您提供一個版本的資料集。如要下載該筆記本,請在 Jupyter 筆記本中執行下列 gsutil 指令:

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

步驟 2:使用 Pandas 讀取資料集

在建立 Pandas DataFrame 之前,我們會為每個資料欄的資料類型建立 dict,讓 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,並傳遞我們先前指定的資料類型。為因應原始資料集以特定方式排序,請務必重組我們的資料。我們使用名為 shufflesklearn 公用程式進行這項作業,並在第一個儲存格中匯入:

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 資料集的前五個資料列。執行上述儲存格後,畫面應如下所示:

貸款資料集預覽

以下是我們將用來訓練模型的特徵。如果您捲動至末端,就會看到最後一欄 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 函式,而非使用 one-hot 編碼表示類別值。

get_dummies 會使用包含多個可能值的資料欄,並將其轉換為一系列只包含 0 和 1 的資料欄。舉例來說,如果其中包含「color」欄可能的值為「blue」以及「紅色」get_dummies 會轉換為 2 個名為「color_blue」的資料欄和「color_red」全都是布林值 0 和 1。

如要為類別特徵建立虛擬欄,請執行下列指令:

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

data.head()

這次預覽資料時,您會發現單一地圖項目 (例如下圖中的 purchaser_type) 分割成多個資料欄:

貓熊虛擬柱

步驟 4:將資料拆分為訓練集和測試集

機器學習的一個重要概念是訓練 / 測試分割。我們會使用大部分的資料來訓練模型,其餘則將其餘部分用在前所未見的資料上來測試模型。

將下列程式碼新增至筆記本,該筆記本使用 Scikit-learn 函式 train_test_split 來分割資料:

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

現在您可以開始建構並訓練模型了!

6. 建構、訓練及評估 XGBoost 模型

步驟 1:定義及訓練 XGBoost 模型

在 XGBoost 中建立模型十分簡單。我們會使用 XGBClassifier 類別建立模型,而且只需要針對特定分類工作傳遞正確的 objective 參數。在本例中,我們使用 reg:logistic 因為發生二元分類問題,而希望模型輸出單一值 (0,1):0 表示未獲核准,1 則代表已核准。

下列程式碼會建立 XGBoost 模型:

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

您可以使用一行程式碼來訓練模型,呼叫 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% 的準確率,但您的準確度可能會略有不同,因為機器學習本來往往會具有隨機性。

步驟 3:儲存模型

如要部署模型,請執行下列指令,將模型儲存至本機檔案:

model.save_model('model.bst')

7. 使用 What-if 工具解讀模型

步驟 1:建立 What-if 工具視覺化內容

如要將 What-if Tool 連結至您的本機模型,您必須將該模型的某些測試範例,以及這些範例的真值值傳送給該模型。讓我們建立包含 500 個測試範例的 Numpy 陣列,以及這些範例的真值標籤:

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

只要將 What-if Tool 化,就和建立 WitConfigBuilder 物件,並將要分析的模型傳遞給這個物件一樣簡單。

由於 What-if Tool 預期模型中每個類別的分數清單 (本例中為 2),因此我們將搭配 What-If Tool 使用 XGBoost 的 predict_proba 方法:

config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
  .set_custom_predict_fn(model.predict_proba)
  .set_target_feature('mortgage_status')
  .set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)

請注意,載入圖表需要一點時間。載入後,您應該會看到以下內容:

What-If Tool 初始檢視

Y 軸代表模型的預測結果,1approved 預測結果的可信度高,0 是高可信度的denied預測。X 軸只是所有載入資料點的延伸,

步驟 2:探索個別資料點

What-if Tool 的預設檢視畫面是「Datapoint 編輯器」分頁。您可以在這裡點選任一資料點,查看該資料點的特徵、變更特徵值,以及查看變更如何影響模型對個別資料點的預測結果。

在以下範例中,我們選擇的資料點接近 0.5 這個門檻。與這個特定資料點相關聯的抵押貸款應用程式,來自 CFPB。我們已將特徵值變更為 0,並將 agency_code_Department of Housing and Urban Development (HUD) 的值變更為 1,以瞭解如果這筆貸款並非源自 HUD,模型的預測作業會受到什麼影響:

如 What-if Tool 的左下方部分所見,變更這項功能後,模型的approved預測結果大幅減少了 32%。這可能代表出借代理商的貸款已對模型的輸出結果有重大影響,但我們還需要進行更多分析才能確定。

在 UI 的左下方,我們還可以查看每個資料點的真值值,並與模型的預測結果進行比較:

步驟 3:反事實分析

接下來,請點選任一資料點,然後向右移動「顯示最接近反對資料集的資料點」滑桿:

選取這個選項後,系統就會顯示最相似特徵值 (與您選取的原始特徵值) 的資料點,以及相反的預測。接著您可以捲動特徵值,查看兩個資料點的差異 (差異會以綠色和粗體標示)。

步驟 4:查看部分相依圖

如要瞭解各項特徵對模型整體預測結果的影響,請勾選「部分相依圖」方塊,並確認您已選取「全域部分相依圖」

由此可見,從 HUD 取得的貸款更有可能遭拒。這個圖形就是這個形狀,因為代理商代碼是布林值特徵,因此值只能是 0 或 1。

applicant_income_thousands 是數值特徵,在部分相依圖中,我們可以發現,收入越高的申請機率就越高,但最多只有 $20 萬美元。$20 萬美元後,這項功能不會影響模型的預測結果。

步驟 5:瞭解整體成效和公平性

接著,前往「成效與」公平性分頁。這會針對提供的資料集,顯示模型結果的整體效能統計資料,包括混淆矩陣、PR 曲線和 ROC 曲線。

選取 mortgage_status 做為真值特徵,即可查看混淆矩陣:

這個混淆矩陣會將模型正確及錯誤的預測資料,以資料總計百分比的形式呈現。如果您將「實際是 / 預測是」和「實際否 / 預測為」平方數加總,產生的準確率應該要和模型相同 (本例中為 87%,不過訓練機器學習模型中存在隨機程度的元素,因此可能略有差異)。

您還可以使用門檻滑桿進行實驗,提高及降低模型在決定貸款預測的 approved 之前必須傳回的正分類分數,然後看看會如何改變準確率、偽陽性和偽陰性。在本例中,準確率為 .55 的門檻最高。

接著,在左側「Slice by」(區隔依據) 下拉式選單中,選取 loan_purpose_Home_purchase

您會看到兩部分資料的成效:「0」其中顯示貸款並非房屋貸款時,「1」片段適用於貸款房屋。檢查兩個切片之間的準確率、偽陽性和偽陰性率,找出效能差異。

如果展開列來查看混淆矩陣,就會看到模型預測「已核准」大約 70% 的購屋貸款申請,少了 46% 不用於房屋買賣的貸款 (具體百分比因您的型號而異):

如果您從左側的圓形按鈕選取客層一致,系統就會調整兩個門檻值,讓模型預測approved以同等百分比的兩個配量之申請者百分比。我們該如何改進每個片段的準確率、偽陽性和偽陰性結果?

步驟 6:瞭解功能發布情形

最後,前往 What-if Tool 中的「Features」分頁。這會顯示資料集中每個特徵的值分佈情形:

您可以透過這個分頁確保資料集是平衡的。例如,在資料集裡,看起來是很少來自農場服務局的貸款。為提升模型準確度,我們可能會考慮增加該運輸公司的貸款 (如有)。

我們在此說明瞭幾個「假設工具」探索提案。歡迎繼續試用這項工具,還有許多值得探索的地方!

8. 將模型部署至 Vertex AI

我們的模型在本機運作,但如果能隨處 (而不只是這個筆記本) 進行預測,就會很棒。在這個步驟中,我們會將其部署至雲端。

步驟 1:為模型建立 Cloud Storage 值區

首先,定義一些在程式碼研究室的其他部分會用到的環境變數。請在下列值中填入您的 Google Cloud 專案名稱、您要建立的 Cloud Storage 值區名稱 (必須是全域不重複的名稱),以及模型第一個版本的版本名稱:

# Update the variables below to your own Google Cloud project ID and GCS bucket name. You can leave the model name we've specified below:
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
MODEL_NAME = 'xgb_mortgage'

現在,我們已準備好建立 Storage 值區,用來儲存 XGBoost 模型檔案。部署之後,我們會將 Vertex AI 指向這個檔案。

在筆記本中執行這個 gsutil 指令,藉此建立區域性儲存空間值區:

!gsutil mb -l us-central1 $MODEL_BUCKET

步驟 2:將模型檔案複製到 Cloud Storage

接著,我們會將 XGBoost 儲存的模型檔案複製到 Cloud Storage。執行下列 gsutil 指令:

!gsutil cp ./model.bst $MODEL_BUCKET

請前往 Cloud 控制台中的儲存空間瀏覽器,確認檔案已複製完成:

步驟 3:建立模型並部署至端點

我們快要可以將模型部署至雲端了!在 Vertex AI 中,模型可包含多個端點。首先來建立模型,然後在模型內建立端點並加以部署

首先,使用 gcloud CLI 建立模型:

!gcloud beta ai models upload \
--display-name=$MODEL_NAME \
--artifact-uri=$MODEL_BUCKET \
--container-image-uri=us-docker.pkg.dev/cloud-aiplatform/prediction/xgboost-cpu.1-2:latest \
--region=us-central1

artifact-uri 參數會指向您儲存 XGBoost 模型的儲存位置。container-image-uri 參數可告知 Vertex AI 要使用哪個預先建構的容器來提供服務。指令完成後,請前往 Vertex 控制台的「模型」區段取得新模型的 ID。步驟如下:

從控制台取得模型 ID

複製該 ID 並儲存至變數:

MODEL_ID = "your_model_id"

接下來,我們要在這個模型中建立端點。只要使用以下 gcloud 指令即可:

!gcloud beta ai endpoints create \
--display-name=xgb_mortgage_v1 \
--region=us-central1

完成後,筆記本輸出內容中就會顯示端點的登入位置。找出指出端點已建立路徑,其路徑如下所示:projects/project_ID/locations/us-central1/endpoints/endpoint_ID.,然後將下方的值替換成先前建立的端點 ID:

ENDPOINT_ID = "your_endpoint_id"

如要部署端點,請執行下列指令:

!gcloud beta ai endpoints deploy-model $ENDPOINT_ID \
--region=us-central1 \
--model=$MODEL_ID \
--display-name=xgb_mortgage_v1 \
--machine-type=n1-standard-2 \
--traffic-split=0=100

端點部署作業大約會在 5 到 10 分鐘內完成。在端點部署期間,請前往控制台的「模型」部分。按一下您的模型,您應該會看到最終部署:

成功完成部署後,載入旋轉圖示的位置會顯示綠色勾號。

步驟 4:測試已部署的模型

如要確認您部署的模型是否正常運作,請透過 gcloud 進行測試,確認已部署的模型可正常運作。首先,使用測試集的範例儲存 JSON 檔案:

%%writefile predictions.json
{
  "instances": [
    [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]
  ]
}

請執行以下 gcloud 指令測試模型:

!gcloud beta ai endpoints predict $ENDPOINT_ID \
--json-request=predictions.json \
--region=us-central1

輸出內容中應會顯示模型的預測結果。這個特定範例已獲核准,因此值應該接近 1。

9. 清除

如要繼續使用這個筆記本,建議您在未使用時將其關閉。在 Cloud 控制台的「Notebooks」(筆記本) UI 中,依序選取筆記本和「Stop」(停止)

如要刪除在本研究室中建立的所有資源,只要刪除筆記本執行個體即可,不必停止執行個體。

如要刪除您部署的端點,請前往 Vertex 控制台的「端點」部分,然後按一下「刪除」圖示:

如要刪除 Storage 值區,請使用 Cloud 控制台中的導覽選單前往「Storage」(儲存空間)、選取值區,然後點選「Delete」(刪除):