1. Wprowadzenie

Nieuczciwe działanie często obejmuje ukryte sieci powiązanych encji, np. wiele kont, które mają ten sam adres e-mail, numer telefonu lub adres pocztowy. Tradycyjne relacyjne bazy danych mogą mieć problemy z wydajnym wykonywaniem zapytań dotyczących tych złożonych relacji wieloetapowych.
BigQuery Graph umożliwia analizowanie tych sieci na dużą skalę za pomocą baz danych grafów. Możesz zdefiniować wykres właściwości na podstawie istniejących tabel BigQuery i używać języka zapytań do wykresów (GQL) do znajdowania wzorców w danych.
Częstym zastosowaniem sieci grafów w wykrywaniu oszustw jest blokowanie zamówień z adresem dostawy powiązanym z siecią oszustw lub blokowanie płatności należących do .
W tym ćwiczeniu utworzysz rozwiązanie do wykrywania oszustw za pomocą BigQuery Graph. Wczytasz dane z Cloud Storage, utworzysz graf właściwości i użyjesz zapytań do grafu, aby zidentyfikować podejrzane połączenia.
Czego się nauczysz
- Jak utworzyć zbiór danych BigQuery i wczytać dane.
- Jak zdefiniować graf właściwości za pomocą DDL.
- Jak wysyłać zapytania do grafu za pomocą języka GQL.
- Jak wykrywać oszustwa za pomocą analizy grafów.
Czego potrzebujesz
- Projekt Google Cloud z włączonymi płatnościami.
- Środowisko notatnika BigQuery (BigQuery Studio lub Colab Enterprise).
Koszt
W tym module używane są płatne zasoby Google Cloud. Szacowany koszt to mniej niż 5 USD, przy założeniu, że po zakończeniu usuniesz zasoby.
2. Zanim zaczniesz
Wybieranie lub tworzenie projektu w chmurze Google Cloud
- W konsoli Google Cloud na stronie selektora projektów wybierz lub utwórz projekt w chmurze Google Cloud.
- Sprawdź, czy w projekcie Google Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy płatności są włączone.
Wybierz środowisko
Aby ukończyć ten moduł, potrzebujesz środowiska notatnika. Możesz użyć BigQuery Studio lub Colab Enterprise.
- Otwórz stronę BigQuery w konsoli Google Cloud.
- Do uruchamiania zapytań o grafy będziesz używać notatnika w Pythonie.
Uruchamianie Cloud Shell
- Kliknij Aktywuj Cloud Shell u góry konsoli Google Cloud.
- Potwierdź uwierzytelnianie:
gcloud auth list
- Potwierdź projekt:
gcloud config get project
- W razie potrzeby ustaw:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
Włącz interfejsy API
Aby włączyć wymagany interfejs BigQuery API, uruchom to polecenie:
gcloud services enable bigquery.googleapis.com
3. Wczytaj dane
W tym kroku utworzysz zbiór danych BigQuery i wczytasz przykładowe dane z Cloud Storage.
Przykładowe dane składają się z kilku plików CSV przedstawiających symulowane środowisko sprzedaży detalicznej:
customers.csv: informacje o koncie klienta,emails.csv: Adresy e-mail.phones.csv: numery telefonów.addresses.csv: adresy pocztowe,customer_emails.csv,customer_phones.csv,customer_addresses.csv: łączenie tabel.orders.csv: historia zamówień, w tym oznaczenia oszustw;
Tworzenie zbioru danych
Utwórz zbiór danych o nazwie fraud_demo, w którym będą przechowywane tabele.
- W tym ćwiczeniu będziemy wykonywać polecenia SQL. Te polecenia możesz uruchomić w BigQuery Studio > Edytor SQL lub użyć polecenia
bq queryw Cloud Shell.
Zakładamy, że używasz edytora SQL BigQuery, aby zapewnić sobie lepsze wrażenia podczas tworzenia instrukcji wielowierszowych.
CREATE SCHEMA IF NOT EXISTS `fraud_demo` OPTIONS(location="US");
Wczytywanie tabel
Aby wczytać dane z Cloud Storage do zbioru danych, uruchom te instrukcje SQL.
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. Tworzenie wykresu właściwości
Po wczytaniu danych możesz zdefiniować wykres właściwości. Graf właściwości składa się z węzłów (encji) i krawędzi (relacji).
W tym laboratorium węzły to:
- Klient: reprezentuje właściciela konta.
- Telefon: reprezentuje numer telefonu.
- Email: reprezentuje adres e-mail.
- Address: reprezentuje adres pocztowy.
Krawędzie to:
- OwnsPhone: łączy klienta z telefonem.
- OwnsEmail: łączy klienta z adresem e-mail.
- LinkedToAddress: łączy klienta z adresem.

Tworzenie wykresu
Aby utworzyć graf o nazwie FraudDemo w zbiorze danych fraud_demo, uruchom tę instrukcję DDL:
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. Analizowanie sieci (2 połączenia)
Otwórz Nowy notatnik w BigQuery Studio.

W części tego ćwiczenia dotyczącej wizualizacji i rekomendacji użyjemy notatnika Google Colab w BigQuery Studio. Dzięki temu możemy łatwo wizualizować wyniki wykresu.
Notatnik grafów BigQuery jest zaimplementowany jako IPython Magics. Dodając polecenie magiczne %%bigquery z funkcją TO_JSON, możesz wizualizować wyniki w sposób pokazany w kolejnych sekcjach. W tym kroku uruchomisz zapytanie do grafu, aby znaleźć proste połączenia między kontami. Jest to zapytanie „2-hop”, ponieważ przemieszcza się 2 kroki od węzła początkowego, aby znaleźć powiązane węzły (np. Klient –> E-mail –> Klient).
Zaczniemy od zbadania konta należącego do Nicole Wade. Chcemy znaleźć wszystkie konta powiązane z nią w 2 krokach.
Uruchamianie zapytania 2-Hop Query
Uruchom w notatniku to zapytanie.
%%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

Interpretowanie wyników
To zapytanie:
- Zaczyna się od węzła
Customerz wartościąaccount_id„d2f1f992-d116-41b3-955b-6c76a3352657” (Nicole Wade). - Podąża za dowolną krawędzią
OwnsEmail,OwnsPhonelubLinkedToAddressdo węzła łączącego (Phone,EmaillubAddress). - Podąża krawędziami z powrotem od tego węzła łączącego do innych węzłów
Customer. - Filtruje krawędzie na podstawie sygnatury czasowej (
last_updated_ts), aby zobaczyć stan sieci w określonym czasie.
Powinno być widać, że Zachary Cordova i Brenda Brown są połączeni z Nicole za pomocą tego samego adresu.
6. Analizowanie sieci (4 przeskoki)
W tym kroku rozszerzysz zapytanie, aby znaleźć bardziej złożone relacje. Będziemy szukać połączeń 4-hop. Dzięki temu możemy znajdować konta połączone za pomocą kilku podmiotów pośrednich (np. Klient A –> e-mail –> Klient B –> telefon –> Klient C).
Będziemy też obserwować, jak ta sieć zmienia się z czasem.
Stan „Przed”
Najpierw przyjrzyjmy się sieci w dniu 30 lipca 2025 r.
Uruchom poniższe zapytanie:
%%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

Stan „Po”
Zobaczmy teraz, jak wygląda sieć 2 tygodnie później. Uruchomimy to samo zapytanie, ale bez ograniczeń dotyczących daty.
Uruchom poniższe zapytanie:
%%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

Interpretowanie wyników
Usuwając filtry daty, wysyłasz zapytanie dotyczące pełnego zbioru danych. Zauważysz, że sieć znacznie się rozrosła. Nicole Wade należy teraz do znacznie większej, dobrze powiązanej grupy. Szybkie rozszerzanie sieci połączonych urządzeń jest silnym wskaźnikiem potencjalnie nieuczciwych działań, takich jak udostępnianie zasobów przez grupę oszustów.
7. Generowanie raportu o oszustwie
W tym kroku połączysz analizę grafów z tradycyjnymi firmowymi bazami danych (zamówieniami), aby wygenerować kompleksowy raport o oszustwach. Będziesz rozpoznawać zagrożone konta i potencjalnie fałszywe zamówienia.
To zapytanie jest bardziej złożone. Używa funkcji GRAPH_TABLE do uruchamiania zapytania o graf w standardowej wersji SQL i oblicza zmianę rozmiaru sieci (diff) między stanami „przed” i „po”, które zaobserwowaliśmy w poprzednim kroku.
Uruchamianie zapytania raportu o oszustwach
Uruchom w notatniku to zapytanie.
%%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
Interpretowanie wyników
Ten raport zawiera:
account_id: identyfikator analizowanego konta.order_id: Identyfikator ostatniego zamówienia.latest_size: rozmiar połączonej sieci.previous_size: rozmiar sieci 2 tygodnie temu;diff: wzrost rozmiaru sieci;num_order: liczba ostatnich zamówień.reported_as_fraud: czy zamówienie zostało oznaczone jako oszukańcze.order_total: łączna kwota zamówienia.notes: obliczony stan ryzyka na podstawie wzrostu sieci i historii zamówień.
Zobaczysz konta z dużymi wartościami diff i wysokimi łącznymi kwotami zamówień, które są najlepszymi kandydatami do dalszego zbadania. Notatki „KLIENT ZAGROŻONY” i „POTENCJALNE OSZUSTWO” pomagają określić priorytety tych kont.

8. Wykrywanie na dużą skalę
W tym ostatnim kroku analizy wizualizujesz sieć w większej skali. Zamiast zaczynać od jednego konta, będziesz wyszukiwać połączenia między zestawem podejrzanych kont.
Dzięki temu możesz sprawdzić, czy kilka niezależnych analiz zagrożeń nie jest w rzeczywistości częścią tej samej większej grupy oszustów.
Uruchamianie zapytania skalowanego
Uruchom w notatniku to zapytanie.
%%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
Interpretowanie wyników
To zapytanie zwraca złożony wykres pokazujący, jak określone podejrzane konta nakładają się na siebie i współdzielą zasoby. Teraz możesz wykrywać oszustwa na dużą skalę, identyfikując klastry aktywności, które mogą wymagać skoordynowanej reakcji.

9. Czyszczenie
Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby zużyte w tym ćwiczeniu, usuń zbiór danych i wykres właściwości.
Aby zwolnić miejsce w środowisku, uruchom te instrukcje SQL.
DROP PROPERTY GRAPH IF EXISTS fraud_demo.FraudDemo;
DROP SCHEMA IF EXISTS fraud_demo CASCADE;
10. Gratulacje
Gratulacje! Udało Ci się utworzyć rozwiązanie do wykrywania oszustw za pomocą BigQuery Graph.
Wiesz już, jak:
- wczytać dane z Cloud Storage do BigQuery;
- Zdefiniuj graf właściwości za pomocą DDL.
- Wysyłaj zapytania do wykresu za pomocą języka GQL, aby znajdować proste i złożone relacje.
- Łączenie analizy grafów z firmowymi bazami danych w celu identyfikowania ryzyka.
- Wizualizacja sieci na dużą skalę.
Więcej zasobów