BigQuery Graph ile Sahtekarlık Algılama

1. Giriş

Pazarlama Başlığı - Fintek Sektöründe Sahtekarlık

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

  1. Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun.
  2. 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.

  1. Google Cloud Console'da BigQuery sayfasına gidin.
  2. Grafik sorgularını çalıştırmak için Python not defterini kullanacaksınız.

Cloud Shell'i Başlatma

  1. Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i tıklayın.
  2. Kimlik doğrulamayı doğrulayın:
gcloud auth list
  1. Projenizi onaylayın:
gcloud config get project
  1. 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.

  1. 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 query komutunu kullanabilirsiniz. Yeni SQL SorgusuÇ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.

Yeni Not Defteri Oluşturma

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:

  1. account_id "d2f1f992-d116-41b3-955b-6c76a3352657" (Nicole Wade) ile Customer düğümünde başlar.
  2. OwnsEmail, OwnsPhone veya LinkedToAddress kenarlarından herhangi birini kullanarak bağlantı düğümüne (Phone, Email veya Address) ulaşır.
  3. Bu bağlanan düğümden diğer Customer düğümlere giden kenarları takip eder.
  4. 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