Crea un modelo de detección de fraudes en AI Platform de Cloud con TensorFlow Enterprise y BigQuery

1. Descripción general

En este lab, transferirás directamente un conjunto de datos de BigQuery y entrenarás un modelo de detección de fraudes con TensorFlow Enterprise en AI Platform de Google Cloud.

Qué aprenderá

Aprenderás a hacer lo siguiente:

  • Analiza datos en BigQuery
  • Transfiere datos con el conector de BigQuery en TensorFlow Enterprise
  • Crear un modelo de aprendizaje profundo para detectar fraudes con un conjunto de datos desequilibrado

2. Analiza los datos en BigQuery

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: Accede al conjunto de datos públicos de BigQuery

Sigue este vínculo para acceder a los conjuntos de datos públicos de BigQuery en la consola de Google Cloud.

En el árbol de recursos de la esquina inferior izquierda, verás una lista de conjuntos de datos. Navega por los conjuntos de datos disponibles hasta que encuentres ml-datasets y, luego, selecciona la tabla ulb-fraud-detection dentro de él:

d5e78261514a90ef.png

Haz clic en cada pestaña para obtener más información sobre el conjunto de datos:

  • En la pestaña Esquema, se describen los tipos de datos.
  • En la pestaña Detalles, se explica que este es un conjunto de datos desequilibrado con 284,407 transacciones, de las cuales 492 son fraudulentas.
  • La pestaña Vista previa muestra los registros del conjunto de datos.

Paso 2: Consulta la tabla

La pestaña de detalles nos brinda la siguiente información sobre los datos:

  • El tiempo es la cantidad de segundos entre la primera transacción en el conjunto de datos y la hora de la transacción seleccionada.
  • V1-V28 son columnas que se transformaron a través de una técnica de reducción de la dimensionalidad llamada PCA que anonimiza los datos.
  • El importe es el importe de la transacción.

Analicemos con más detalle haciendo clic en Consultar tabla para ejecutar una consulta:

581e596426a98383.png

Actualiza la instrucción para agregar un * para ver todas las columnas y haz clic en Ejecutar.

SELECT * FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection` LIMIT 1000

Paso 3: Analiza los datos

BigQuery proporciona una serie de funciones estadísticas. Veamos cómo se correlacionan los datos con la variable de destino Class.

SELECT CORR(Time,Class) as TimeCorr, CORR(V1,Class) as V1Corr, CORR(V2,Class) as V2Corr, CORR(Amount,Class) as AmountCorr FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`

e1e98a8315b62e9e.png

La correlación proporcionará un rango de -1 (correlacionado negativamente) a 1 (correlacionado de manera positiva), donde 0 será independiente.

Ten en cuenta que V1 y V2 tienen una ligera correlación con nuestra variable objetivo (alrededor de -0.1 y 0 .1 respectivamente).

No observamos mucha correlación con el atributo tiempo. Una correlación ligeramente negativa podría decirnos que hay menos transacciones fraudulentas a lo largo del tiempo en el conjunto de datos.

Importe tiene una correlación aún menor, lo que indica que las transacciones fraudulentas son muy probables en importes de transacción más altos.

Paso 4: Calcula los valores medios para el escalamiento de atributos

Normalizar los valores de atributos puede ayudar a que una red neuronal converja más rápido. Un esquema común consiste en centrar los valores alrededor de 0 con una desviación estándar de 1. La siguiente consulta recuperará los valores medios. No es necesario guardar el resultado, ya que tendremos un fragmento de código para eso más adelante.

También notarás que la consulta incluye una cláusula WHERE interesante. Lo describiremos en la siguiente sección, cuando veamos cómo dividir los datos entre conjuntos de entrenamiento y de prueba.

SELECT
   AVG(Time), AVG(V1), AVG(V2), AVG(V3), AVG(V4), AVG(V5), AVG(V6), AVG(V7), AVG(V8),
   AVG(V9), AVG(V10),AVG(V11), AVG(V12), AVG(V13), AVG(V14), AVG(V15), AVG(V16),
   AVG(V17), AVG(V18), AVG(V19), AVG(V20), AVG(V21), AVG(V22), AVG(V23), AVG(V24),
   AVG(V25), AVG(V26), AVG(V27),AVG(V28), AVG(Amount)
FROM
   `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE
   MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),
   SAFE_CAST(Amount AS STRING)))),10) < 8

Paso 5: Divide los datos

Es una práctica común usar 3 conjuntos de datos cuando se compila un modelo de aprendizaje automático:

  • Entrenamiento: se usa para compilar el modelo a través del ajuste de parámetros de manera iterativa.
  • Validación: Se usa para evaluar si el modelo está sobreajustado a través de la verificación en datos independientes durante el proceso de entrenamiento.
  • Prueba: se usa después de crear el modelo para evaluar la exactitud.

En este codelab, usaremos una división de entrenamiento/validación/prueba 80/10/10.

Pondremos cada conjunto de datos en su propia tabla en BigQuery. El primer paso es crear un “conjunto de datos” de BigQuery , que es un contenedor de tablas relacionadas. Con tu proyecto seleccionado, selecciona Crear conjunto de datos.

1084d9f5edbf760b.png

Luego, crea un conjunto de datos llamado tfe_codelab para que contenga las tablas de entrenamiento, validación y prueba.

e5b8646ebdf5f272.png

Ahora, ejecutaremos 3 consultas de entrenamiento, prueba y validación, y guardaremos los datos en el nuevo conjunto de datos tfe_codelab.

En el Editor de consultas, ejecuta una consulta para generar los datos de entrenamiento:

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) < 8

Una vez completada la consulta, guarda los resultados en una tabla de BigQuery.

49d20c9b4b62f6a7.png

En el conjunto de datos tfe_codelab que acabas de crear, asigna el nombre ulb_fraud_detection_train a la tabla y guarda los datos.

6d83cf113a0682e1.png

La cláusula WHERE primero divide los datos mediante el cálculo de un hash en un par de columnas. Luego, selecciona filas en las que el resto del hash, cuando se divide por 10, es inferior a 80, lo que nos da un 80%.

Ahora vamos a repetir el mismo proceso para los conjuntos de validación y prueba con consultas similares que seleccionan un 10% de los datos cada uno.

Validación

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) = 8

Guarda los resultados de esta consulta en una tabla llamada ulb_fraud_detection_val.

Prueba

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) = 9

Guarda los resultados de esta consulta en una tabla llamada ulb_fraud_detection_test.

3. Configura tu entorno de notebook

Ahora que ya hicimos una breve introducción a los datos, configuremos el entorno de desarrollo del modelo.

Paso 1: Habilitar las API

El conector de BigQuery usa la API de almacenamiento de BigQuery. Busca la API de BigQuery Storage en la consola y habilítala si está inhabilitada actualmente.

9895a2fd3cdf8f8c.png

Paso 2: 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 TensorFlow Enterprise 1.x without GPUs:

35301141e9fd3f44.png

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

3b801f8ff3db0f2f.png

Luego, crea un notebook de Python 3 desde JupyterLab:

58523671a252b95a.png

4. Transfiere registros desde BigQuery

Paso 1: 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 tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers

from tensorflow_io.bigquery import BigQueryClient

import functools

tf.enable_eager_execution()

Paso 2: Define las constantes

A continuación, definamos algunas constantes para usar en el proyecto. Cambia GCP_PROJECT_ID por el ID del proyecto real que estás usando. Ejecuta las celdas nuevas a medida que las creas.

GCP_PROJECT_ID = '<YOUR_PROJECT_ID>'
DATASET_GCP_PROJECT_ID = GCP_PROJECT_ID # A copy of the data is saved in the user project
DATASET_ID = 'tfe_codelab'
TRAIN_TABLE_ID = 'ulb_fraud_detection_train'
VAL_TABLE_ID = 'ulb_fraud_detection_val'
TEST_TABLE_ID = 'ulb_fraud_detection_test'

FEATURES = ['Time','V1','V2','V3','V4','V5','V6','V7','V8','V9','V10','V11','V12','V13','V14','V15','V16','V17','V18','V19','V20','V21','V22','V23','V24','V25','V26','V27','V28','Amount']
LABEL='Class'
DTYPES=[tf.float64] * len(FEATURES) + [tf.int64]

Paso 3: Define las funciones auxiliares

Ahora, definamos algunas funciones. read_session() lee los datos de una tabla de BigQuery. extract_labels() es una función auxiliar para separar la columna de etiquetas del resto, de modo que el conjunto de datos tenga el formato que espera keras.model_fit() más adelante.

client = BigQueryClient()

def read_session(TABLE_ID):
    return client.read_session(
        "projects/" + GCP_PROJECT_ID, DATASET_GCP_PROJECT_ID, TABLE_ID, DATASET_ID,
        FEATURES + [LABEL], DTYPES, requested_streams=2
)

def extract_labels(input_dict):
  features = dict(input_dict)
  label = tf.cast(features.pop(LABEL), tf.float64)
  return (features, label)

Paso 4: Transfiere datos

Por último, crearemos cada conjunto de datos y, luego, imprimiremos el primer lote del conjunto de datos de entrenamiento. Ten en cuenta que definimos un BATCH_SIZE de 32. Este es un parámetro importante que afectará la velocidad y exactitud del entrenamiento.

BATCH_SIZE = 32

raw_train_data = read_session(TRAIN_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)
raw_val_data = read_session(VAL_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)
raw_test_data = read_session(TEST_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)

next(iter(raw_train_data)) # Print first batch

5. Compilar el modelo

Paso 1: Preprocesa los datos

Creemos columnas de atributos para cada atributo del conjunto de datos. En este conjunto de datos en particular, todas las columnas son del tipo numeric_column, pero hay varios otros tipos de columnas (p.ej., columna_categórica).

Como vimos anteriormente, también normalizaremos los datos para que se centren alrededor de cero a fin de que la red converja más rápido. Ya calculamos previamente las medias de cada atributo que se usarán en este cálculo.

MEANS = [94816.7387536405, 0.0011219465482001268, -0.0021445914636999603, -0.002317402958335562,
         -0.002525792169927835, -0.002136576923287782, -3.7586818983702984, 8.135919975738768E-4,
         -0.0015535579268265718, 0.001436137140461279, -0.0012193712736681508, -4.5364970422902533E-4,
         -4.6175444671576083E-4, 9.92177789685366E-4, 0.002366229151475428, 6.710217226762278E-4,
         0.0010325807119864225, 2.557260815835395E-4, -2.0804190062322664E-4, -5.057391100818653E-4,
         -3.452114767842334E-6, 1.0145936326270006E-4, 3.839214074518535E-4, 2.2061197469126577E-4,
         -1.5601580596677608E-4, -8.235017846415852E-4, -7.298316615408554E-4, -6.898459943652376E-5,
         4.724125688297753E-5, 88.73235686453587]

def norm_data(mean, data):
  data = tf.cast(data, tf.float32) * 1/(2*mean)
  return tf.reshape(data, [-1, 1])

numeric_columns = []

for i, feature in enumerate(FEATURES):
  num_col = tf.feature_column.numeric_column(feature, normalizer_fn=functools.partial(norm_data, MEANS[i]))
  numeric_columns.append(num_col)

numeric_columns

Paso 2: Compila el modelo

Ya está todo listo para crear un modelo. Enviaremos las columnas que acabamos de crear a la red. Luego, compilaremos el modelo. Incluimos la métrica de AUC de precisión/recuperación, que es útil para los conjuntos de datos desequilibrados.

model = keras.Sequential([
    tf.keras.layers.DenseFeatures(numeric_columns),
    layers.Dense(64, activation='relu'),
    layers.Dense(64, activation='relu'),
    layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy', tf.keras.metrics.AUC(curve='PR')])

Paso 3: Entrena el modelo

Hay una serie de técnicas para manejar datos desequilibrados, incluido el sobremuestreo (generación de datos nuevos en la clase minoritaria) y el submuestreo (reducción de los datos en la clase mayoritaria).

Para los fines de este codelab, usaremos una técnica que sobrepondera la pérdida cuando se clasifica de forma errónea la clase minoritaria. Especificaremos un parámetro class_weight cuando entrenes y uses el peso "1" (fraude) más alta, ya que es mucho menos frecuente.

Usaremos 3 ciclos de entrenamiento (pasa a través de los datos) en este lab, por lo que el entrenamiento es más rápido. En una situación real, deberíamos ejecutarlo el tiempo suficiente hasta que dejes de ver aumentos en la precisión del conjunto de validación.

CLASS_WEIGHT = {
    0: 1,
    1: 100
}
EPOCHS = 3

train_data = raw_train_data.shuffle(10000)
val_data = raw_val_data
test_data = raw_test_data

model.fit(train_data, validation_data=val_data, class_weight=CLASS_WEIGHT, epochs=EPOCHS)

Paso 4: Evaluar el modelo

La función evaluate() se puede aplicar a datos de prueba que el modelo nunca vio para proporcionar una evaluación objetiva. Afortunadamente, reservamos datos de prueba solo para eso.

model.evaluate(test_data)

Paso 5: Exploración

En este lab, demostramos cómo transferir un gran conjunto de datos de BigQuery directamente a un modelo de Keras de TensorFlow. También recorrimos todos los pasos para crear un modelo. Por último, aprendimos un poco sobre cómo manejar los problemas de clasificación desequilibrados.

Siéntete libre de seguir jugando con las diferentes arquitecturas y enfoques del conjunto de datos desequilibrados para ver si puedes mejorar la exactitud.

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

57213ef2edad9257.png

Si quieres borrar todos los recursos que creaste en este lab, solo debes borrar 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.