Détection de fraudes
La détection de fraudes est un sujet courant dans plusieurs domaines : financier – banques, assurances, social ou judiciaire… Une fraude est un acte malhonnête fait dans l’intention de tromper en contrevenant à la loi ou aux règlements [1]. A titre d’illustration, l’article ne considère que la fraude à la carte bancaire. C’est la situation dans laquelle le détenteur de la carte constate sur son compte bancaire des débits dont il n’est pas à l’origine. Cette fraude a de lourdes conséquences à la fois sur les banques et leurs clients pour deux raisons :
- D’une part, les victimes sont nombreuses [2]. En France, 1,3 million de ménages possédant un compte bancaire déclarent avoir subit au moins un débit frauduleux en 2018, soit 4,3 % des ménages. Deux tiers d’entre eux s’aperçoivent la fraude en consultant leur relevé bancaire tandis que 64 % ignorent comment l’auteur a procédé. Le nombre de ménages victimes est en constante augmentation (1,3 million en 2018 contre 0,5 million en 2010).
- D’autre part, les volumes frauduleux sont considérables [3]. La fraude sur les transactions en 2018 s’élève à 439 millions d’euros (+13,4 % par rapport à 2017) sur le montant total de 704,4 milliards d’euros (5,9 % de plus que l’an précédent).
La détection de fraudes est un enjeu de taille malgré la petite fraction que représentent les fraudes parmi les transactions régulières, celles-ci pouvant causer d’importantes pertes d’agent et de confiance sans outils
adéquats pour les prévenir.
Autoencodeur Variationnel
L’outil traditionnel de détection de fraudes est d’appliquer les règles de gestion pour signaler les transactions frauduleuses. Cette approche paraît inflexible, devenant inefficace quand les fraudeurs réussissent à contourner les règles de gestion. Alternativement, les modèles de machine learning / deep learning peuvent être appliqués sur les données historiques, permettant de reconnaître les motifs des fraudes et de les repérer parmi les transactions futures.
En effet, la détection de fraudes est une tâche de classification, réalisée en deux phases :
- Entraînement : Le modèle est estimé à partir d’un jeu de données de transactions passées.
- Prédiction : Les nouvelles données sont soumises pour obtenir, grâce au modèle estimé, pour chaque transaction un label “frauduleuse” ou “normale”.
Les modèles d’apprentissage supervisé et non-supervisé peuvent servir à cette classification :
- Apprentissage supervisé : Le modèle apprend des transactions préalablement étiquetées en “frauduleuse” ou “normale”. Ses paramètres sont ajustés de façon à minimiser l’écart entre les labels résultants et initiaux. Néanmoins, la qualité du modèle peut être nuancée pour deux raisons : d’un côté, l’étiquetage des échantillons n’est pas complètement sûr et de l’autre côté, les données sont souvent déséquilibrées où les fraudes restent marginales envers les transactions normales.
- Apprentissage non-supervisé : La labellisation de données n’est plus nécessaire. Le modèle identifie les fraudes, étant différentes des transactions régulières, comme des anomalies.
L’article décrit par la suite le réseau de neurones artificiels autoencodeur [4]. Ce dernier détecte les fraudes comme des anomalies parmi les transactions dans le cadre de l’apprentissage non-supervisé.
Figure 1. Schéma d’un autoencodeur
Fig. 1 dessine une configuration simple d’un autoencodeur dit vanille avec trois parties : encodeur, espace latent et décodeur. L’encodeur produit d’abord une représentation compacte dans l’espace latent de dimension réduite (z) à partir de l’entrée x (Eq. 1); ces informations stockées en z sont ensuite utilisées pour générer la sortie x’ (Eq. 2).
(1)
(2)
L’objectif de l’autoencodeur est d’obtenir la sortie x’ identique à l’entrée x. L’optimisation du modèle est donc la recherche des paramètres des fonctions E et D pour minimiser l’écart entre x et x’, d’où la fonction de coût de reconstruction (Eq. 3).
(3)
De cette façon, l’autoencodeur vanille permet de minimiser les erreurs de la reconstruction (la sortie x’ devrait être identique à l’entrée x). Il est ainsi capable d’identifier les comportements anormaux grâce aux leurs importantes erreurs de reconstruction.
Il y a pourtant le souci de sur-apprentissage pour l’architecture dans Fig. 1. En effet, quand la fonction de coût Lrec (Eq. 3) tend vers zéro pendant l’entraînement de l’autoencoder, ce dernier apprend par cœur les données d’entrée, ne faisant que la copie de x dans x’.
Figure 2. Schéma d’un autoencodeur variationnel
L’autoencodeur variationnel (Fig. 2) offre la solution pour remédier ce problématique. L’espace latent z n’est plus décrit par un vecteur fixe. Au contraire, chaque dimension d de z est représentée par une distribution normale N(μd, σd2). Autrement dit, la représentation compacte z n’est plus discrète mais devient continue avec ces distributions, permettant la génération du modèle sur le jeu de données.
Remarquez que deux couches supplémentaires sont ajoutées pour apprendre les paramètres des distributions normales, la première pour la moyenne μ et la deuxième pour la variance σ (Fig. 2). Ainsi, pour chaque l’entrée x, ces couches supplémentaires d’abord donnent μ et σ. Un échantillonnage aléatoire à partir de N(0, 1) est fait pour chaque dimension d de l’espace latent, résultant en ϵd. La représentation compacte z est déduite par (Eq. 4) où ⊙ le produit matriciel de Hadamard.
(4)
En outre, la fonction de coût (Eq. 5) reflète l’objectif double de l’autoencodeur variationnel : de minimiser les erreurs de la reconstruction (la sortie x’ devrait être identique à l’entrée x) et d’imposer les distributions normales représentant l’espace latent (la moyenne μ devrait être 0 et la variance 1). La fonction Lkl est le terme de divergence de Kullback-Leibler, souvent utilisée pour la comparaison entre deux distributions.
(5)
La fonction de coût Lkl paraît équivalente à une régularisation (Eq. 5), évitant le sur-apprentissage du modèle. Ainsi, l’autoencodeur variationnel permet à la fois la distinction des fraudes parmi des transactions normales et la génération du modèle sur le jeu de données.
Détection de fraudes par Autoencodeur Variationnel
L’autoencodeur variationnel est appliqué pour détecter les fraudes dans un jeu de données des transactions bancaires [5]. Celui-ci est organisé dans une table de trente colonnes (Fig. 3) dont vingt-neuf contiennent les renseignements anonymisés des transactions (“V1”, “V2”, … , “V28” et “Amount”) et une dernière les label (“Class”). Il y a au total 284 807 lignes dont 492 lignes labellisées 1 (“frauduleuse”) et 284 315 lignes labellisées 0 (“normale”). Le déséquilibre de données est extrêmement marqué par la minorité des fraudes (0,17 %) contre la majorité des transactions régulières (99,83 %). Ce jeux de données est divisé en trois sous-ensembles “Train”, “Valid” et “Test” selon le ratio 64 : 16 : 20.
Figure 3. Échantillons du jeux de données [5]
Les librairies spécifiques sont importées, le premier groupe concerne le post-traitement des données et des résultats et le deuxième l’entraînement de l’autoencodeur variationnel.
import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import roc_curve, auc, precision_recall_curve, confusion_matrix import matplotlib.pyplot as plt import seaborn as sns import itertools from keras import backend as K from keras.models import Model, load_model from keras.layers import Input, Dense, Lambda from keras.callbacks import ModelCheckpoint, TensorBoard
L’architecture miroir de l’autoencodeur variationnel (Fig. 2) se compose de l’encoder, la couche latente et le decoder avec 12, 6 et 12 neurones, respectivement. L’entrée du réseau ne contient que les colonnes caractéristiques car la colonne label n’est pas nécessaire.
def sampling(args): z_mean, z_log_var = args epsilon = K.random_normal(shape=K.shape(z_mean), mean=0., stddev=1.) return z_mean + K.exp(z_log_var / 2) * epsilon input_dim = X_train.shape[1] hidden_dim = 12 latent_dim = 6 x = Input(shape=(input_dim,)) encoder_hidden = Dense(hidden_dim, activation='tanh')(x) z_mean = Dense(latent_dim, name='z_mean')(encoder_hidden) z_log_var = Dense(latent_dim, name='z_log_var')(encoder_hidden) z = Lambda(sampling, name='z_sampled')([z_mean, z_log_var]) decoder_hidden = Dense(hidden_dim, activation='tanh')(z) xprime = Dense(input_dim)(decoder_hidden) def rec_loss(x_true, x_pred): return K.sum(K.square(x_true - x_pred), axis=-1) def kl_loss(x_true, x_pred): return - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1) def vae_loss(x_true, x_pred): rec_loss = K.sum(K.square(x_true - x_pred), axis=-1) kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1) return K.mean((rec_loss + kl_loss) / 2) vae = Model(x, xprime) vae.compile(optimizer='adam', loss=vae_loss, metrics=[rec_loss, kl_loss]) vae.summary()
L’entraînement de l’autoencodeur variationnel s’effectue grâce à l’optimiseur Adam et la fonction de coût dans (Eq. 5). Le modèle converge après 1000 itérations, les valeurs de la fonction de coût s’approchant pour “Train” et “Valid” (Fig. 4).
checkpointer = ModelCheckpoint(filepath="vae.h5", verbose=0, save_best_only=True) tensorboard = TensorBoard(log_dir='./logs', histogram_freq=0, write_graph=True, write_images=True) history = vae.fit(X_train, X_train, epochs=nb_epoch, batch_size=batch_size, shuffle=True, validation_data=(X_valid, X_valid), verbose=1, callbacks=[checkpointer, tensorboard]).history
Figure 4. La fonction de coût pour “Train” et “Valid”
Les erreurs de reconstruction sont définies comme la différence entre la sortie x’ de l’autoencodeur variationnel et l’entrée x. Il s’avère que les erreurs de reconstruction sont plus importantes pour les fraudes que pour les transactions normales. Un seuil sera donc fixé pour distinguer les comportements frauduleux des normaux (Fig. 5).
predict_valid = vae.predict(X_valid) mse = np.mean(np.power(X_valid - predict_valid, 2), axis=1) error_valid = pd.DataFrame({'reconstruction_error': mse, 'true_class': y_valid})
Figure 5. Erreur de reconstruction pour le sous-ensemble “Valid”
Le seuil est choisi pour avoir un bon compromis entre la précision et le rappel. Celui-ci peut être ajusté selon les paramètres définis par le métier. Supposons que le coût lié à chaque fraude est égal au volume de la transaction car la banque devrait le rembourser au client victime tandis que celui des transactions normales s’élève à 1 ‰ de la somme transférée, équivalent au frais de vérification. Le coût total est la somme cumulative de ces deux coûts. La courbe du coût total, tracée dans Fig. 6 en fonction du seuil des erreurs de reconstruction, atteint son minimum lorsque le seuil vaut 0,8.
Figure 6. Coûts de la détection de fraudes en fonction du seuil des erreurs de reconstruction
Quand le seuil est égal à 0,8, la matrice de confusion résultante (Fig. 7) montre que pour “Valid”, la plupart des fraudes (90,6%) sont détectées par l’autoencodeur tandis que 90,9% des transactions normales sont autorisées. En revanche, la technique se trompe sur 9,4% des fraudes et 9,1% des transactions normales. Un résultat similaire est obtenu pour le sous-ensemble de données “Test”.
pred_y = [1 if e > threshold else 0 for e in error_valid.reconstruction_error.values] cf_matrix = confusion_matrix(error_valid.true_class, pred_y)
Figure 7. Matrice de confusion
L’étape d’entraînement de l’autoencodeur variationnel est effectuée sur Google AI Platform. L’arborescence du projet est montrée dans Fig. 8 où se trouvent les fichiers requirements.txt, setup.py pour les dépendances et le package du code et un dossier trainer qui contient un fichier vide __init__.py et train.py dans lequel écrit l’autoencodeur variationnel. L’article [6] fournit en détail l’usage de Google AI Platform pour l’entraînement et la prédiction des modèles machine learning / deep learning.
Figure 8. Arborescence du projet
Le bucket qui contient les données du projet est d’abord créé depuis le terminal. Les données sont ensuite chargées dans ce bucket de Cloud Storage.
gsutil mb gs://bucket-fraud-detection-ae gsutil cp dataset.csv gs://bucket-fraud-detection-ae
Le job d’entraînement sur Google AI Platform se fait enfin via le script shell suivant.
PROJECT_ID=fraud-detection-ae JOB_NAME=fraud_detection_ae_$(date +%Y%m%d_%H%M%S) REGION=us-central1 gcloud config set project $PROJECT_ID gcloud ai-platform jobs submit training $JOB_NAME \ --module-name=trainer.train \ --package-path=./trainer \ --storage-path=gs://bucket-fraud-detection-ae/$JOB_NAME \ --region=$REGION \ --scale-tier=CUSTOM \ --master-machine-type=n1-standard-8 \ --python-version=3.7 \ --runtime-version=2.1
Références
[1]
[2] Observatoire National de la Délinquance et des Réponses Pénales (2019) Résultats de l’enquête cadre de vie et Sécurité [3] Observatoire de la Sécurité des Moyens de Paiement (2018) Rapport annuel [4] Goodfellow, Bengio, Courville (2016) Deep Learning. The MIT Press [5] Pozzolo, Caelen, Johnson, Bontempi (2015) Calibrating Probability with Undersampling for Unbalanced Classification. Symposium on Computational Intelligence and Data Mining, IEEE, [6] Sevi (2020) Google Cloud AI Platform : Training – Prediction – Deep Learning blog.engineering.publicissapient.fr