Creazione di un modello di ML finanziario con lo strumento What-If e Vertex AI

1. Panoramica

In questo lab utilizzerai lo strumento What-if per analizzare un modello XGBoost addestrato su dati finanziari. Dopo aver analizzato il modello, ne eseguirai il deployment nel nuovo Vertex AI di Cloud.

Cosa imparerai

Imparerai a:

  • Addestra un modello XGBoost su un set di dati di mutui pubblici in un blocco note ospitato
  • Analizza il modello con lo strumento What-if
  • esegui il deployment del modello XGBoost su Vertex AI

Il costo totale per l'esecuzione di questo lab su Google Cloud è di circa $1.

2. Introduzione a Vertex AI

Questo lab utilizza la più recente offerta di prodotti AI disponibile su Google Cloud. Vertex AI integra le offerte ML di Google Cloud in un'esperienza di sviluppo fluida. In precedenza, i modelli addestrati con AutoML e i modelli personalizzati erano accessibili tramite servizi separati. La nuova offerta combina entrambi in un'unica API, insieme ad altri nuovi prodotti. Puoi anche migrare progetti esistenti su Vertex AI. In caso di feedback, consulta la pagina di supporto.

Vertex AI include molti prodotti diversi per supportare i flussi di lavoro ML end-to-end. Questo lab è incentrato sui prodotti evidenziati di seguito: Prediction e Notebooks.

Panoramica del prodotto Vertex

3. Una breve introduzione a XGBoost

XGBoost è un framework di machine learning che utilizza alberi decisionali e incremento del gradiente per creare modelli predittivi. Funziona raggruppando più alberi decisionali in base al punteggio associato ai diversi nodi foglia in un albero.

Il diagramma seguente è una visualizzazione di un semplice modello ad albero decisionale che valuta se una partita di sport deve essere svolta in base alle previsioni meteo:

Esempio di modello ad albero

Perché utilizziamo XGBoost per questo modello? Sebbene le reti neurali tradizionali abbiano un rendimento migliore su dati non strutturati come immagini e testi, gli alberi decisionali spesso hanno un ottimo rendimento con i dati strutturati, come il set di dati dei mutui che utilizzeremo in questo codelab.

4. Configura l'ambiente

Per eseguire questo codelab, è necessario un progetto Google Cloud con fatturazione abilitata. Per creare un progetto, segui le istruzioni riportate qui.

Passaggio 1: abilita l'API Compute Engine

Passa a Compute Engine e seleziona Abilita se non è già abilitato. Ne avrai bisogno per creare la tua istanza di blocco note.

Passaggio 2: abilita l'API Vertex AI

Vai alla sezione Vertex AI della tua console Cloud e fai clic su Abilita API Vertex AI.

Dashboard Vertex

Passaggio 3: crea un'istanza di Notebooks

Dalla sezione Vertex della console Cloud, fai clic su Notebooks:

Seleziona blocchi note

Da qui, seleziona Nuova istanza. Quindi seleziona il tipo di istanza TensorFlow Enterprise 2.3 senza GPU:

Istanza TFE

Utilizza le opzioni predefinite e fai clic su Crea. Una volta creata l'istanza, seleziona Apri JupyterLab.

Passaggio 4: installa XGBoost

Una volta aperta l'istanza JupyterLab, dovrai aggiungere il pacchetto XGBoost.

Per farlo, seleziona Terminale da Avvio app:

Poi esegui questo comando per installare l'ultima versione di XGBoost supportata da Vertex AI:

pip3 install xgboost==1.2

Al termine, apri un'istanza di blocco note Python 3 dall'Avvio app. Puoi iniziare a usare il tuo blocco note.

Passaggio 5: importa i pacchetti Python

Nella prima cella del blocco note, aggiungi le seguenti importazioni ed esegui la cella. Per eseguirlo, premi il pulsante Freccia destra nel menu in alto o premi Invio:

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. Scaricare ed elaborare i dati

Utilizzeremo un set di dati sui mutui di ffiec.gov per addestrare un modello XGBoost. Abbiamo eseguito una certa pre-elaborazione sul set di dati originale e creato una versione più piccola che puoi utilizzare per addestrare il modello. Il modello prevede se una determinata richiesta di mutuo sarà approvata o meno.

Passaggio 1: scarica il set di dati pre-elaborato

Abbiamo reso disponibile per te una versione del set di dati in Google Cloud Storage. Puoi scaricarlo eseguendo questo comando gsutil nel tuo blocco note Jupyter:

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

Passaggio 2: leggi il set di dati con Pandas

Prima di creare il nostro DataFrame Pandas, creeremo un dict del tipo di dati di ogni colonna in modo che Pandas legga correttamente il set di dati:

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
})

Quindi creeremo un DataFrame, passando i tipi di dati che abbiamo specificato sopra. È importante eseguire lo shuffling dei dati nel caso in cui il set di dati originale sia ordinato in un modo specifico. A questo scopo utilizziamo un'utilità sklearn denominata shuffle, che abbiamo importato nella prima cella:

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() ci consente di visualizzare l'anteprima delle prime 5 righe del nostro set di dati in Pandas. Dopo aver eseguito la cella sopra, dovresti vedere una schermata simile a questa:

Anteprima del set di dati dei mutui

Queste sono le caratteristiche che utilizzeremo per addestrare il modello. Se scorri fino alla fine, vedrai l'ultima colonna approved, che è ciò che stiamo prevedendo. Il valore 1 indica che una determinata richiesta è stata approvata, mentre 0 indica che è stata rifiutata.

Per vedere la distribuzione dei valori approvati / negati nel set di dati e creare un array numpy delle etichette, esegui questo comando:

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

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

Circa il 66% del set di dati contiene applicazioni approvate.

Passaggio 3: crea una colonna fittizia per i valori categorici

Questo set di dati contiene una combinazione di valori categorici e numerici, ma XGBoost richiede che tutte le caratteristiche siano numeriche. Anziché rappresentare i valori categorici utilizzando la codifica one-hot, per il nostro modello XGBoost utilizziamo la funzione get_dummies di Pandas.

get_dummies prende una colonna con più valori possibili e la converte in una serie di colonne, ciascuna con solo 0 e 1. Ad esempio, se avevamo una colonna "colore" con possibili valori di "blu" e "rosso", get_dummies lo trasformerebbe in due colonne chiamate "color_blue" e "color_red" con tutti i valori booleani 0 e 1.

Per creare colonne fittizie per le caratteristiche categoriche, esegui questo codice:

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

data.head()

Questa volta, quando visualizzi l'anteprima dei dati, vedrai le singole funzionalità (come purchaser_type nella foto sotto) suddivise in più colonne:

Colonne fittizie di panda

Passaggio 4: suddivisione dei dati in set di addestramento e test

Un concetto importante nel machine learning è la suddivisione tra addestramento e test. Prenderemo la maggior parte dei nostri dati e li utilizzeremo per addestrare il modello, e metteremo da parte il resto per testare il modello su dati mai visti prima.

Aggiungi il seguente codice al tuo blocco note, che utilizza la funzione Scikit-learn train_test_split per suddividere i nostri dati:

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

Ora è tutto pronto per creare e addestrare il modello.

6. Creare, addestrare e valutare un modello XGBoost

Passaggio 1: definisci e addestra il modello XGBoost

Creare un modello in XGBoost è semplice. Utilizzeremo la classe XGBClassifier per creare il modello e dobbiamo solo passare il parametro objective corretto per la nostra attività di classificazione specifica. In questo caso utilizziamo reg:logistic perché abbiamo un problema di classificazione binaria e vogliamo che il modello restituisca un singolo valore nell'intervallo (0,1): 0 per non approvato e 1 per approvato.

Il codice seguente creerà un modello XGBoost:

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

Puoi addestrare il modello con una sola riga di codice, chiamando il metodo fit() e passandogli i dati e le etichette di addestramento.

model.fit(x_train, y_train)

Passaggio 2: valuta l'accuratezza del modello

Ora possiamo utilizzare il nostro modello addestrato per generare previsioni sui dati di test con la funzione predict().

Useremo quindi la funzione accuracy_score() di Scikit-learn per calcolare l'accuratezza del nostro modello in base alle sue prestazioni sui dati di test. Inoltre, passiamo i valori dei dati empirici reali insieme ai valori previsti dal modello per ogni esempio del set di test:

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

Dovresti vedere una precisione di circa l'87%, ma la tua sarà leggermente diversa, dato che c'è sempre un elemento di casualità nel machine learning.

Passaggio 3: salva il modello

Per eseguire il deployment del modello, esegui questo codice per salvarlo in un file locale:

model.save_model('model.bst')

7. Usa lo strumento What-If per interpretare il tuo modello

Passaggio 1: crea la visualizzazione dello strumento What-if

Per collegare lo strumento What-if al tuo modello locale, devi passarlo un sottoinsieme degli esempi di test insieme ai valori empirici reali per questi esempi. Creiamo un array Numpy di 500 dei nostri esempi di test insieme alle relative etichette basate su dati empirici reali:

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

Per creare un'istanza per lo strumento What-if è sufficiente creare un oggetto WitConfigBuilder e trasmettergli il modello da analizzare.

Poiché lo strumento What-If prevede un elenco di punteggi per ogni classe nel nostro modello (in questo caso 2), useremo il metodo predict_proba di XGBoost con lo strumento What-If:

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)

Tieni presente che il caricamento della visualizzazione richiederà un minuto. Al termine del caricamento, dovresti vedere quanto segue:

Vista iniziale dello strumento What-If

L'asse y mostra la previsione del modello. 1 è una previsione approved ad alta affidabilità e 0 è una previsione denied ad alta affidabilità. L'asse x è semplicemente la diffusione di tutti i punti di dati caricati.

Passaggio 2: esplora i singoli punti dati

La visualizzazione predefinita dello strumento What-if è la scheda Editor datapoint. Qui puoi fare clic su un singolo punto dati per visualizzarne le caratteristiche, modificarne i valori e vedere come il cambiamento influisce sulla previsione del modello su un singolo punto dati.

Nell'esempio riportato di seguito, abbiamo scelto un punto dati vicino alla soglia di 0,5. La richiesta di mutuo associata a questo particolare punto dati ha avuto origine dal CFPB. Abbiamo modificato questa caratteristica in 0 e anche il valore di agency_code_Department of Housing and Urban Development (HUD) è stato modificato in 1 per vedere cosa succederebbe alla previsione del modello se il prestito proveniva invece da HUD:

Come possiamo vedere nella sezione in basso a sinistra dello strumento What-if, la modifica di questa funzionalità ha ridotto in modo significativo la previsione approved del modello del 32%. Questo potrebbe indicare che l'agenzia da cui ha avuto origine un prestito ha un forte impatto sull'output del modello, ma sarà necessario effettuare ulteriori analisi per averne la certezza.

Nella parte in basso a sinistra dell'interfaccia utente, possiamo anche vedere il valore basato su dati empirici reali per ciascun punto dati e confrontarlo con la previsione del modello:

Passaggio 3: analisi controfattuale

Successivamente, fai clic su un punto dati qualsiasi e sposta verso destra il cursore Mostra punto dati controfattuale più vicino:

Se selezioni questa opzione, verrà mostrato il punto dati con i valori delle caratteristiche più simili a quello originale selezionato, ma la previsione opposta. Puoi quindi scorrere i valori delle caratteristiche per vedere le differenze tra i due punti dati (le differenze sono evidenziate in verde e in grassetto).

Passaggio 4: osserva i grafici di dipendenza parziale

Per vedere in che modo ciascuna caratteristica influisce sulle previsioni del modello nel complesso, seleziona la casella Grafici di dipendenza parziale e assicurati che sia selezionato Grafici di dipendenza parziale globali:

Qui possiamo vedere che i prestiti provenienti da HUD hanno una probabilità leggermente superiore di essere rifiutati. Il grafico ha questa forma perché il codice agenzia è una caratteristica booleana, per cui i valori possono essere esattamente 0 o 1.

applicant_income_thousands è una caratteristica numerica e, nel grafico di dipendenza parziale, possiamo notare che un reddito più elevato aumenta leggermente la probabilità che una richiesta venga approvata, ma solo fino a circa 200.000 $. Dopo 200.000 $, questa caratteristica non influisce sulla previsione del modello.

Passaggio 5: esamina il rendimento e l'equità complessivi

Quindi, vai alla scheda Performance & Equità. Mostra le statistiche generali sulle prestazioni dei risultati del modello sul set di dati fornito, comprese le matrici di confusione, le curve PR e le curve ROC.

Seleziona mortgage_status come funzionalità di dati empirici reali per visualizzare una matrice di confusione:

Questa matrice di confusione mostra le previsioni corrette e non corrette del modello come percentuale del totale. Se sommi i quadrati Sì/Sì previsto e No/No/No previsto effettivo, la somma dovrebbe avere la stessa accuratezza del modello (in questo caso circa l'87%, anche se il modello potrebbe variare leggermente perché c'è un elemento di casualità nell'addestramento dei modelli ML).

Puoi anche fare esperimenti con il dispositivo di scorrimento della soglia, alzando e abbassando il punteggio di classificazione positivo che il modello deve restituire prima che decida di prevedere approved per il prestito e vedere come cambia l'accuratezza, i falsi positivi e i falsi negativi. In questo caso, l'accuratezza è massima intorno a una soglia di 0,55.

Quindi, nel menu a discesa Sezione per, seleziona loan_purpose_Home_purchase:

Verrà visualizzato il rendimento per i due sottoinsiemi di dati: lo "0" sezione mostra quando il prestito non riguarda l'acquisto di una casa e "1" sezione riguarda quando il prestito riguarda l'acquisto di una casa. Controlla l'accuratezza, i falsi positivi e il tasso di falsi negativi tra le due sezioni per cercare le differenze nelle prestazioni.

Se espandi le righe per esaminare le matrici di confusione, puoi vedere che il modello prevede "approvato" per circa il 70% delle richieste di prestito per l'acquisto di una casa e solo il 46% dei prestiti non destinati all'acquisto di una casa (le percentuali esatte variano a seconda del modello):

Se selezioni Parità demografica dai pulsanti di opzione a sinistra, le due soglie verranno regolate in modo che il modello preveda approved per una percentuale simile di candidati in entrambe le sezioni. Cosa ne influenza l'accuratezza, i falsi positivi e i falsi negativi per ogni sezione?

Passaggio 6: esplora la distribuzione delle funzionalità

Infine, vai alla scheda Funzionalità nello strumento What-if. Viene mostrata la distribuzione dei valori per ogni caratteristica nel tuo set di dati:

Puoi usare questa scheda per assicurarti che il set di dati sia bilanciato. Ad esempio, sembra che pochissimi prestiti nel set di dati provengano da Farm Service Agency. Per migliorare l'accuratezza del modello, potremmo valutare l'aggiunta di altri prestiti da questa agenzia, se i dati sono disponibili.

In questo articolo abbiamo descritto solo alcune idee per l'esplorazione dello strumento What-If. Puoi continuare a sperimentare con lo strumento, ci sono molte altre aree da esplorare.

8. Esegui il deployment del modello su Vertex AI

Il nostro modello funziona in locale, ma sarebbe bello se potessimo fare previsioni da qualsiasi luogo (non solo da questo blocco note!). In questo passaggio ne eseguiremo il deployment nel cloud.

Passaggio 1: crea un bucket Cloud Storage per il nostro modello

Per prima cosa, definiamo alcune variabili di ambiente che utilizzeremo nel resto del codelab. Compila i valori seguenti con il nome del tuo progetto Google Cloud, il nome del bucket Cloud Storage che vuoi creare (deve essere univoco a livello globale) e il nome della versione della prima versione del modello:

# 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'

Ora siamo pronti a creare un bucket di archiviazione in cui archiviare il file del modello XGBoost. Puntiamo Vertex AI a questo file durante il deployment.

Esegui questo comando gsutil dal blocco note per creare un bucket di archiviazione a livello di regione:

!gsutil mb -l us-central1 $MODEL_BUCKET

Passaggio 2: copia il file del modello in Cloud Storage

Ora copieremo il file del modello salvato di XGBoost in Cloud Storage. Esegui il seguente comando gsutil:

!gsutil cp ./model.bst $MODEL_BUCKET

Vai al browser Storage nella console Cloud per verificare che il file sia stato copiato:

Passaggio 3: crea il modello ed esegui il deployment su un endpoint

Siamo quasi pronti per eseguire il deployment del modello nel cloud. In Vertex AI un modello può contenere più endpoint. Prima creeremo un modello, quindi creeremo un endpoint al suo interno e ne eseguiremo il deployment.

Innanzitutto, utilizza l'interfaccia a riga di comando gcloud per creare il tuo modello:

!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

Il parametro artifact-uri punterà alla posizione di archiviazione in cui hai salvato il modello XGBoost. Il parametro container-image-uri indica a Vertex AI quale container predefinito utilizzare per la pubblicazione. Al termine del comando, vai alla sezione dei modelli della console Vertex per ottenere l'ID del nuovo modello. Puoi trovarla qui:

Recupera l'ID modello dalla console

Copia l'ID e salvalo in una variabile:

MODEL_ID = "your_model_id"

Ora è il momento di creare un endpoint all'interno di questo modello. Possiamo farlo con questo comando gcloud:

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

Al termine, dovresti vedere la posizione del tuo endpoint registrata nell'output del blocco note. Cerca la riga indicante che l'endpoint è stato creato con un percorso simile al seguente: projects/project_ID/locations/us-central1/endpoints/endpoint_ID. Quindi, sostituisci i valori seguenti con gli ID dell'endpoint creato sopra:

ENDPOINT_ID = "your_endpoint_id"

Per eseguire il deployment dell'endpoint, esegui il comando gcloud seguente:

!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

Il completamento del deployment dell'endpoint richiederà circa 5-10 minuti. Durante il deployment dell'endpoint, vai alla sezione dei modelli della console. Fai clic sul tuo modello e dovresti vedere il deployment endpiont:

Una volta completato il deployment, vedrai un segno di spunta verde in corrispondenza della rotellina di caricamento.

Passaggio 4: testa il modello di cui è stato eseguito il deployment

Per assicurarti che il modello di cui hai eseguito il deployment funzioni, testalo utilizzando gcloud per fare una previsione. Per prima cosa, salva un file JSON con un esempio del nostro set di test:

%%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]
  ]
}

Testa il modello eseguendo questo comando gcloud:

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

Nell'output dovresti vedere la previsione del modello. Questo esempio specifico è stato approvato, pertanto dovresti vedere un valore vicino a 1.

9. Esegui la pulizia

Se desideri continuare a utilizzare questo blocco note, ti consigliamo di disattivarlo quando non lo usi. Dall'interfaccia utente di Notebooks in Cloud Console, seleziona il blocco note, quindi seleziona Interrompi:

Per eliminare tutte le risorse che hai creato in questo lab, elimina l'istanza del blocco note anziché arrestarla.

Per eliminare l'endpoint di cui hai eseguito il deployment, vai alla sezione Endpoint della console Vertex e fai clic sull'icona Elimina:

Per eliminare il bucket di archiviazione, utilizzando il menu di navigazione nella console Cloud, vai a Storage, seleziona il bucket e fai clic su Elimina: