Créer un modèle de détection de fraudes sur Cloud AI Platform à l'aide de TensorFlow Enterprise et de BigQuery

1. Présentation

Dans cet atelier, vous allez ingérer directement un ensemble de données BigQuery et entraîner un modèle de détection de fraude avec TensorFlow Enterprise sur Google Cloud AI Platform.

Objectifs de l'atelier

Vous allez apprendre à effectuer les opérations suivantes :

  • Analyser des données dans BigQuery
  • Ingérer des données à l'aide du connecteur BigQuery dans TensorFlow Enterprise
  • Créer un modèle de deep learning pour détecter les fraudes avec un ensemble de données déséquilibré

2. Analyser les données dans BigQuery

Pour suivre cet atelier de programmation, vous aurez besoin d'un projet Google Cloud Platform dans lequel la facturation est activée. Pour créer un projet, suivez ces instructions.

Étape 1 : Accéder à l'ensemble de données public BigQuery

Suivez ce lien pour accéder aux ensembles de données publics BigQuery dans la console Google Cloud.

Dans l'arborescence des ressources en bas à gauche, vous verrez une liste d'ensembles de données. Parcourez les ensembles de données disponibles jusqu'à trouver ml-datasets, puis sélectionnez la table ulb-fraud-detection :

d5e78261514a90ef.png

Cliquez sur chaque onglet pour en savoir plus sur l'ensemble de données :

  • L'onglet Schéma décrit les types de données.
  • L'onglet Détails explique qu'il s'agit d'un ensemble de données déséquilibré avec 284 407 transactions, dont 492 sont frauduleuses.
  • L'onglet Aperçu affiche les enregistrements du jeu de données.

Étape 2 : Interrogez le tableau

L'onglet "Détails" nous indique les informations suivantes sur les données :

  • Heure : nombre de secondes entre la première transaction de l'ensemble de données et l'heure de la transaction sélectionnée.
  • V1 à V28 sont des colonnes qui ont été transformées à l'aide d'une technique de réduction de la dimensionnalité appelée PCA, qui a anonymisé les données.
  • Amount (Montant) correspond au montant de la transaction.

Pour en savoir plus, cliquez sur Interroger la table pour exécuter une requête :

581e596426a98383.png

Modifiez l'instruction pour ajouter un astérisque (*) afin d'afficher toutes les colonnes, puis cliquez sur Exécuter.

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

Étape 3 : Analysez les données

BigQuery propose un certain nombre de fonctions statistiques. Voyons comment les données sont corrélées à la variable cible 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 corrélation fournit une plage allant de -1 (corrélation négative) à 1 (corrélation positive), 0 étant indépendant.

Notez que V1 et V2 présentent une légère corrélation avec notre variable cible (environ -0,1 et 0,1 respectivement).

Nous ne constatons pas de corrélation forte avec Heure. Une corrélation légèrement négative peut indiquer que le nombre de transactions frauduleuses diminue au fil du temps dans l'ensemble de données.

Amount présente une corrélation encore plus faible, ce qui indique que les transactions frauduleuses sont très légèrement plus probables pour les montants de transaction plus élevés.

Étape 4 : Calculez les valeurs moyennes pour la mise à l'échelle des caractéristiques

La normalisation des valeurs des caractéristiques peut aider un réseau de neurones à converger plus rapidement. Un schéma courant consiste à centrer les valeurs autour de 0 avec un écart-type de 1. La requête suivante récupère les valeurs moyennes. Il n'est pas nécessaire d'enregistrer le résultat, car nous aurons un extrait de code pour cela plus tard.

Vous remarquerez également que la requête inclut une clause WHERE intéressante. Nous aborderons ce point dans la section suivante, lorsque nous verrons comment répartir les données entre les ensembles d'entraînement et de 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

Étape 5 : Fractionner les données

Il est courant d'utiliser trois ensembles de données lors de la création d'un modèle de machine learning :

  • Entraînement : utilisé pour créer le modèle en ajustant les paramètres de manière itérative
  • Validation : utilisée pour évaluer si le modèle est en surapprentissage en vérifiant les données indépendantes pendant le processus d'entraînement.
  • Test : utilisé après la création du modèle pour évaluer la précision

Dans cet atelier de programmation, nous utiliserons une répartition 80/10/10 pour l'entraînement, la validation et le test.

Nous placerons chaque ensemble de données dans sa propre table BigQuery. La première étape consiste à créer un "ensemble de données" BigQuery, qui est un conteneur pour les tables associées. Une fois votre projet sélectionné, cliquez sur Créer un ensemble de données.

1084d9f5edbf760b.png

Créez ensuite un ensemble de données appelé tfe_codelab pour contenir les tables d'entraînement, de validation et de test.

e5b8646ebdf5f272.png

Nous allons maintenant exécuter trois requêtes pour l'entraînement, le test et la validation, et enregistrer les données dans le nouvel ensemble de données tfe_codelab.

Dans l'éditeur de requête, exécutez une requête pour générer les données d'entraînement :

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

Une fois la requête terminée, enregistrez les résultats dans une table BigQuery.

49d20c9b4b62f6a7.png

Dans l'ensemble de données tfe_codelab que vous venez de créer, nommez la table ulb_fraud_detection_train et enregistrez les données.

6d83cf113a0682e1.png

La clause WHERE divise d'abord les données en calculant un hachage sur plusieurs colonnes. Il sélectionne ensuite les lignes dont le reste du hachage divisé par 10 est inférieur à 80, ce qui nous donne 80 %.

Répétons maintenant le même processus pour les ensembles de validation et de test avec des requêtes similaires qui sélectionnent chacune 10 % des données.

Validation

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

Enregistrez les résultats de cette requête dans une table nommée ulb_fraud_detection_val.

Tester

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

Enregistrez les résultats de cette requête dans une table appelée ulb_fraud_detection_test.

3. Configurer votre environnement Notebook

Maintenant que nous avons brièvement présenté les données, configurons notre environnement de développement de modèle.

Étape 1 : Activez les API

Le connecteur BigQuery utilise l'API BigQuery Storage. Recherchez l'API BigQuery Storage dans la console et activez-la si elle est actuellement désactivée.

9895a2fd3cdf8f8c.png

Étape 2 : Créez une instance AI Platform Notebooks.

Accédez à la section AI Platform Notebooks de la console Cloud, puis cliquez sur Nouvelle instance. Sélectionnez ensuite le dernier type d'instance TensorFlow Enterprise 1.x sans GPU :

35301141e9fd3f44.png

Utilisez les options par défaut, puis cliquez sur Créer. Une fois l'instance créée, sélectionnez Ouvrir JupyterLab :

3b801f8ff3db0f2f.png

Créez ensuite un notebook Python 3 à partir de JupyterLab :

58523671a252b95a.png

4. Ingérer des enregistrements depuis BigQuery

Étape 1 : Importez les packages Python

Dans la première cellule de votre notebook, ajoutez les importations suivantes et exécutez la cellule. Pour l'exécuter, appuyez sur le bouton en forme de flèche vers la droite dans le menu du haut ou appuyez sur Cmd+Entrée :

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

Étape 2 : Définissez les constantes

Définissons ensuite quelques constantes à utiliser dans le projet. Remplacez GCP_PROJECT_ID par l'ID du projet que vous utilisez réellement. N'hésitez pas à exécuter les nouvelles cellules au fur et à mesure que vous les créez.

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]

Étape 3 : Définissez des fonctions d'assistance

Définissons maintenant quelques fonctions. read_session() lit les données d'une table BigQuery. extract_labels() est une fonction d'assistance qui permet de séparer la colonne des libellés du reste, afin que l'ensemble de données soit au format attendu par keras.model_fit() par la suite.

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)

Étape 4 : Ingérer les données

Enfin, créons chaque ensemble de données, puis imprimons le premier lot de l'ensemble de données d'entraînement. Notez que nous avons défini une BATCH_SIZE de 32. Il s'agit d'un paramètre important qui aura un impact sur la vitesse et la précision de l'entraînement.

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. Créer un modèle

Étape 1 : Prétraiter les données

Créons des colonnes de caractéristiques pour chaque caractéristique de l'ensemble de données. Dans cet ensemble de données, toutes les colonnes sont de type numeric_column, mais il existe d'autres types de colonnes (par exemple, categorical_column).

Comme nous l'avons vu précédemment, nous allons également normaliser les données pour qu'elles soient centrées autour de zéro, afin que le réseau converge plus rapidement. Nous avons précalculé les moyennes de chaque caractéristique à utiliser dans ce calcul.

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

Étape 2 : Créer le modèle

Nous sommes maintenant prêts à créer un modèle. Nous allons insérer les colonnes que nous venons de créer dans le réseau. Nous allons ensuite compiler le modèle. Nous incluons la métrique AUC de précision/rappel, qui est utile pour les ensembles de données déséquilibrés.

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

Étape 3 : Entraîner le modèle

Il existe plusieurs techniques pour gérer les données déséquilibrées, y compris le suréchantillonnage (génération de nouvelles données dans la classe minoritaire) et le sous-échantillonnage (réduction des données dans la classe majoritaire).

Pour les besoins de cet atelier de programmation, utilisons une technique qui surpondère la perte en cas de classification incorrecte de la classe minoritaire. Nous spécifierons un paramètre class_weight lors de l'entraînement et attribuerons un poids de "1" (fraude) plus élevé, car il est beaucoup moins répandu.

Dans cet atelier, nous utiliserons trois époques (passages dans les données) pour accélérer l'entraînement. Dans un scénario réel, nous souhaiterions l'exécuter suffisamment longtemps pour que la précision de l'ensemble de validation cesse d'augmenter.

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)

Étape 4 : Évaluer le modèle

La fonction evaluate() peut être appliquée à des données de test que le modèle n'a jamais vues pour fournir une évaluation objective. Heureusement, nous avons mis de côté des données de test pour cela.

model.evaluate(test_data)

Étape 5 : Exploration

Dans cet atelier, nous vous avons montré comment ingérer un grand ensemble de données depuis BigQuery directement dans un modèle TensorFlow Keras. Nous avons également passé en revue toutes les étapes de la création d'un modèle. Enfin, nous avons appris à gérer les problèmes de classification déséquilibrée.

N'hésitez pas à continuer à tester différentes architectures et approches pour l'ensemble de données déséquilibré, afin de voir si vous pouvez améliorer la précision.

6. Nettoyage

Si vous souhaitez continuer à utiliser ce notebook, nous vous recommandons de le désactiver quand vous ne vous en servez pas. À partir de l'interface utilisateur de Notebooks dans la console Cloud, sélectionnez le notebook et cliquez sur Arrêter :

57213ef2edad9257.png

Si vous souhaitez supprimer toutes les ressources que vous avez créées dans cet atelier, il vous suffit de supprimer l'instance de notebook au lieu de l'arrêter.

À l'aide du menu de navigation de la console Cloud, accédez à "Stockage" et supprimez les deux buckets que vous avez créés pour stocker les composants de votre modèle.