1. Giriş

Sahtekarlık içeren etkinlik genellikle bağlı varlıkların gizli ağlarını içerir. Örneğin, aynı e-posta adresini, telefon numarasını veya fiziksel adresi paylaşan birden fazla hesap. Geleneksel ilişkisel veritabanları, bu karmaşık ve çok adımlı ilişkileri verimli bir şekilde sorgulamakta zorlanabilir.
BigQuery Graph, bu ağları grafik veritabanlarını kullanarak geniş ölçekte analiz etmenize olanak tanır. Mevcut BigQuery tablolarınızın üzerinde bir özellik grafiği tanımlayabilir ve verilerinizdeki kalıpları bulmak için Grafik Sorgu Dili'ni (GQL) kullanabilirsiniz.
Grafik ağlarının sahtekarlık tespitinde yaygın olarak kullanılan bir uygulaması, sahtekarlık ağıyla ilişkili bir teslimat adresine sahip siparişleri veya sahtekarlık ağına ait ödemeleri durdurmaktır .
Bu codelab'de BigQuery Graph'i kullanarak bir sahtekarlık algılama çözümü oluşturacaksınız. Cloud Storage'dan veri yükleyecek, bir özellik grafiği oluşturacak ve şüpheli bağlantıları belirlemek için grafik sorgularını kullanacaksınız.
Neler öğreneceksiniz?
- BigQuery veri kümesi oluşturma ve veri yükleme
- DDL kullanarak özellik grafiği tanımlama
- GQL kullanarak grafiği sorgulama
- Dolandırıcılığı tespit etmek için grafik analizini kullanma
İhtiyacınız olanlar
- Faturalandırmanın etkin olduğu bir Google Cloud projesi.
- BigQuery not defteri ortamı (BigQuery Studio veya Colab Enterprise)
Maliyet
Bu laboratuvarda, faturalandırılabilir Google Cloud kaynakları kullanılmaktadır. Tahmini maliyet, tamamlandıktan sonra kaynakları sileceğiniz varsayıldığında 5 ABD dolarının altındadır.
2. Başlamadan önce
Bir Google Cloud projesi seçin veya oluşturun
- Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun.
- Google Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Faturalandırmanın etkin olup olmadığını nasıl kontrol edeceğinizi öğrenin.
Ortamınızı seçin
Bu laboratuvarı çalıştırmak için bir not defteri ortamına ihtiyacınız vardır. BigQuery Studio veya Colab Enterprise'ı kullanabilirsiniz.
- Google Cloud Console'da BigQuery sayfasına gidin.
- Grafik sorgularını çalıştırmak için Python not defterini kullanacaksınız.
Cloud Shell'i Başlatma
- Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i tıklayın.
- Kimlik doğrulamayı doğrulayın:
gcloud auth list
- Projenizi onaylayın:
gcloud config get project
- Gerekirse ayarlayın:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
API'leri etkinleştir
Gerekli BigQuery API'yi etkinleştirmek için şu komutu çalıştırın:
gcloud services enable bigquery.googleapis.com
3. Verileri Yükle
Bu adımda bir BigQuery veri kümesi oluşturacak ve örnek verileri Cloud Storage'dan yükleyeceksiniz.
Örnek veriler, simüle edilmiş bir perakende ortamını temsil eden çeşitli CSV dosyalarından oluşur:
customers.csv: Müşteri hesabı bilgileri.emails.csv: E-posta adresleri.phones.csv: Telefon numaraları.addresses.csv: Fiziksel adresler.customer_emails.csv,customer_phones.csv,customer_addresses.csv: Tabloları bağlama.orders.csv: Sahtekarlık işaretleri de dahil olmak üzere sipariş geçmişi.
Veri kümesini oluşturma
Tabloları tutmak için fraud_demo adlı bir veri kümesi oluşturun.
- Bu codelab'de SQL komutlarını yürüteceğiz. Bu komutları BigQuery Studio > SQL Düzenleyici'de çalıştırabilir veya Cloud Shell'de
bq querykomutunu kullanabilirsiniz.
Çok satırlı oluşturma ifadeleriyle daha iyi bir deneyim için BigQuery SQL Düzenleyici'yi kullandığınızı varsayacağız.
CREATE SCHEMA IF NOT EXISTS `fraud_demo` OPTIONS(location="US");
Tabloları Yükleme
Verileri Cloud Storage'dan veri kümenize yüklemek için aşağıdaki SQL ifadelerini çalıştırın.
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. Mülk grafiğini oluşturma
Veriler yüklendiğine göre artık mülk grafiğini tanımlayabilirsiniz. Özellik grafiği, düğümlerden (varlıklar) ve kenarlardan (ilişkiler) oluşur.
Bu laboratuvarda düğümler şunlardır:
- Müşteri: Hesap sahibini temsil eder.
- Telefon: Telefon numarasını gösterir.
- E-posta: Bir e-posta adresini temsil eder.
- Adres: Fiziksel bir adresi temsil eder.
Kenarlar:
- OwnsPhone: Müşteriyi telefona bağlar.
- OwnsEmail: Bir müşteriyi e-postaya bağlar.
- LinkedToAddress: Bir Müşteriyi bir Adrese bağlar.

Grafiği oluşturma
fraud_demo veri kümenizde FraudDemo adlı grafiği oluşturmak için aşağıdaki DDL ifadesini çalıştırın.
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. Ağları Analiz Etme (2 Atlama)
BigQuery Studio'da New Notebook'u (Yeni Not Defteri) açın.

Bu codelab'in görselleştirme ve öneri bölümlerinde BigQuery Studio'da Google Colab not defteri kullanacağız. Bu sayede grafik sonuçlarını kolayca görselleştirebiliriz.
BigQuery Graph Notebook, IPython Magics olarak uygulanır. %%bigquery sihirli komutunu TO_JSON işleviyle birlikte ekleyerek sonuçları aşağıdaki bölümlerde gösterildiği gibi görselleştirebilirsiniz. Bu adımda, hesaplar arasındaki basit bağlantıları bulmak için bir grafik sorgusu çalıştıracaksınız. Bu, ilgili düğümleri bulmak için başlangıç düğümünden 2 atlama uzaklaşan bir "2 atlamalı" sorgudur (ör. Müşteri -> E-posta -> Müşteri).
Nicole Wade'e ait hesabı inceleyerek başlayacağız. 2 yönlendirme ile onunla ilgili tüm hesapları bulmak istiyoruz.
2 Hop Sorgusunu Çalıştırma
Not defterinizde aşağıdaki sorguyu çalıştırın.
%%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

Sonuçları anlama
Bu sorgu:
account_id"d2f1f992-d116-41b3-955b-6c76a3352657" (Nicole Wade) ileCustomerdüğümünde başlar.OwnsEmail,OwnsPhoneveyaLinkedToAddresskenarlarından herhangi birini kullanarak bağlantı düğümüne (Phone,EmailveyaAddress) ulaşır.- Bu bağlanan düğümden diğer
Customerdüğümlere giden kenarları takip eder. - Ağın belirli bir zamandaki durumunu görmek için kenarları zaman damgasına (
last_updated_ts) göre filtreler.
Zachary Cordova ve Brenda Brown'ın aynı adres üzerinden Nicole'e bağlı olduğunu görürsünüz.
6. Ağları Analiz Etme (4 Atlama)
Bu adımda, daha karmaşık ilişkileri bulmak için sorguyu genişleteceksiniz. 4 atlamalı bağlantılar aranır. Bu sayede, birkaç ara tüzel kişi aracılığıyla bağlanan hesapları (ör. A müşterisi -> E-posta -> B müşterisi -> Telefon -> C müşterisi) bulabiliriz.
Bu ağın zaman içinde nasıl değiştiğini de gözlemleyeceğiz.
"Önceki" Durum
Öncelikle, 30 Temmuz 2025'te ağın nasıl göründüğüne bakalım.
Aşağıdaki sorguyu çalıştırın:
%%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

"Sonraki" durum
Şimdi de ağın 2 hafta sonra nasıl göründüğüne bakalım. Aynı sorguyu tarih kısıtlamaları olmadan çalıştıracağız.
Aşağıdaki sorguyu çalıştırın:
%%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

Sonuçları anlama
Tarih filtrelerini kaldırdığınızda, sorgunuz tüm veri kümesi üzerinde çalışır. Ağın önemli ölçüde büyüdüğünü fark edeceksiniz. Nicole Wade artık çok daha büyük ve birbirine sıkı sıkıya bağlı bir grubun parçası. Bağlı bir ağın bu şekilde hızlı bir şekilde genişlemesi, zaman içinde kaynak paylaşan bir dolandırıcılık çetesi gibi sahtekarlık içeren etkinliklerin olası bir göstergesidir.
7. Sahtekarlık Raporu Oluşturma
Bu adımda, kapsamlı bir sahtekarlık raporu oluşturmak için grafik analizini geleneksel iş verileriyle (siparişler) birleştireceksiniz. Risk altındaki hesapları ve olası sahtekarlık içeren siparişleri belirleyebilirsiniz.
Bu sorgu daha karmaşık. Standart SQL'de grafik sorgusunu çalıştırmak için GRAPH_TABLE kullanılır ve önceki adımda gözlemlediğimiz "önce" ve "sonra" durumları arasındaki ağ boyutundaki değişikliği (diff) hesaplar.
Sahtekarlık raporu sorgusunu çalıştırma
Not defterinizde aşağıdaki sorguyu çalıştırın.
%%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
Sonuçları anlama
Bu raporda şunlar gösterilir:
account_id: Analiz edilen hesabın kimliği.order_id: Yakın zamanda verilen bir siparişin kimliği.latest_size: Bağlı ağın mevcut boyutu.previous_size: 2 hafta önceki ağ boyutu.diff: Ağ boyutundaki büyüme.num_order: Son siparişlerin sayısı.reported_as_fraud: Siparişin sahtekarlık olarak işaretlenip işaretlenmediği.order_total: Siparişin toplam tutarı.notes: Ağ büyümesine ve sipariş geçmişine göre hesaplanan risk durumu.
Daha fazla inceleme için uygun olan, büyük diff değerlerine ve yüksek sipariş toplamlarına sahip hesapları görürsünüz. "RİSKLİ MÜŞTERİ" ve "OLASI SAHTEKARLIK SİPARİŞİ" notları, bu hesaplara öncelik vermenize yardımcı olur.

8. Geniş Ölçekte Algılama
Bu son analiz adımında ağı daha büyük bir ölçekte görselleştireceksiniz. Tek bir hesapla başlamak yerine, bir dizi şüpheli hesap arasındaki bağlantıları sorgularsınız.
Bu sayede, birden fazla bağımsız soruşturmanın aslında aynı büyük dolandırıcılık şebekesinin parçası olup olmadığını görebilirsiniz.
Ölçeklendirilmiş sorguyu çalıştırma
Not defterinizde aşağıdaki sorguyu çalıştırın.
%%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
Sonuçları anlama
Bu sorgu, belirtilen şüpheli hesapların nasıl çakıştığını ve kaynakları nasıl paylaştığını gösteren karmaşık bir grafik döndürür. Artık büyük ölçekte sahtekarlık tespiti yapabilir, koordineli bir yanıt gerektirebilecek etkinlik kümelerini belirleyebilirsiniz.

9. Temizleme
Bu codelab'de kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini önlemek istiyorsanız veri kümesini ve özellik grafiğini silmeniz gerekir.
Ortamınızı temizlemek için aşağıdaki SQL ifadelerini çalıştırın.
DROP PROPERTY GRAPH IF EXISTS fraud_demo.FraudDemo;
DROP SCHEMA IF EXISTS fraud_demo CASCADE;
10. Tebrikler
Tebrikler! BigQuery Graph'ı kullanarak başarıyla bir sahtekarlık algılama çözümü oluşturdunuz.
Öğrendikleriniz:
- Cloud Storage'dan BigQuery'ye veri yükleyin.
- DDL kullanarak bir özellik grafiği tanımlayın.
- Basit ve karmaşık ilişkileri bulmak için GQL kullanarak grafiği sorgulayın.
- Riski belirlemek için grafik analizini işletme verileriyle birleştirin.
- Ağları geniş ölçekte görselleştirin.
Diğer Kaynaklar