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 fraudes 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édez à l'ensemble de données public BigQuery

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

Dans l'arborescence des ressources dans le coin inférieur gauche, vous verrez une liste de jeux de données. Parcourez les ensembles de données disponibles jusqu'à trouver ml-datasets, puis sélectionnez la table ulb-fraud-detection qu'il contient:

d5e78261514a90ef.png

Cliquez sur chaque onglet pour en savoir plus sur le jeu 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 frauduleuses.
  • L'onglet Aperçu affiche les enregistrements de l'ensemble de données.

Étape 2: Interroger la table

L'onglet "Details" (Détails) nous fournit les informations suivantes à propos des données:

  • Le temps correspond au nombre de secondes entre la première transaction de l'ensemble de données et l'heure de la transaction sélectionnée.
  • Les colonnes V1-V28 ont été transformées à l'aide d'une technique de réduction de la dimensionnalité appelée PCA, qui a anonymisé les données.
  • Le montant correspond au montant de la transaction.

Examinons de plus près la requête en cliquant sur Exécuter une requête sur la table:

581e596426a98383.png

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

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

Étape 3: Analysez les données

BigQuery fournit un certain nombre de fonctions statistiques. Examinons la corrélation entre les données et 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 comprise entre -1 (corrélée négativement) et 1 (corrélée positivement), 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 n'observons pas beaucoup de corrélation avec le temps. Une corrélation légèrement négative peut indiquer qu'il y a moins de transactions frauduleuses au fil du temps dans l'ensemble de données.

La corrélation avec le montant est même plus faible, ce qui indique que les transactions frauduleuses sont très légèrement plus susceptibles d'être associées à des montants de transactions plus élevés.

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

La normalisation des valeurs des caractéristiques peut accélérer la convergence d'un réseau de neurones. Un schéma courant consiste à centrer les valeurs autour de 0 avec un écart type de 1. La requête suivante récupérera 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 le décrirons dans la section suivante, lorsque nous verrons comment diviser 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: Répartir les données

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

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

Dans cet atelier de programmation, nous allons utiliser une répartition entraînement/validation/test de 80/10/10.

Nous allons placer chaque ensemble de données dans sa propre table dans 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é, choisissez Créer un ensemble de données.

1084d9f5edbf760b.png

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

e5b8646ebdf5f272.png

Nous allons maintenant exécuter trois requêtes d'entraînement, de test et de validation, puis 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

Lorsque la requête est 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 quelques colonnes. Ensuite, il sélectionne les lignes où le reste du hachage lorsqu’il est divisé par 10 est inférieur à 80, ce qui nous donne 80%.

Répétez maintenant le même processus pour les ensembles de validation et de test avec des requêtes similaires qui sélectionnent chacun 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 appelé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 de notebook

Maintenant que nous avons passé en revue une brève présentation des données, configurons l'environnement de développement du 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 à partir de BigQuery

Étape 1: Importez les packages Python

Dans la première cellule de votre notebook, ajoutez les importations suivantes et exécutez la cellule. Vous pouvez l'exécuter en appuyant sur la flèche vers la droite dans le menu supérieur ou en appuyant sur Commande+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 de projet que vous utilisez. Exécutez les nouvelles cellules à 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 les fonctions des assistants

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 d'étiquette du reste afin que l'ensemble de données soit au format attendu par keras.model_fit() ultérieurement.

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érez les données

Pour finir, nous allons créer chaque ensemble de données, puis imprimer le premier lot à partir de l'ensemble de données d'entraînement. Notez que nous avons défini une valeur 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 particulier, toutes les colonnes sont de type numeric_column, mais il existe un certain nombre 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é la moyenne 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 alimenter le réseau avec les colonnes que nous venons de créer. 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 un certain nombre de 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, nous allons utiliser une technique qui surpondère la perte en cas de classification erronée de la classe minoritaire. Nous spécifierons un paramètre class_weight lors de l'entraînement et une pondération "1" (fraude) plus élevée, car elle est beaucoup moins répandue.

Dans cet atelier, nous allons utiliser trois époques (passe par les données) pour que l'entraînement soit plus rapide. Dans un scénario réel, il faudrait l'exécuter suffisamment longtemps jusqu'à ce que l'arrêt de l'affichage augmente la précision de l'ensemble de validation.

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 afin de fournir une évaluation objective. Heureusement, nous avons réservé des données de test à cet effet.

model.evaluate(test_data)

Étape 5: Exploration

Dans cet atelier, nous avons appris à ingérer un grand ensemble de données de 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 avec déséquilibre.

N'hésitez pas à continuer à jouer avec différentes architectures et approches de l'ensemble de données déséquilibré pour voir si vous pouvez améliorer la justesse.

6. Nettoyage

Si vous souhaitez continuer à utiliser cet ordinateur portable, nous vous recommandons de le désactiver lorsqu'il n'est pas utilisé. À partir de l'interface utilisateur de Notebooks dans Cloud Console, sélectionnez le notebook, puis 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 Cloud Console, accédez à "Storage" (Stockage) et supprimez les deux buckets que vous avez créés pour stocker les ressources de votre modèle.