Cómo analizar con la Herramienta What-If un modelo de AA financiero implementado en AI Platform de Cloud

1. Descripción general

En este lab, utilizarás la Herramienta What-If para analizar un modelo XGBoost entrenado con datos financieros y que se implementó en AI Platform de Cloud.

Qué aprenderá

Aprenderás a hacer lo siguiente:

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

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

2. Manual básico y rápido de XGBoost

XGBoost es un framework de aprendizaje automático que usa árboles de decisión y potenciación de gradientes para compilar modelos predictivos. Funciona en el ensamblaje de varios árboles de decisión en función de la puntuación asociada con diferentes nodos 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 tiempo:

308a0bfc70733abf.png

¿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.

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

Navega a la sección Modelos de AI Platform de la consola de Cloud y haz clic en Habilitar si aún no está habilitada.

d0d38662851c6af3.png

Paso 2: 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 3: Crea una instancia de AI Platform Notebooks

Navega a la sección AI Platform Notebooks de la consola de Cloud y haz clic en Instancia nueva. Luego, selecciona el tipo de instancia más reciente de TF Enterprise 2.x sin GPU:

7d16190440ab2e9c.png

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

827f8868d3841ba0.png

Paso 4: Instala XGBoost

Cuando se abra tu instancia de JupyterLab, deberás agregar el paquete XGBoost.

Para ello, selecciona Terminal en el selector:

28dcf2790ce77c96.png

Luego, ejecuta el siguiente comando para instalar la última versión de XGBoost compatible con AI Platform de Cloud:

pip3 install xgboost==0.90

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 de tu notebook, agrega las siguientes importaciones y ejecuta la celda. Para ejecutarla, presiona el botón de la flecha hacia la derecha en el menú superior o presiona Command + 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

4. Descarga y procesa datos

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

Paso 1: Descarga el conjunto de datos ya procesados

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 Pandas, crearemos un dict del tipo de datos de cada columna para que Pandas lea el 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 redistribuir nuestros datos en caso de que el conjunto de datos original esté ordenado de una manera específica. Para hacer esto, 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:

29106b71103235a6.png

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 y rechazados en el conjunto de datos y crear un array de NumPy de las etiquetas, ejecuta el siguiente comando:

# 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 la codificación one-hot, para nuestro modelo 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 valores posibles de “blue” y "rojo", get_dummies transformaría esto en 2 columnas llamadas “color_blue” y "color_red" 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()

Cuando obtengas una vista previa de los datos esta vez, verás atributos individuales (como purchaser_type que se muestra a continuación) divididos en varias columnas:

83aacfaad626e538.png

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 antes vio.

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

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

Ya está todo listo para que compiles y entrenes tu modelo.

5. 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 tendremos que 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 el modelo entrenado para generar predicciones con los 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 según el rendimiento de los datos de prueba. Pasaremos los valores de verdad fundamental junto con los valores predichos del modelo para cada ejemplo en 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 el tuyo variará un poco, ya que siempre existe un elemento de aleatoriedad en el aprendizaje automático.

Paso 3: Guarda el modelo

Para implementar el modelo, ejecuta el siguiente código y guárdalo en un archivo local:

model.save_model('model.bst')

6. Implementar el modelo en AI Platform de Cloud

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 siguientes valores 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 primera versión de tu modelo:

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

Ya tenemos todo listo para crear un bucket de almacenamiento y almacenar nuestro archivo del modelo XGBoost. Indicaremos Cloud AI Platform hacia este archivo cuando realicemos la implementación.

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

!gsutil mb $MODEL_BUCKET

Paso 2: Copia el archivo de modelo en Cloud Storage

A continuación, copiaremos nuestro archivo del modelo guardado de XGBoost en 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 copió el archivo:

31e2567fa0117214.png

Paso 3: Crea e implementa el modelo

Ya casi está todo listo para implementar el modelo. El siguiente comando de gcloud ai-platform creará un modelo nuevo en tu proyecto. La llamaremos xgb_mortgage:

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

Ahora es el momento de implementar el modelo. Podemos hacerlo con el siguiente comando de 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'

Mientras se ejecuta, revisa la sección de modelos de la consola de AI Platform. Deberías ver tu nueva versión implementándose allí:

342875ba92becad1.png

Cuando la implementación se complete correctamente, verás una marca de verificación verde donde se encuentra el ícono giratorio de carga. La implementación debería tardar entre 2 y 3 minutos.

Paso 4: Prueba el modelo implementado

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

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

Ejecuta este código para probar tu modelo:

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

print(prediction)

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.

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 What-If a tus modelos de AI Platform, debes pasarle un subconjunto de los ejemplos de prueba junto con los valores de verdad fundamental de esos ejemplos. Creemos 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].values,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 de AI Platform que queremos analizar.

Aquí usamos el parámetro opcional adjust_prediction porque la Herramienta What-If espera una lista de puntuaciones para cada clase de nuestro modelo (en este caso, 2). Dado que nuestro modelo solo devuelve un único valor de 0 a 1, lo transformamos al formato correcto en esta función:

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)

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

4c0b00e6afcdbe01.png

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 expansión de todos los datos cargados.

Paso 2: Explora los datos individuales

La vista predeterminada de la Herramienta What-If es la pestaña del 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 hipotecaria 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:

717620d6a1330479.png

Como podemos ver en la sección inferior izquierda de la Herramienta What-If, cambiar este atributo redujo 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:

60ff20ae80ed5e27.png

Paso 3: Análisis contrafáctico

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

ae64fd7abefe5449.png

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

Paso 4: Observa los gráficos de dependencia parcial

Para ver cómo cada atributo afecta a las predicciones del modelo en general, marca la casilla Gráficos de dependencias parciales y asegúrate de que se seleccione Dibujos de dependencias parciales globales:

72117b5ceb683841.png

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

applicant_income_thousands es un atributo numérico y, en el gráfico de dependencia parcial, podemos ver que los ingresos más altos aumentan ligeramente la probabilidad de que se apruebe una solicitud, pero solo hasta alrededor de $200,000. Después de $200,000, este atributo no afecta la predicción del modelo.

Paso 5: Explora el rendimiento y la equidad generales

A continuación, ve a la sección Rendimiento y Equidad. Esto muestra las estadísticas generales de rendimiento de los resultados del modelo en el conjunto de datos proporcionado, incluidas las matrices de confusión, las curvas PR y las curvas ROC.

Selecciona mortgage_status como el atributo de verdad fundamental para ver una matriz de confusión:

fe1384ee47699498.png

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í predicho y No real / No predicho, debería sumar la misma exactitud que tu modelo (alrededor del 87%).

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

A continuación, en el menú desplegable Segmentar por de la izquierda, selecciona loan_purpose_Home_purchase:

f3f1858d627d57ab.png

Ahora verá el rendimiento en los dos subconjuntos de sus datos: el "0". muestra cuando el préstamo no es para la compra de una vivienda, y el número “1” cuando el préstamo es para la compra de una vivienda. Verifica la tasa de precisión, falso positivo y falso negativo entre las dos porciones para buscar diferencias en el rendimiento.

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

318a8d5a8ffc6bea.png

Si seleccionas Paridad demográfica en los botones de selección de la izquierda, se ajustarán los dos umbrales, de modo que el modelo prediga approved para un porcentaje similar de solicitantes en ambos segmentos. ¿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. Esto te muestra la distribución de los valores para cada atributo del conjunto de datos:

48ab3c4879793324.png

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

Aquí describimos algunas ideas de exploración de la Herramienta What-If. Siéntete libre de seguir jugando con la herramienta, ¡hay muchas más áreas por explorar!

8. Limpieza

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

879147427150b6c7.png

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

En el menú de navegación de la consola de Cloud, navega a Almacenamiento y borra los buckets que creaste para almacenar tus recursos del modelo.