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 sur vos tables BigQuery existantes et utiliser le langage de requête de graphe (GQL) pour trouver des modèles dans vos données.
Une application courante des réseaux de graphiques pour la détection des fraudes consiste à arrêter les commandes dont l'adresse de livraison est associée à un réseau de fraude ou à arrêter les paiements appartenant à un réseau de fraude .
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 depuis Cloud Storage, créer un graphique de propriétés et utiliser des requêtes graphiques pour identifier les connexions suspectes.
Points abordés
- Comment créer un ensemble de données BigQuery et charger des données
- Comment définir un graphique de propriétés à l'aide du langage DDL.
- Découvrez comment interroger le graphique à l'aide de GQL.
- Découvrez comment utiliser l'analyse de graphiques pour détecter les fraudes.
Prérequis
- 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 supprimiez 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
Pour suivre cet atelier, vous aurez besoin d'un environnement de notebook. Vous pouvez utiliser BigQuery Studio ou Colab Enterprise.
- Accédez à la page BigQuery de la console Google Cloud.
- 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 la commande suivante 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 depuis Cloud Storage.
Les exemples de données se composent de plusieurs fichiers CSV représentant un environnement de vente simulé :
customers.csv: informations sur le compte client.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 d'association.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 stocker les tables.
- Pour cet atelier de programmation, nous allons exécuter des commandes SQL. Vous pouvez exécuter ces commandes dans BigQuery Studio > Éditeur SQL ou utiliser la commande
bq querydans Cloud Shell.
Nous partons du principe que vous utilisez l'éditeur SQL BigQuery pour une meilleure expérience avec les instructions CREATE multilignes.
CREATE SCHEMA IF NOT EXISTS `fraud_demo` OPTIONS(location="US");
Charger des tables
Exécutez les instructions SQL suivantes pour charger les données depuis 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é
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 bords sont les suivants :
- OwnsPhone : associe un client à un téléphone.
- OwnsEmail : associe un client à une adresse e-mail.
- LinkedToAddress : associe un client à une adresse.

Créer le graphique
Exécutez l'instruction LDD 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 sauts)
Ouvrez Nouveau notebook dans BigQuery Studio.

Pour les parties visualisation et recommandation de cet atelier de programmation, nous utiliserons un notebook Google Colab dans BigQuery Studio. Cela nous permet de visualiser facilement les résultats du graphique.
BigQuery Graph Notebook est implémenté en tant que commande magique IPython. En ajoutant la commande magique %%bigquery avec la fonction TO_JSON, vous pouvez visualiser les résultats comme indiqué dans les sections suivantes. Au cours de cette étape, vous allez exécuter une requête de graphique pour trouver des connexions simples entre les comptes. Il s'agit d'une requête "à deux sauts", car elle effectue deux sauts à partir d'un nœud de départ pour trouver les nœuds associés (par exemple, Client > E-mail > Client).
Nous allons commencer par examiner le compte de Nicole Wade. Nous voulons trouver tous les comptes associés à elle en deux sauts.
Exécuter la requête 2-Hop
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 nœud
Customeravecaccount_id"d2f1f992-d116-41b3-955b-6c76a3352657" (Nicole Wade). - Suit l'un des bords
OwnsEmail,OwnsPhoneouLinkedToAddressvers un nœud de connexion (Phone,EmailouAddress). - Suit les arêtes en arrière à partir 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 sauts)
Dans cette étape, vous allez étendre la requête pour trouver des relations plus complexes. Nous rechercherons les connexions à quatre degrés de séparation. Cela nous permet de trouver des comptes connectés par le biais de plusieurs entités intermédiaires (par exemple, Client A → Adresse e-mail → Client B → Numéro de téléphone → Client C).
Nous observerons également l'évolution de ce réseau au fil du temps.
État "Avant"
Commençons par examiner le réseau tel qu'il existait le 30 juillet 2025.
Exécutez la requête suivante :
%%bigquery --graph
%%bigquery --graph
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)]))
GRAPH fraud_demo.FraudDemo
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 a considérablement augmenté. 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 fraudeurs partageant des ressources au fil du temps.
7. Générer un rapport sur la fraude
Dans cette étape, vous allez combiner l'analyse de graphiques avec les données commerciales traditionnelles (commandes) pour générer un rapport complet sur la fraude. Vous identifierez les comptes à risque et les commandes potentiellement frauduleuses.
Cette requête est plus complexe. Il utilise GRAPH_TABLE pour exécuter la requête de graphique dans le langage 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 sur la 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 du risque calculé en fonction de la croissance du réseau et de l'historique des commandes.
Vous verrez les comptes avec des valeurs diff élevées et des totaux de commandes importants, qui sont de bons candidats pour une enquête plus approfondie. Les notes "CLIENT À RISQUE" et "COMMANDE POTENTIELLEMENT FRAUDULEUSE" vous aident à 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 rechercher des connexions entre un ensemble de comptes suspects.
Cela vous permet de déterminer si plusieurs enquêtes indépendantes font en réalité partie d'un même réseau de fraude plus vaste.
Exécuter la requête mise à l'é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 pouvez désormais détecter la fraude à grande échelle et identifier les groupes d'activités qui pourraient nécessiter une réponse coordonnée.

9. Effectuer un nettoyage
Pour éviter que les ressources utilisées dans cet atelier de programmation soient facturées sur votre compte Google Cloud, supprimez 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éfinissez un graphique de propriétés à l'aide du langage DDL.
- Interrogez le graphique à l'aide de GQL pour trouver des relations simples et complexes.
- Combinez l'analyse de graphiques avec les données d'entreprise pour identifier les risques.
- Visualisez les réseaux à grande échelle.
Autres ressources