Crea un modelo de AA financiero con la Herramienta What-If y Vertex AI

1. Descripción general

En este lab, usarás la herramienta What-If para analizar un modelo de XGBoost entrenado en datos financieros. Después de analizar el modelo, lo implementarás en el nuevo Vertex AI de Cloud.

Qué aprenderá

Aprenderás a hacer lo siguiente:

  • Entrena un modelo XGBoost en un conjunto de datos públicos hipotecarios en un notebook alojado
  • Analiza el modelo con la Herramienta What-If
  • Implementa el modelo XGBoost en Vertex AI

El costo total de la ejecución de este lab en Google Cloud es de aproximadamente $1.

2. Introducción a Vertex AI

En este lab, se utiliza la oferta de productos de IA más reciente de Google Cloud. Vertex AI integra las ofertas de AA de Google Cloud en una experiencia de desarrollo fluida. Anteriormente, se podía acceder a los modelos personalizados y a los entrenados con AutoML mediante servicios independientes. La nueva oferta combina ambos en una sola API, junto con otros productos nuevos. También puedes migrar proyectos existentes a Vertex AI. Para enviarnos comentarios, visita la página de asistencia.

Vertex AI incluye muchos productos distintos para respaldar flujos de trabajo de AA de extremo a extremo. Este lab se enfocará en los productos que se destacan a continuación: Prediction y Notebooks.

Descripción general del producto Vertex

3. Una introducción rápida a XGBoost

XGBoost es un framework de aprendizaje automático que usa árboles de decisión y amplificación de gradientes para crear modelos predictivos. Funciona combinando varios árboles de decisión en función de la puntuación asociada con diferentes nodos de hoja en un árbol.

El siguiente diagrama es una visualización de un modelo de árbol de decisión simple que evalúa si se debe jugar un partido deportivo en función del pronóstico del clima:

Ejemplo de modelo de árbol

¿Por qué usamos XGBoost para este modelo? Si bien se demostró que las redes neuronales tradicionales tienen un mejor rendimiento con datos no estructurados, como imágenes y texto, los árboles de decisión suelen tener un rendimiento excelente en datos estructurados, como el conjunto de datos hipotecarios que usaremos en este codelab.

4. Cómo configurar tu entorno

Para ejecutar este codelab, necesitarás un proyecto de Google Cloud Platform que tenga habilitada la facturación. Para crear un proyecto, sigue estas instrucciones.

Paso 1: Habilita la API de Compute Engine

Ve a Compute Engine y selecciona Habilitar (si aún no está habilitada). La necesitarás para crear la instancia de notebook.

Paso 2: Habilita la API de Vertex AI

Navega a la sección Vertex de la consola de Cloud y haz clic en Habilitar la API de Vertex AI.

Panel de Vertex

Paso 3: Crea una instancia de Notebooks

En la sección Vertex de la consola de Cloud, haz clic en Notebooks:

Cómo seleccionar notebooks

Desde allí, selecciona Nueva instancia. Luego, selecciona el tipo de instancia TensorFlow Enterprise 2.3 sin GPUs:

Instancia de TFE

Usa las opciones predeterminadas y, luego, haz clic en Crear. Una vez que se crea la instancia, selecciona Abrir JupyterLab.

Paso 4: Instala XGBoost

Una vez que se abra tu instancia de JupyterLab, deberás agregar el paquete XGBoost.

Para ello, selecciona Terminal en el selector:

Luego, ejecuta el siguiente comando para instalar la versión más reciente de XGBoost compatible con Vertex AI:

pip3 install xgboost==1.2

Cuando se complete, abre una instancia de notebook de Python 3 desde el selector. Ya estás listo para comenzar con tu notebook.

Paso 5: Importa paquetes de Python

En la primera celda del notebook, agrega las siguientes importaciones y ejecútala. Para ejecutarlo, presiona el botón de flecha hacia la derecha en el menú superior o presiona Comando Intro:

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. Descarga y procesa datos

Usaremos un conjunto de datos hipotecarios de ffiec.gov para entrenar un modelo XGBoost. Realizamos un procesamiento previo en el conjunto de datos original y creamos una versión más pequeña para que la uses para entrenar el modelo. El modelo predecirá si se aprobará o no una solicitud de hipoteca en particular.

Paso 1: Descarga el conjunto de datos procesado previamente

En Google Cloud Storage, hay una versión del conjunto de datos a tu disposición. Para descargarlo, ejecuta el siguiente comando gsutil en tu notebook de Jupyter:

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

Paso 2: Lee el conjunto de datos con Pandas

Antes de crear nuestro DataFrame de Pandas, crearemos un dict del tipo de datos de cada columna para que Pandas lea nuestro conjunto de datos correctamente:

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

A continuación, crearemos un DataFrame y le pasaremos los tipos de datos que especificamos anteriormente. Es importante mezclar nuestros datos en caso de que el conjunto de datos original esté ordenado de una manera específica. Para ello, usamos una utilidad sklearn llamada shuffle, que importamos en la primera celda:

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() nos permite obtener una vista previa de las primeras cinco filas de nuestro conjunto de datos en Pandas. Deberías ver algo como esto después de ejecutar la celda anterior:

Vista previa del conjunto de datos de hipotecas

Estos son los atributos que usaremos para entrenar nuestro modelo. Si te desplazas hasta el final, verás la última columna approved, que es lo que estamos prediciendo. Un valor de 1 indica que se aprobó una aplicación específica, y 0 indica que se rechazó.

Para ver la distribución de los valores aprobados o rechazados en el conjunto de datos y crear un array numpy de las etiquetas, ejecuta lo siguiente:

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

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

Alrededor del 66% del conjunto de datos contiene aplicaciones aprobadas.

Paso 3: Crea una columna ficticia para valores categóricos

Este conjunto de datos contiene una combinación de valores categóricos y numéricos, pero XGBoost requiere que todos los atributos sean numéricos. En lugar de representar valores categóricos con codificación one-hot, para nuestro modelo de XGBoost aprovecharemos la función get_dummies de Pandas.

get_dummies toma una columna con varios valores posibles y la convierte en una serie de columnas, cada una con solo 0 y 1. Por ejemplo, si tuviéramos una columna "color" con los valores posibles "azul" y "rojo", get_dummies lo transformaría en 2 columnas llamadas "color_azul" y "color_rojo" con todos los valores booleanos 0 y 1.

A fin de crear columnas de prueba para nuestros atributos categóricos, ejecuta el siguiente código:

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

data.head()

Esta vez, cuando obtengas una vista previa de los datos, verás componentes individuales (como purchaser_type en la imagen que aparece a continuación) divididos en varias columnas:

Columnas simuladas de Pandas

Paso 4: Divide los datos en conjuntos de entrenamiento y prueba

Un concepto importante en el aprendizaje automático es la división de entrenamiento y prueba. Usaremos la mayoría de nuestros datos para entrenar nuestro modelo y reservaremos el resto para probar el modelo con datos que nunca ha visto.

Agrega el siguiente código a tu notebook, que usa la función train_test_split de Scikit-learn para dividir nuestros datos:

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

Ya está todo listo para compilar y entrenar tu modelo.

6. Crea, entrena y evalúa un modelo XGBoost

Paso 1: Define y entrena el modelo de XGBoost

Crear un modelo en XGBoost es sencillo. Usaremos la clase XGBClassifier para crear el modelo y solo debemos pasar el parámetro objective correcto para nuestra tarea de clasificación específica. En este caso, usamos reg:logistic, ya que tenemos un problema de clasificación binaria y queremos que el modelo genere un solo valor en el rango de (0,1): 0 para no aprobado y 1 para aprobado.

El siguiente código creará un modelo XGBoost:

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

Puedes entrenar el modelo con una línea de código llamando al método fit() y pasándole los datos de entrenamiento y las etiquetas.

model.fit(x_train, y_train)

Paso 2: Evalúa la exactitud de tu modelo

Ahora podemos usar nuestro modelo entrenado para generar predicciones en nuestros datos de prueba con la función predict().

Luego, usaremos la función accuracy_score() de Scikit-learn para calcular la exactitud de nuestro modelo en función de su rendimiento en nuestros datos de prueba. Le pasaremos los valores de verdad fundamental junto con los valores pronosticados del modelo para cada ejemplo de nuestro conjunto de prueba:

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

Deberías ver una precisión de alrededor del 87%, pero la tuya variará ligeramente, ya que siempre hay un elemento de aleatoriedad en el aprendizaje automático.

Paso 3: Guarda tu modelo

Para implementar el modelo, ejecuta el siguiente código para guardarlo en un archivo local:

model.save_model('model.bst')

7. Usa la Herramienta What-If para interpretar tu modelo

Paso 1: Crea la visualización de la Herramienta What-If

Para conectar la herramienta Qué pasaría si a tu modelo local, debes pasarle un subconjunto de tus ejemplos de prueba junto con los valores de verdad fundamental de esos ejemplos. Crear un array Numpy de 500 de nuestros ejemplos de prueba junto con sus etiquetas de verdad fundamental:

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

Crear una instancia de la Herramienta What-If es tan simple como crear un objeto WitConfigBuilder y pasarle el modelo que queremos analizar.

Dado que la Herramienta What-If espera una lista de puntuaciones para cada clase de nuestro modelo (en este caso, 2), usaremos el método predict_proba de XGBoost con la Herramienta 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)

Ten en cuenta que la visualización tardará un minuto en cargarse. Cuando se cargue, deberías ver lo siguiente:

Vista inicial de la herramienta What-If

En el eje Y, se muestra la predicción del modelo, en el que 1 es una predicción approved de alta confianza y 0 es una predicción denied de alta confianza. El eje x es solo la propagación de todos los datos cargados.

Paso 2: Explora los datos individuales

La vista predeterminada de la herramienta What-if es la pestaña Editor de datos. Aquí puedes hacer clic en cualquier dato individual para ver sus atributos, cambiar sus valores y ver cómo ese cambio afecta la predicción del modelo en un dato individual.

En el siguiente ejemplo, elegimos un dato cercano al umbral de 0 .5. La solicitud de hipoteca asociada con este dato en particular se originó en la CFPB. Cambiamos ese atributo a 0 y también cambiamos el valor de agency_code_Department of Housing and Urban Development (HUD) a 1 para ver qué pasaría con la predicción del modelo si este préstamo se originara a partir del HUD:

Como podemos ver en la sección inferior izquierda de la herramienta Qué pasaría si, cambiar esta función disminuyó significativamente la predicción de approved del modelo en un 32%. Esto podría indicar que la agencia de donde proviene un préstamo tiene un fuerte impacto en los resultados del modelo, pero tendremos que hacer más análisis para estar seguros.

En la parte inferior izquierda de la IU, también podemos ver el valor de verdad fundamental de cada dato y compararlo con la predicción del modelo:

Paso 3: Análisis contrafactual

Luego, haz clic en cualquier dato y mueve el control deslizante Mostrar el dato contrafáctico más cercano hacia la derecha:

Si seleccionas esta opción, se mostrará el dato que tiene los valores de atributos más similares al original que seleccionaste, pero con la predicción opuesta. Luego, puedes desplazarte por los valores de los atributos para ver en qué se diferencian los dos datos (las diferencias se destacan en verde y en negrita).

Paso 4: Observa los gráficos de dependencia parcial

Para ver cómo cada atributo afecta las predicciones del modelo en general, marca la casilla Gráficos de dependencia parcial y asegúrate de que esté seleccionada la opción Gráficos de dependencia parcial globales:

Aquí podemos ver que los préstamos que provienen del HUD tienen una probabilidad ligeramente mayor de que se rechacen. El gráfico tiene esta forma porque el código de la agencia es un atributo booleano, por lo que los valores solo pueden ser exactamente 0 o 1.

applicant_income_thousands es una característica numérica y, en el gráfico de dependencia parcial, podemos ver que un ingreso más alto aumenta ligeramente la probabilidad de que se apruebe una solicitud, pero solo hasta alrededor de USD 200,000. Después de USD 200,000, este atributo no afecta la predicción del modelo.

Paso 5: Explora el rendimiento general y la equidad

A continuación, ve a la pestaña Rendimiento y equidad. Se muestran las estadísticas de rendimiento generales de los resultados del modelo en el conjunto de datos proporcionado, incluidas las matrices de confusión, las curvas de PR y las curvas ROC.

Selecciona mortgage_status como la función de verdad fundamental para ver una matriz de confusión:

Esta matriz de confusión muestra las predicciones correctas e incorrectas del modelo como un porcentaje del total. Si sumas los cuadrados Sí real / Sí previsto y No real / No previsto, deberías obtener la misma precisión que tu modelo (en este caso, alrededor del 87%, aunque tu modelo puede variar ligeramente, ya que hay un elemento de aleatoriedad en el entrenamiento de los modelos de AA).

También puedes experimentar con el control deslizante de umbral, subir y bajar la puntuación de clasificación positiva que el modelo debe mostrar antes de decidir si predecir approved para el préstamo y ver cómo cambia la precisión, los falsos positivos y los falsos negativos. En este caso, la exactitud es más alta alrededor de un umbral de 0.55.

Luego, en el menú desplegable Dividir por de la izquierda, selecciona loan_purpose_Home_purchase:

Ahora verás el rendimiento en los dos subconjuntos de tus datos: la porción “0” muestra cuando el préstamo no es para una compra de una vivienda, y la porción “1” es para cuando el préstamo es para la compra de una casa. Consulta la precisión, el porcentaje de falsos positivos y el porcentaje de falsos negativos entre las dos divisiones para buscar diferencias en el rendimiento.

Si expandes las filas para ver las matrices de confusión, puedes ver que el modelo predice que el modelo está “aprobado” para ~70% de solicitudes de préstamos para compras de viviendas y solo el 46% de préstamos que no son para compras de viviendas (los porcentajes exactos varían según tu modelo):

Si seleccionas Paridad demográfica en los botones de selección de la izquierda, se ajustarán los dos umbrales para que el modelo prediga approved para un porcentaje similar de postulantes en ambas divisiones. ¿Qué efectos tiene esto en la exactitud y los falsos positivos y los falsos negativos de cada porción?

Paso 6: Explora la distribución de atributos

Por último, navega a la pestaña Features en la Herramienta What-If. Se muestra la distribución de valores de cada atributo de tu conjunto de datos:

Puedes usar esta pestaña para asegurarte de que tu conjunto de datos esté equilibrado. Por ejemplo, parece que muy pocos préstamos del conjunto de datos se originaron en la Agencia de Servicios Agrícolas. Para mejorar la precisión del modelo, podríamos considerar agregar más préstamos de esa agencia si los datos están disponibles.

Aquí, describimos solo algunas ideas de exploración de la herramienta What-If. No dudes en seguir jugando con la herramienta, ya que hay muchas más áreas para explorar.

8. Implementar el modelo en Vertex AI

Nuestro modelo está funcionando localmente, pero sería bueno poder hacer predicciones con él desde cualquier lugar (no solo desde este notebook). En este paso, lo implementaremos en la nube.

Paso 1: Crea un bucket de Cloud Storage para nuestro modelo

Primero, definamos algunas variables de entorno que usaremos durante el resto del codelab. Completa los valores que se indican a continuación con el nombre de tu proyecto de Google Cloud, el nombre del bucket de Cloud Storage que deseas crear (debe ser único a nivel global) y el nombre de la versión de la primera versión de tu modelo:

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

Ya está todo listo para crear un bucket de almacenamiento para nuestro archivo de modelo de XGBoost. Le indicaremos a Vertex AI que use este archivo cuando lo implementemos.

Ejecuta este comando gsutil desde tu notebook para crear un bucket de Regional Storage:

!gsutil mb -l us-central1 $MODEL_BUCKET

Paso 2: Copia el archivo del modelo en Cloud Storage

A continuación, copiaremos el archivo del modelo guardado de XGBoost a Cloud Storage. Ejecuta el siguiente comando gsutil:

!gsutil cp ./model.bst $MODEL_BUCKET

Ve al navegador de almacenamiento en la consola de Cloud para confirmar que se haya copiado el archivo:

Paso 3: Crea el modelo y, luego, impleméntalo en un extremo

Ya casi está todo listo para implementar el modelo en la nube. En Vertex AI, un modelo puede contener varios extremos. Primero, crearemos un modelo y, luego, crearemos un extremo dentro de ese modelo y lo implementaremos.

Primero, usa la CLI de gcloud para crear tu modelo:

!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

El parámetro artifact-uri apuntará a la ubicación de Storage en la que guardaste tu modelo de XGBoost. El parámetro container-image-uri le indica a Vertex AI qué contenedor compilado previamente usar para la entrega. Una vez que se complete este comando, navega a la sección de modelos de la consola de Vertex para obtener el ID de tu modelo nuevo. Puedes encontrarla aquí:

Obtén el ID del modelo desde la consola

Copia ese ID y guárdalo en una variable:

MODEL_ID = "your_model_id"

Ahora es el momento de crear un extremo dentro de este modelo. Podemos hacerlo con este comando de gcloud:

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

Cuando se complete, deberías ver la ubicación de tu extremo registrada en el resultado de nuestro notebook. Busca la línea que dice que el extremo se creó con una ruta de acceso que se ve de la siguiente manera: projects/project_ID/locations/us-central1/endpoints/endpoint_ID. Luego, reemplaza los valores que aparecen a continuación por los IDs del extremo que creaste anteriormente:

ENDPOINT_ID = "your_endpoint_id"

Para implementar tu extremo, ejecuta el siguiente comando de gcloud:

!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

La implementación del extremo tardará entre 5 y 10 minutos en completarse. Mientras se implementa tu extremo, ve a la sección de modelos de la consola. Haz clic en tu modelo y deberías ver que se implementa tu extremo:

Cuando la implementación se complete correctamente, verás una marca de verificación verde donde está el ícono giratorio de carga.

Paso 4: Prueba el modelo implementado

Para asegurarte de que tu modelo implementado funcione, pruébalo con gcloud para hacer una predicción. Primero, guarda un archivo JSON con un ejemplo de nuestro conjunto de pruebas:

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

Para probar tu modelo, ejecuta este comando de gcloud:

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

Deberías ver la predicción de tu modelo en el resultado. Este ejemplo en particular se aprobó, por lo que deberías ver un valor cercano a 1.

9. Limpieza

Si quieres seguir usando este notebook, te recomendamos que lo desactives cuando no lo uses. En la IU de Notebooks de la consola de Cloud, selecciona el notebook y, luego, haz clic en Detener:

Si quieres borrar todos los recursos que creaste en este lab, solo borra la instancia de notebook en lugar de detenerla.

Para borrar el extremo que implementaste, navega a la sección Extremos de la consola de Vertex y haz clic en el ícono de borrar:

Para borrar el bucket de almacenamiento, en el menú de navegación de la consola de Cloud, navega a Almacenamiento, selecciona tu bucket y haz clic en Borrar (Delete):