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

Qué aprenderá

Aprenderás a hacer lo siguiente:

  • Analiza datos en BigQuery
  • Transfiere datos con el conector de BigQuery en TensorFlow Enterprise
  • Crea 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, ubicado en 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 que se encuentra 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.
  • En la pestaña Vista previa, se muestran los registros del conjunto de datos.

Paso 2: Realiza consultas a la tabla

En la pestaña de detalles, se indica lo siguiente sobre los datos:

  • Tiempo es la cantidad de segundos entre la primera transacción en el conjunto de datos y el momento de la transacción seleccionada.
  • Las columnas V1 a V28 se transformaron a través de una técnica de reducción de dimensionalidad llamada PCA que anonimizó los datos.
  • Amount es el importe de la transacción.

Hagamos clic en Consultar tabla para ejecutar una consulta y analizarla con más detalle:

581e596426a98383.png

Actualiza la instrucción para agregar un asterisco (*) y 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 varias funciones estadísticas. Echemos un vistazo a cómo se correlacionan los datos con la variable objetivo Clase.

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 (correlación negativa) a 1 (correlación positiva), y 0 indica independencia.

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

No vemos mucha correlación con el tiempo. Una correlación ligeramente negativa podría indicarnos que hay menos transacciones fraudulentas con el tiempo en el conjunto de datos.

La variable Amount tiene una correlación aún más baja, lo que indica que las transacciones fraudulentas son muy ligeramente más probables en importes de transacción más altos.

Paso 4: Calcula los valores medios para el ajuste de la escala de los atributos

Normalizar los valores de los atributos puede ayudar a que una red neuronal converja más rápido. Un esquema común es 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. Describiremos ese proceso en la próxima sección, cuando expliquemos cómo dividir los datos entre los conjuntos de entrenamiento y 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 crear el modelo ajustando los parámetros de forma iterativa.
  • Validación: Se usa para evaluar si el modelo se sobreajusta. Para ello, se verifica con datos independientes durante el proceso de entrenamiento.
  • Prueba: Se usa después de crear el modelo para evaluar la precisión.

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

Colocaremos 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 para tablas relacionadas. Con tu proyecto seleccionado, elige 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 para el entrenamiento, la prueba y la 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

Cuando se complete 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

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

Ahora, repitamos el mismo proceso para los conjuntos de validación y prueba con consultas similares que seleccionen el 10% de los datos cada una.

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 vimos una breve introducción a los datos, configuremos nuestro entorno de desarrollo de modelos.

Paso 1: Habilitar las API

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

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 TensorFlow Enterprise 1.x más reciente sin GPUs:

35301141e9fd3f44.png

Usa las opciones predeterminadas y 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 del notebook, agrega las siguientes importaciones y ejecuta la celda. Para ejecutarlo, presiona el botón de flecha hacia la derecha en el menú superior o presiona Comando + 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 funciones de ayuda

Ahora, definamos algunas funciones. read_session() lee 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 los 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 la precisión 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 otros tipos de columnas (p.ej., categorical_column).

Como ya mencionamos, también normalizaremos los datos para que se centren en cero y la red converja más rápido. Precalculamos las medias de cada característica para usarlas 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

Ahora sí podemos crear un modelo. Alimentaremos la red con las columnas que acabamos de crear. Luego, compilaremos el modelo. Incluimos la métrica del 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

Existen varias técnicas para controlar los datos desequilibrados, como el sobremuestreo (generar datos nuevos en la clase minoritaria) y el submuestreo (reducir los datos en la clase mayoritaria).

Para los fines de este codelab, usemos una técnica que le dé más peso a la pérdida cuando se clasifica de forma incorrecta la clase minoritaria. Especificaremos un parámetro class_weight cuando entrenemos y ponderaremos "1" (fraude) más alto, ya que es mucho menos frecuente.

En este lab, usaremos 3 épocas (pasadas por los datos) para que el entrenamiento sea más rápido. En una situación real, nos gustaría ejecutarlo el tiempo suficiente hasta que dejemos 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 los 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 conjunto de datos grande de BigQuery directamente a un modelo de Keras de TensorFlow. También explicamos todos los pasos para crear un modelo. Por último, aprendimos un poco sobre cómo abordar los problemas de clasificación desequilibrada.

No dudes en seguir probando diferentes arquitecturas y enfoques para el conjunto de datos desequilibrado y ver si puedes mejorar la precisión.

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

57213ef2edad9257.png

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

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