Analisi di un modello ML finanziario di cui è stato eseguito il deployment su Cloud AI Platform con lo strumento What-if

1. Panoramica

In questo lab utilizzerai lo strumento What-if per analizzare un modello XGBoost addestrato su dati finanziari e di cui è stato eseguito il deployment su Cloud AI Platform.

Cosa imparerai

Al termine del corso sarai in grado di:

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

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

2. 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:

308a0bfc70733abf.png

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.

3. 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 Cloud AI Platform Models

Vai alla sezione Modelli di AI Platform della console Cloud e fai clic su Abilita se non è già abilitata.

d0d38662851c6af3.png

Passaggio 2: 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 3: crea un'istanza di AI Platform Notebooks

Vai alla sezione AI Platform Notebooks della console Cloud e fai clic su Nuova istanza. Quindi, seleziona il tipo di istanza TF Enterprise 2.x più recente senza GPU:

7d16190440ab2e9c.png

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

772f8868d3841ba0.png

Passaggio 4: installa XGBoost

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

Per farlo, seleziona Terminale da Avvio app:

28dcf2790ce77c96.png

Poi esegui questo comando per installare la versione più recente di XGBoost supportata da Cloud AI Platform:

pip3 install xgboost==0.90

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

4. 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 DataFrame Pandas, occorre creare un detto per il 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:

29106b71103235a6.png

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:

83aacfaad626e538.png

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 al blocco note il codice seguente, che utilizza la funzione Scikit Learn train_test_split per suddividere i dati:

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

Ora è tutto pronto per creare e addestrare il modello.

5. 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().

Utilizzeremo 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 empirici reali insieme ai valori previsti dal modello per ogni esempio nel nostro 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')

6. Esegui il deployment del modello in Cloud AI Platform

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. Inserisci 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 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'

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

Esegui questo comando gsutil dal blocco note per creare un bucket:

!gsutil mb $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:

31e2567fa0117214.png

Passaggio 3: crea ed esegui il deployment del modello

Siamo quasi pronti per eseguire il deployment del modello. Il seguente comando gcloud di ai-platform creerà un nuovo modello nel progetto. Lo chiameremo xgb_mortgage:

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

Ora è il momento di eseguire il deployment del modello. Possiamo farlo con questo comando 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'

Mentre è in esecuzione, controlla la sezione dei modelli della console di AI Platform. Dovresti vedere il deployment della nuova versione qui:

342875ba92becad1.png

Una volta completato il deployment, vedrai un segno di spunta verde in corrispondenza della rotellina di caricamento. Il deployment dovrebbe richiedere 2-3 minuti.

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 il primo esempio del nostro set di test:

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

Testa il modello eseguendo questo codice:

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

print(prediction)

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

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

Passaggio 1: crea la visualizzazione dello strumento What-if

Per connettere lo strumento What-if ai tuoi modelli AI Platform, devi passarlo un sottoinsieme degli esempi di test insieme ai valori di fatto 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].values,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 AI Platform che vogliamo analizzare.

Qui utilizziamo il parametro facoltativo adjust_prediction perché lo strumento What-if prevede un elenco di punteggi per ogni classe nel nostro modello (in questo caso 2). Poiché il nostro modello restituisce un solo valore compreso tra 0 e 1, lo trasformiamo nel formato corretto in questa funzione:

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)

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

4c0b00e6afcdbe01.png

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) è impostato su 1 per vedere cosa succederebbe alla previsione del modello se il prestito proveniva invece da HUD:

717620d6a1330479.png

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:

60ff20ae80ed5e27.png

Passaggio 3: analisi controfattuale

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

ae64fd7abefe5449.png

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:

72117b5ceb683841.png

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:

fe1384ee47699498.png

Questa matrice di confusione mostra le previsioni corrette e non corrette del modello come percentuale del totale. Se somma i quadrati Effettivo Sì / Sì previsto e Effettivo No / No previsto, la somma della precisione sarà la stessa del modello (circa l'87%).

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:

f3f1858d627d57ab.png

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

318a8d5a8ffc6bea.png

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:

48ab3c4879793324.png

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

879147427150b6c7.png

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

Utilizzando il menu di navigazione nella console Cloud, vai a Storage ed elimina i bucket creati per archiviare gli asset del modello.