1. Introduction

Les activités frauduleuses impliquent souvent des réseaux cachés d'entités connectées, par exemple plusieurs comptes partageant la même adresse e-mail, le même numéro de téléphone ou la même adresse physique. Les bases de données relationnelles traditionnelles peuvent avoir du mal à interroger efficacement ces relations complexes à plusieurs niveaux.
BigQuery Graph vous permet d'analyser ces réseaux à grande échelle à l'aide de bases de données graphiques. Vous pouvez définir un graphique de propriétés au-dessus de vos tables BigQuery existantes et utiliser le langage de requête de graphique (GQL) pour trouver des modèles dans vos données.
Une application courante des réseaux graphiques pour la détection des fraudes consiste à bloquer les commandes dont l'adresse de livraison est associée à un réseau de fraude ou à bloquer les paiements appartenant à .
Dans cet atelier de programmation, vous allez créer une solution de détection des fraudes à l'aide de BigQuery Graph. Vous allez charger des données à partir de Cloud Storage, créer un graphique de propriétés et utiliser des requêtes graphiques pour identifier les connexions suspectes.
Points abordés
- Créer un ensemble de données BigQuery et charger des données
- Définir un graphique de propriétés à l'aide du langage de définition de données (DDL)
- Interroger le graphique à l'aide du langage de requête de graphique (GQL)
- Utiliser l'analyse de graphiques pour détecter les fraudes
Ce dont vous avez besoin
- Un projet Google Cloud avec facturation activée.
- Un environnement de notebook BigQuery (BigQuery Studio ou Colab Enterprise).
Coût
Cet atelier utilise des ressources Google Cloud facturables. Le coût estimé est inférieur à 5 $, en supposant que vous supprimez les ressources une fois l'atelier terminé.
2. Avant de commencer
Sélectionner ou créer un projet Google Cloud
- Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.
- Vérifiez que la facturation est activée pour votre projet Google Cloud. Découvrez comment vérifier si la facturation est activée.
Choisir votre environnement
Vous aurez besoin d'un environnement de notebook pour exécuter cet atelier. Vous pouvez utiliser BigQuery Studio ou Colab Enterprise.
- Accédez à la page BigQuery dans Google Cloud Console.
- Vous utiliserez le notebook Python pour exécuter les requêtes graphiques.
Démarrer Cloud Shell
- Cliquez sur Activer Cloud Shell en haut de la console Google Cloud.
- Vérifiez l'authentification :
gcloud auth list
- Confirmez votre projet :
gcloud config get project
- Définissez-le si nécessaire :
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
Activer les API
Exécutez cette commande pour activer l'API BigQuery requise :
gcloud services enable bigquery.googleapis.com
3. Charger des données
Dans cette étape, vous allez créer un ensemble de données BigQuery et charger les exemples de données à partir de Cloud Storage.
Les exemples de données se composent de plusieurs fichiers CSV représentant un environnement de vente au détail simulé :
customers.csv: informations sur les comptes clients.emails.csv: adresses e-mail.phones.csv: numéros de téléphone.addresses.csv: adresses physiques.customer_emails.csv,customer_phones.csv,customer_addresses.csv: tables de liaison.orders.csv: historique des commandes, y compris les indicateurs de fraude.
Créer l'ensemble de données
Créez un ensemble de données nommé fraud_demo pour contenir les tables.
- Pour cet atelier de programmation, nous allons exécuter des commandes SQL. Vous pouvez exécuter ces commandes dans le BigQuery Studio > Éditeur SQL ou utiliser la
bq querycommande dans Cloud Shell.
Nous partons du principe que vous utilisez l'éditeur SQL BigQuery pour une meilleure expérience avec les instructions de création sur plusieurs lignes.
CREATE SCHEMA IF NOT EXISTS `fraud_demo` OPTIONS(location="US");
Charger des tables
Exécutez les instructions SQL suivantes pour charger des données de Cloud Storage dans votre ensemble de données.
LOAD DATA OVERWRITE `fraud_demo.customers`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customers.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.emails`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/emails.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.phones`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/phones.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.addresses`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/addresses.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.customer_emails`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customer_emails.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.customer_phones`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customer_phones.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.customer_addresses`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customer_addresses.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.orders`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/orders.csv'],
skip_leading_rows = 1
);
4. Créer le graphique de propriétés
Maintenant que les données sont chargées, vous pouvez définir le graphique de propriétés. Un graphique de propriétés se compose de nœuds (entités) et d'arêtes (relations).
Dans cet atelier, les nœuds sont les suivants :
- Client : représente le titulaire du compte.
- Téléphone : représente un numéro de téléphone.
- E-mail : représente une adresse e-mail.
- Adresse : représente une adresse physique.
Les arêtes sont les suivantes :
- OwnsPhone : connecte un client à un téléphone.
- OwnsEmail : connecte un client à un e-mail.
- LinkedToAddress : connecte un client à une adresse.

Créer le graphique
Exécutez l'instruction DDL suivante pour créer le graphique nommé FraudDemo dans votre ensemble de données fraud_demo.
CREATE OR REPLACE PROPERTY GRAPH fraud_demo.FraudDemo
NODE TABLES(
fraud_demo.customers
KEY(account_id)
LABEL Customer PROPERTIES(
account_id,
name),
fraud_demo.emails
KEY(email)
LABEL Email PROPERTIES(
email,
email_type),
fraud_demo.phones
KEY(phone_number)
LABEL Phone PROPERTIES(
phone_number,
phone_type),
fraud_demo.addresses
KEY(address)
LABEL Address PROPERTIES(
address,
address_type)
)
EDGE TABLES(
fraud_demo.customer_emails
KEY(account_id, email)
SOURCE KEY(account_id) REFERENCES customers(account_id)
DESTINATION KEY(email) REFERENCES emails(email)
LABEL OwnsEmail PROPERTIES(
account_id,
email,
last_updated_ts),
fraud_demo.customer_phones
KEY(account_id, phone_number)
SOURCE KEY(account_id) REFERENCES customers(account_id)
DESTINATION KEY(phone_number) REFERENCES phones(phone_number)
LABEL OwnsPhone PROPERTIES(
account_id,
phone_number,
last_updated_ts),
fraud_demo.customer_addresses
KEY(account_id, address)
SOURCE KEY(account_id) REFERENCES customers(account_id)
DESTINATION KEY(address) REFERENCES addresses(address)
LABEL LinkedToAddress PROPERTIES(
account_id,
address,
last_updated_ts)
);
5. Analyser les réseaux (2 niveaux)
Ouvrez Nouveau notebook dans BigQuery Studio.

Pour les parties de visualisation et de recommandation de cet atelier de programmation, nous allons utiliser un notebook Google Colab dans BigQuery Studio. Cela nous permet de visualiser facilement les résultats du graphique.
Collez le code suivant dans une cellule de code :
!pip install bigquery-magics==0.12.1
Le notebook BigQuery Graph est implémenté en tant que commandes magiques IPython. En ajoutant la commande magique %%bigquery avec la fonction TO_JSON, vous pouvez visualiser les résultats comme indiqué dans les sections suivantes. Dans cette étape, vous allez exécuter une requête graphique pour trouver des connexions simples entre les comptes. Il s'agit d'une requête à deux niveaux, car elle effectue deux sauts à partir d'un nœud de départ pour trouver des nœuds associés (par exemple, Client -> E-mail -> Client).
Nous allons commencer par examiner le compte appartenant à Nicole Wade. Nous voulons trouver tous les comptes qui lui sont associés via deux sauts.
Exécuter la requête à deux niveaux
Exécutez la requête suivante dans votre notebook.
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH
p=(a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress WHERE e.last_updated_ts < '2025-07-30']- (n) ){2}
WHERE a.account_id IN ("d2f1f992-d116-41b3-955b-6c76a3352657")
-- Verify the final node in the hop array is a Customer
AND 'Customer' IN UNNEST(LABELS(n[OFFSET(1)]))
RETURN TO_JSON(p) AS paths

Comprendre les résultats
Cette requête :
- Commence au niveau du nœud
Customeravecaccount_id"d2f1f992-d116-41b3-955b-6c76a3352657" (Nicole Wade). - Suit l'une des arêtes
OwnsEmail,OwnsPhone, ouLinkedToAddressvers un nœud de connexion (Phone,Email, ouAddress). - Suit les arêtes de ce nœud de connexion vers d'autres nœuds
Customer. - Filtre les arêtes en fonction d'un code temporel (
last_updated_ts) pour afficher l'état du réseau à un moment précis.
Vous devriez voir que Zachary Cordova et Brenda Brown sont connectés à Nicole via la même adresse.
6. Analyser les réseaux (4 niveaux)
Dans cette étape, vous allez étendre la requête pour trouver des relations plus complexes. Nous allons rechercher des connexions à quatre niveaux. Cela nous permet de trouver des comptes connectés via plusieurs entités intermédiaires (par exemple, Client A -> E-mail -> Client B -> Téléphone -> Client C).
Nous allons également observer l'évolution de ce réseau au fil du temps.
État "Avant"
Tout d'abord, examinons le réseau tel qu'il existait le 30 juillet 2025.
Exécutez la requête suivante :
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH p= ANY SHORTEST (a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress WHERE e.last_updated_ts < '2025-07-30']- (n) ){3, 5}(reachable_a:Customer)
WHERE a.account_id IN ("d2f1f992-d116-41b3-955b-6c76a3352657")
-- Ensure the final node in the dynamic chain is actually a Customer
AND 'Customer' IN UNNEST(LABELS(n[OFFSET(ARRAY_LENGTH(n) - 1)]))
RETURN
TO_JSON(p) AS paths, -- Array of all traversed edges
ARRAY_LENGTH(e) AS hop_count

État "Après"
Voyons maintenant à quoi ressemble le réseau deux semaines plus tard. Nous allons exécuter la même requête, mais sans les restrictions de date.
Exécutez la requête suivante :
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH p= ANY SHORTEST (a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress]- (n) ){3, 5}(reachable_a:Customer)
WHERE a.account_id IN ("d2f1f992-d116-41b3-955b-6c76a3352657")
-- Ensure the final node in the dynamic chain is actually a Customer
AND 'Customer' IN UNNEST(LABELS(n[OFFSET(ARRAY_LENGTH(n) - 1)]))
RETURN
TO_JSON(p) AS paths, -- Array of all traversed edges
ARRAY_LENGTH(e) AS hop_count

Comprendre les résultats
En supprimant les filtres de date, vous interrogez l'ensemble de données complet. Vous remarquerez que le réseau s'est considérablement développé. Nicole Wade fait désormais partie d'un groupe beaucoup plus vaste et très connecté. Cette expansion rapide d'un réseau connecté est un indicateur fort d'une activité potentiellement frauduleuse, comme un réseau de fraude partageant des ressources au fil du temps.
7. Générer un rapport de fraude
Dans cette étape, vous allez combiner l'analyse de graphiques avec des données commerciales traditionnelles (commandes) pour générer un rapport de fraude complet. Vous allez identifier les comptes à risque et les commandes potentiellement frauduleuses.
Cette requête est plus complexe. Elle utilise GRAPH_TABLE pour exécuter la requête graphique dans SQL standard et calcule la variation de la taille du réseau (diff) entre les états "avant" et "après" que nous avons observés à l'étape précédente.
Exécuter la requête de rapport de fraude
Exécutez la requête suivante dans votre notebook.
%%bigquery --graph
WITH num_orders AS (
SELECT account_id, COUNT(1) AS num_order
FROM fraud_demo.orders
WHERE order_time > '2025-07-30'
GROUP BY account_id
),
orders AS (
SELECT account_id, order_id, fraud, order_total
FROM fraud_demo.orders
WHERE order_time > '2025-07-30'
),
-- Use Quantified Path Patterns to find connections up to 4 hops away
latest_connect AS (
SELECT
account_id,
ARRAY_LENGTH(ARRAY_AGG(DISTINCT connected_id)) AS size
FROM GRAPH_TABLE(
fraud_demo.FraudDemo
MATCH (a:Customer)-[:OwnsEmail|OwnsPhone|LinkedToAddress]-{4}(connected:Customer)
RETURN a.account_id AS account_id, connected.account_id AS connected_id
)
GROUP BY account_id
),
prev_connect AS (
SELECT
account_id,
ARRAY_LENGTH(ARRAY_AGG(DISTINCT connected_id)) AS size
FROM GRAPH_TABLE(
fraud_demo.FraudDemo
-- Apply the timestamp filter to EVERY edge in the 4-hop chain
MATCH (a:Customer)
(-[e:OwnsEmail|OwnsPhone|LinkedToAddress WHERE e.last_updated_ts < '2025-07-30']-(n)){4}
WHERE 'Customer' IN UNNEST(LABELS(n[OFFSET(3)]))
RETURN a.account_id AS account_id, n[OFFSET(3)].account_id AS connected_id
)
GROUP BY account_id
),
edge_changes AS (
SELECT account_id, MAX(last_updated_ts) AS max_last_updated_ts
FROM fraud_demo.customer_addresses
GROUP BY account_id
)
SELECT
la.account_id,
o.order_id,
la.size AS latest_size,
COALESCE(pa.size, 0) AS previous_size,
la.size - COALESCE(pa.size, 0) AS diff,
nos.num_order,
o.fraud AS reported_as_fraud,
o.order_total,
CASE
WHEN (la.size - COALESCE(pa.size, 0)) > 10 AND nos.num_order IS NULL THEN "CUSTOMER AT RISK"
WHEN (la.size - COALESCE(pa.size, 0)) > 10 AND nos.num_order IS NOT NULL AND o.fraud THEN "CONFIRMED FRAUD ORDER"
WHEN (la.size - COALESCE(pa.size, 0)) > 10 AND nos.num_order IS NOT NULL AND NOT o.fraud THEN "POTENTIAL FRAUD ORDER"
ELSE ""
END AS notes
FROM latest_connect la
LEFT JOIN prev_connect pa ON la.account_id = pa.account_id
LEFT JOIN num_orders nos ON la.account_id = nos.account_id
LEFT JOIN orders o ON la.account_id = o.account_id
INNER JOIN edge_changes ec ON la.account_id = ec.account_id
WHERE nos.num_order > 1 OR (la.size - COALESCE(pa.size, 0)) > 10
ORDER BY diff DESC
Comprendre les résultats
Ce rapport affiche les éléments suivants :
account_id: ID du compte analysé.order_id: ID d'une commande récente.latest_size: taille du réseau connecté aujourd'hui.previous_size: taille du réseau il y a deux semaines.diff: croissance de la taille du réseau.num_order: nombre de commandes récentes.reported_as_fraud: indique si la commande a été signalée comme frauduleuse.order_total: montant total de la commande.notes: état de risque calculé en fonction de la croissance du réseau et de l'historique des commandes.
Vous verrez des comptes avec des valeurs diff élevées et des totaux de commandes élevés, qui sont des candidats idéaux pour une enquête plus approfondie. Les notes "CLIENT À RISQUE" et "COMMANDE POTENTIELLEMENT FRAUDULEUSE" permettent de hiérarchiser ces comptes.

8. Détection à grande échelle
Dans cette dernière étape d'analyse, vous allez visualiser le réseau à plus grande échelle. Au lieu de commencer par un seul compte, vous allez interroger les connexions entre un ensemble de comptes suspects.
Cela vous permet de voir si plusieurs enquêtes indépendantes font en réalité partie du même réseau de fraude plus vaste.
Exécuter la requête à grande échelle
Exécutez la requête suivante dans votre notebook.
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH
p= ANY SHORTEST (a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress]- (n) ){3, 5}
(reachable_a:Customer)
-- these IDs are from the previous results
WHERE a.account_id in ( "845f2b14-cd10-4750-9f28-fe542c4a731b"
, "3ff59684-fbf9-40d7-8c41-285ade5002e6"
, "8887c17b-e6fb-4b3b-8c62-cb721aafd028"
, "03e777e5-6fb4-445d-b48c-cf42b7620874"
, "81629832-eb1d-4a0e-86da-81a198604898"
, "845f2b14-cd10-4750-9f28-fe542c4a731b",
"89e9a8fe-ffc4-44eb-8693-a711a3534849"
)
LIMIT 400
RETURN TO_JSON(p) as paths
Comprendre les résultats
Cette requête renvoie un graphique complexe montrant comment les comptes suspects spécifiés se chevauchent et partagent des ressources. Vous examinez maintenant la détection des fraudes à grande échelle, en identifiant des clusters d'activité qui pourraient justifier une réponse coordonnée.

9. Effectuer un nettoyage
Pour éviter que les ressources utilisées dans cet atelier de programmation ne soient facturées sur votre compte Google Cloud, vous devez supprimer l'ensemble de données et le graphique de propriétés.
Exécutez les instructions SQL suivantes pour nettoyer votre environnement.
DROP PROPERTY GRAPH IF EXISTS fraud_demo.FraudDemo;
DROP SCHEMA IF EXISTS fraud_demo CASCADE;
10. Félicitations
Félicitations ! Vous avez créé une solution de détection des fraudes à l'aide de BigQuery Graph.
Vous avez appris à :
- Charger des données de Cloud Storage vers BigQuery
- Définir un graphique de propriétés à l'aide du langage de définition de données (DDL)
- Interroger le graphique à l'aide du langage de requête de graphique (GQL) pour trouver des relations simples et complexes
- Combiner l'analyse de graphiques avec des données commerciales pour identifier les risques
- Visualiser les réseaux à grande échelle