Crea un modello di rilevamento delle frodi su Cloud AI Platform con TensorFlow Enterprise e BigQuery

1. Panoramica

In questo lab importerai direttamente un set di dati BigQuery e addestrerai un modello di rilevamento delle frodi con TensorFlow Enterprise su Google Cloud AI Platform.

Cosa imparerai

Al termine del corso sarai in grado di:

  • Analizza i dati su BigQuery
  • Importa i dati utilizzando il connettore BigQuery in TensorFlow Enterprise
  • Crea un modello di deep learning per rilevare le frodi con un set di dati sbilanciato

2. Analizza i dati in BigQuery

Per eseguire questo codelab, è necessario un progetto Google Cloud con fatturazione abilitata. Per creare un progetto, segui le istruzioni riportate qui.

Passaggio 1: accedi al set di dati pubblico BigQuery

Segui questo link per accedere ai set di dati pubblici di BigQuery nella console Google Cloud.

Nell'albero delle risorse, nell'angolo in basso a sinistra, vedrai un elenco di set di dati. Naviga tra i set di dati disponibili finché non trovi ml-datasets, quindi seleziona la tabella ulb-fraud-detection al suo interno:

d5e78261514a90ef.png

Fai clic sulle singole schede per scoprire di più sul set di dati:

  • Nella scheda Schema sono descritti i tipi di dati.
  • La scheda Dettagli spiega che si tratta di un set di dati non bilanciato con 284.407 transazioni, di cui 492 sono fraudolente.
  • La scheda Anteprima mostra i record del set di dati.

Passaggio 2: esegui una query sulla tabella

La scheda Dettagli indica queste informazioni sui dati:

  • Tempo equivale al numero di secondi tra la prima transazione nel set di dati e l'ora della transazione selezionata.
  • Le colonne V1-V28 sono state trasformate tramite una tecnica di riduzione della dimensionalità denominata PCA che ha anonimizzato i dati.
  • Importo indica l'importo della transazione.

Osserviamo più da vicino facendo clic su Tabella delle query per eseguire una query:

581e596426a98383.png

Aggiorna l'istruzione per aggiungere un asterisco (*) per visualizzare tutte le colonne e fai clic su Esegui.

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

Passaggio 3: analizza i dati

BigQuery offre una serie di funzioni statistiche. Diamo un'occhiata alla correlazione tra i dati e la variabile target 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 correlazione fornirà un intervallo da -1 (correlazione negativa) a 1 (correlata positivamente), dove 0 è indipendente.

Tieni presente che V1 e V2 hanno una leggera correlazione con la nostra variabile target (rispettivamente -0,1 e 0,1 circa).

Non vediamo molta correlazione con il valore Time. Una correlazione leggermente negativa potrebbe indicare la diminuzione del numero di transazioni fraudolente nel tempo nel set di dati.

Importo ha una correlazione anche più bassa, il che indica che le transazioni fraudolente sono leggermente più probabili con transazioni di importo più elevato.

Passaggio 4: calcola i valori medi per la scalabilità delle caratteristiche

La normalizzazione dei valori delle caratteristiche può aiutare una rete neurale a convergere più velocemente. Uno schema comune consiste nel centrare i valori attorno a 0 con una deviazione standard di 1. La seguente query recupererà i valori medi. Non è necessario salvare il risultato, perché in seguito avremo uno snippet di codice per questo scopo.

Noterai anche che la query include una clausola WHERE interessante. Lo spiegheremo nella prossima sezione, in cui spiegheremo come suddividere i dati tra set di addestramento e set di test.

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

Passaggio 5: suddivisione dei dati

Quando si crea un modello di machine learning, è pratica comune utilizzare tre set di dati:

  • Addestramento: utilizzato per creare il modello regolando iterativamente i parametri
  • Convalida: utilizzata per valutare se il modello è in overfitting verificando su dati indipendenti durante il processo di addestramento.
  • Test: utilizzato dopo la creazione del modello per valutare l'accuratezza

In questo codelab, utilizzeremo una suddivisione 80/10/10 per addestramento/convalida/test.

Inseriremo ogni set di dati nella rispettiva tabella in BigQuery. Il primo passaggio consiste nel creare un "set di dati" BigQuery - che è un contenitore per le tabelle correlate. Con il progetto selezionato, seleziona Crea set di dati.

1084d9f5edbf760b.png

Quindi, crea un set di dati denominato tfe_codelab che contenga le tabelle di addestramento, convalida e test.

e5b8646ebdf5f272.png

Ora eseguiremo 3 query per addestramento, test e convalida e salveremo i dati nel nuovo set di dati tfe_codelab.

Nell'editor di query, esegui una query per generare i dati di addestramento:

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

Al termine della query, salva i risultati in una tabella BigQuery.

49d20c9b4b62f6a7.png

All'interno del set di dati tfe_codelab appena creato, assegna alla tabella il nome ulb_fraud_detection_train e salva i dati.

6d83cf113a0682e1.png

La clausola WHERE divide i dati innanzitutto calcolando un hash su un paio di colonne. Poi seleziona le righe in cui il resto dell'hash, diviso per 10, è inferiore a 80, ottenendo l'80%.

Ripetiamo la stessa procedura per i set di convalida e di test con query simili che selezionano il 10% dei dati ciascuno.

Convalida

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

Salva i risultati di questa query in una tabella denominata ulb_fraud_detection_val.

Prova

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

Salva i risultati di questa query in una tabella denominata ulb_fraud_detection_test.

3. configura l'ambiente del blocco note

Dopo aver seguito una breve introduzione ai dati, impostiamo l'ambiente di sviluppo del modello.

Passaggio 1: abilita le API

Il connettore BigQuery utilizza l'API BigQuery Storage. Cerca l'API BigQuery Storage nella console e abilita l'API se è attualmente disabilitata.

9895a2fd3cdf8f8c.png

Passaggio 2: 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 TensorFlow Enterprise 1.x più recente senza GPU:

35301141e9fd3f44.png

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

3b801f8ff3db0f2f.png

Quindi, crea un blocco note Python 3 da JupyterLab:

58523671a252b95a.png

4. Importa record da BigQuery

Passaggio 1: 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 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()

Passaggio 2: definisci le costanti

Definiamo poi alcune costanti da utilizzare nel progetto. Sostituisci GCP_PROJECT_ID con l'ID progetto effettivo che stai utilizzando. Esegui nuove celle mentre le crei.

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]

Passaggio 3: definisci le funzioni helper

Ora definiamo un paio di funzioni. read_session() legge i dati da una tabella BigQuery. extract_labels() è una funzione helper per separare la colonna dell'etichetta dal resto, in modo che il set di dati sia nel formato previsto da keras.model_fit() in seguito.

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)

Passaggio 4: importa i dati

Infine, creiamo ciascun set di dati e quindi stampiamo il primo batch dal set di dati di addestramento. Tieni presente che abbiamo definito un valore BATCH_SIZE pari a 32. Si tratta di un parametro importante che influirà sulla velocità e sulla precisione dell'addestramento.

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. Crea il modello

Passaggio 1: pre-elabora i dati

Creiamo colonne di caratteristiche per ogni caratteristica nel set di dati. In questo particolare set di dati, tutte le colonne sono di tipo colonna_numerica, ma ne esistono altri (ad es. colonna_categorica).

Come abbiamo già detto, regoleremo anche i dati in modo che siano centrati sullo zero, in modo che la rete converga più velocemente. Abbiamo precalcolato le medie di ciascuna funzionalità da utilizzare in questo calcolo.

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

Passaggio 2: crea il modello

Ora siamo pronti per creare un modello. Le colonne appena create verranno inserite nella rete. Quindi compileremo il modello. Abbiamo incluso la metrica AUC precisione/richiamo, che è utile per i set di dati sbilanciati.

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')])

Passaggio 3: addestra il modello

Esistono varie tecniche per gestire i dati non bilanciati, tra cui il sovracampionamento (generazione di nuovi dati nella classe delle minoranze) e il sottocampionamento (riduzione dei dati nella classe di maggioranza).

Ai fini di questo codelab, utilizziamo una tecnica che sovradimensiona la perdita quando si classifica in modo errato la classe di minoranza. Specificheremo un parametro class_weight durante l'addestramento e il peso "1". (attività fraudolenta) più elevata, in quanto molto meno diffusa.

In questo lab utilizzeremo 3 epoche (passa i dati) per velocizzare l'addestramento. In uno scenario reale, vorremmo eseguirlo abbastanza a lungo fino al punto in cui non si veda più un aumento dell'accuratezza del set di convalida.

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)

Passaggio 4: valuta il modello

La funzione evaluate() può essere applicata per testare dati che il modello non ha mai rilevato per fornire una valutazione oggettiva. Fortunatamente, abbiamo riservato i dati di test proprio per questo.

model.evaluate(test_data)

Passaggio 5: esplorazione

In questo lab, abbiamo dimostrato come importare un grande set di dati da BigQuery direttamente in un modello TensorFlow Keras. Abbiamo anche visto in dettaglio tutti i passaggi per la creazione di un modello. Infine, abbiamo imparato qualcosa su come gestire i problemi di classificazione sbilanciata.

Puoi continuare a sperimentare architetture e approcci diversi a un set di dati sbilanciato per vedere se riesci a migliorare l'accuratezza.

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

57213ef2edad9257.png

Per eliminare tutte le risorse create in questo lab, è sufficiente eliminare 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.