رصد الاحتيال باستخدام BigQuery Graph

1. مقدمة

Marketing Header - Fraud in Fintech

غالبًا ما تتضمّن الأنشطة الاحتيالية شبكات مخفية من الجهات المرتبطة، مثل حسابات متعدّدة تشارك عنوان البريد الإلكتروني أو رقم الهاتف أو العنوان الجغرافي نفسه. قد تواجه قواعد البيانات الارتباطية التقليدية صعوبة في الاستعلام عن هذه العلاقات المعقّدة والمتعددة المراحل بكفاءة.

تتيح لك خدمة BigQuery Graph تحليل هذه الشبكات على نطاق واسع باستخدام قواعد بيانات الرسومات البيانية. يمكنك تحديد رسم بياني للخصائص فوق جداول BigQuery الحالية واستخدام لغة طلبات البحث في الرسوم البيانية (GQL) للعثور على أنماط في بياناتك.

من التطبيقات الشائعة لشبكات الرسوم البيانية في رصد الاحتيال إيقاف الطلبات التي تتضمّن عنوان تسليم مرتبطًا بشبكة احتيال أو إيقاف عمليات الدفع التي تنتمي إلى .

في هذا الدرس التطبيقي حول الترميز، ستنشئ حلاً لرصد الاحتيال باستخدام "الرسم البياني في BigQuery". ستحمّل البيانات من Cloud Storage، وتنشئ رسمًا بيانيًا للعلاقات، وتستخدم طلبات البحث في الرسم البياني لتحديد الروابط المشبوهة.

أهداف الدورة التعليمية

  • كيفية إنشاء مجموعة بيانات في BigQuery وتحميل البيانات
  • كيفية تحديد رسم بياني للخصائص باستخدام لغة تعريف البيانات (DDL)
  • كيفية طلب البحث في الرسم البياني باستخدام لغة طلبات البحث الخاصة بالرسوم البيانية (GQL)
  • كيفية استخدام تحليلات الرسومات البيانية لرصد الاحتيال

المتطلبات

  • مشروع Google Cloud تم تفعيل الفوترة فيه
  • بيئة دفتر ملاحظات BigQuery (‫BigQuery Studio أو Colab Enterprise)

التكلفة

يستخدم هذا الدرس التطبيقي موارد Google Cloud قابلة للفوترة. التكلفة المقدّرة أقل من 5 دولارات أمريكية، على افتراض أنّك ستحذف الموارد بعد الانتهاء.

2. قبل البدء

اختيار مشروع Google Cloud أو إنشاؤه

  1. في Google Cloud Console، في صفحة اختيار المشروع، اختَر مشروعًا على Google Cloud أو أنشِئ مشروعًا.
  2. تأكَّد من تفعيل الفوترة لمشروعك على Google Cloud. كيفية التحقّق من تفعيل الفوترة

اختيار البيئة

ستحتاج إلى بيئة دفتر ملاحظات لتشغيل هذا الدرس التطبيقي. يمكنك استخدام BigQuery Studio أو Colab Enterprise.

  1. انتقِل إلى صفحة BigQuery في Google Cloud Console.
  2. ستستخدم دفتر Python لتنفيذ طلبات البحث في الرسم البياني.

بدء Cloud Shell

  1. انقر على تفعيل Cloud Shell في أعلى "وحدة تحكّم Google Cloud".
  2. إثبات صحة المصادقة:
gcloud auth list
  1. تأكيد مشروعك:
gcloud config get project
  1. اضبطه إذا لزم الأمر:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

تفعيل واجهات برمجة التطبيقات

نفِّذ الأمر التالي لتفعيل واجهة BigQuery API المطلوبة:

gcloud services enable bigquery.googleapis.com \
  bigqueryreservation.googleapis.com 

إنشاء حجز وتعيين في BigQuery

لتنفيذ طلبات بحث GQL، يجب أن يكون لديك حجز يستخدم إصدار Enterprise أو Enterprise Plus، أو إنشاء حجز Enterprise Edition مع التوسّع التلقائي في Cloud Shell:

# 1. Create a BigQuery Enterprise reservation with 0 baseline slots and 100 max autoscaling slots
bq mk --reservation \
  --project_id=${GCP_PROJECT} \
  --location=US \
  --edition=ENTERPRISE \
  --slots=0 \
  --autoscale_max_slots=100 \
  --ignore_idle_slots=true \
  fraud-reservation

# 2. Assign your Cloud project to the newly created reservation for query execution
bq mk --reservation_assignment \
  --project_id=${GCP_PROJECT} \
  --location=US \
  --reservation_id=fraud-reservation \
  --job_type=QUERY \
  --assignee_type=PROJECT \
  --assignee_id=${GCP_PROJECT}

3- تحميل البيانات

في هذه الخطوة، ستنشئ مجموعة بيانات BigQuery وتحمّل البيانات النموذجية من Cloud Storage.

تتألف البيانات النموذجية من عدة ملفات CSV تمثّل بيئة بيع بالتجزئة محاكاة:

  • customers.csv: معلومات حساب العميل
  • emails.csv: عناوين البريد الإلكتروني
  • phones.csv: أرقام الهواتف
  • addresses.csv: العناوين الجغرافية
  • customer_emails.csv، customer_phones.csv، customer_addresses.csv: ربط الجداول
  • orders.csv: سجلّ الطلبات، بما في ذلك الإبلاغ عن الاحتيال

إنشاء مجموعة البيانات

أنشئ مجموعة بيانات باسم fraud_demo لتضمين الجداول.

  1. في هذا الدرس التطبيقي، سننفّذ أوامر SQL. يمكنك تنفيذ هذه الأوامر في BigQuery Studio > محرِّر SQL، أو استخدام الأمر bq query في Cloud Shell. طلب بحث SQL جديدسنفترض أنّك تستخدم أداة تعديل SQL في BigQuery للحصول على تجربة أفضل مع عبارات الإنشاء المتعددة الأسطر.
CREATE SCHEMA IF NOT EXISTS `fraud_demo` OPTIONS(location="US");

جداول التحميل

نفِّذ عبارات SQL التالية لتحميل البيانات من Cloud Storage إلى مجموعة البيانات.

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. إنشاء الرسم البياني للمواقع

بعد تحميل البيانات، يمكنك تحديد الرسم البياني للسمات. يتألف الرسم البياني للخصائص من عُقد (كيانات) وحواف (علاقات).

في هذا التمرين العملي، تكون العُقد كما يلي:

  • العميل: يمثّل صاحب الحساب.
  • الهاتف: يمثّل رقم هاتف.
  • البريد الإلكتروني: يمثّل عنوان بريد إلكتروني.
  • العنوان: يمثّل عنوانًا جغرافيًا.

الحواف هي:

  • OwnsPhone: لربط "العميل" بـ "الهاتف".
  • OwnsEmail: لربط "عميل" بـ "بريد إلكتروني".
  • LinkedToAddress: لربط "عميل" بـ "عنوان".

إنشاء الرسم البياني

نفِّذ عبارة DDL التالية لإنشاء الرسم البياني المسمّى FraudDemo في مجموعة البيانات 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- تحليل الشبكات (خطوتان)

افتح دفتر ملاحظات جديد في BigQuery Studio.

إنشاء دفتر ملاحظات جديد

بالنسبة إلى جزأَي التمثيل البصري والاقتراحات في هذا الدرس التطبيقي حول الترميز، سنستخدم دفتر ملاحظات Google Colab في BigQuery Studio. يتيح لنا ذلك عرض نتائج الرسم البياني بسهولة.

ألصِق ما يلي في خلية رمز برمجي:

!pip install bigquery-magics==0.12.1

يتم تنفيذ BigQuery Graph Notebook كـ IPython Magics. من خلال إضافة الأمر السحري %%bigquery مع الدالة TO_JSON، يمكنك عرض النتائج كما هو موضّح في الأقسام التالية. في هذه الخطوة، ستنفّذ طلب بحث في الرسم البياني للعثور على روابط بسيطة بين الحسابات. هذا طلب بحث "بخطوتين" لأنّه ينتقل بخطوتين من عقدة البداية للعثور على العُقد ذات الصلة (مثل "العميل" -> "البريد الإلكتروني" -> "العميل").

سنبدأ بالتحقيق في الحساب الذي يخص نيكول ويد. نريد العثور على أي حسابات مرتبطة بها من خلال وسيطَين.

تنفيذ طلب البحث "خطوتان"

نفِّذ الطلب التالي في دفتر الملاحظات.

%%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

فهم النتائج

هذا الطلب:

  1. يبدأ عند العقدة Customer مع account_id "d2f1f992-d116-41b3-955b-6c76a3352657" (نيكول ويد).
  2. تتبُّع أي من الحواف OwnsEmail أو OwnsPhone أو LinkedToAddress إلى عقدة ربط (Phone أو Email أو Address)
  3. تتتبّع الحواف من عقدة الربط هذه إلى عقد Customer أخرى.
  4. تفلتر هذه السمة الحواف استنادًا إلى طابع زمني (last_updated_ts) للاطّلاع على حالة الشبكة في وقت معيّن.

يجب أن يظهر أنّ Zachary Cordova وBrenda Brown مرتبطان بـ Nicole من خلال العنوان نفسه.

6. تحليل الشبكات (4 مستويات)

في هذه الخطوة، ستوسّع طلب البحث للعثور على علاقات أكثر تعقيدًا. سنبحث عن روابط بأربع خطوات. يتيح لنا ذلك العثور على حسابات مرتبطة من خلال عدة كيانات وسيطة (مثل العميل أ -> البريد الإلكتروني -> العميل ب -> الهاتف -> العميل ج).

وسنراقب أيضًا كيف تتغير هذه الشبكة بمرور الوقت.

حالة "قبل"

لنلقِ نظرة أولاً على الشبكة كما كانت في 30 يوليو 2025.

نفِّذ طلب البحث التالي:

%%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

حالة "بعد"

لنرى الآن كيف تبدو الشبكة بعد أسبوعَين. سننفّذ طلب البحث نفسه ولكن بدون القيود المتعلقة بالتاريخ.

نفِّذ طلب البحث التالي:

%%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

فهم النتائج

من خلال إزالة فلاتر التاريخ، يمكنك إجراء طلب بحث في مجموعة البيانات الكاملة. ستلاحظ أنّ الشبكة قد نمت بشكل كبير. أصبحت نيكول ويد الآن جزءًا من مجموعة أكبر بكثير ومرتبطة بشكل كبير. ويُعدّ هذا التوسّع السريع لشبكة مرتبطة مؤشرًا قويًا على النشاط الاحتيالي المحتمل، مثل مجموعة احتيال تشارك الموارد بمرور الوقت.

7. إنشاء تقرير عن الاحتيال

في هذه الخطوة، ستجمع بين تحليلات الرسومات البيانية وبيانات النشاط التجاري التقليدية (الطلبات) لإنشاء تقرير شامل عن الاحتيال. ستتمكّن من تحديد الحسابات المعرَّضة للخطر والطلبات الاحتيالية المحتملة.

هذا الاستعلام أكثر تعقيدًا. يستخدم هذا الاستعلام GRAPH_TABLE لتشغيل استعلام الرسم البياني داخل SQL العادي، ويحسب التغيير في حجم الشبكة (diff) بين حالتَي "قبل" و "بعد" اللتين لاحظناهما في الخطوة السابقة.

تنفيذ طلب البحث عن تقرير الاحتيال

نفِّذ الطلب التالي في دفتر الملاحظات.

%%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

فهم النتائج

يعرض هذا التقرير ما يلي:

  • account_id: معرّف الحساب الذي يتم تحليله.
  • order_id: معرّف طلب حديث
  • latest_size: حجم الشبكة المتصلة اليوم
  • previous_size: حجم الشبكة قبل أسبوعَين
  • diff: النمو في حجم الشبكة
  • num_order: عدد الطلبات الأخيرة
  • reported_as_fraud: ما إذا تم وضع علامة على الطلب باعتباره احتيالاً
  • order_total: إجمالي مبلغ الطلب
  • notes: حالة المخاطرة المحسوبة استنادًا إلى نمو الشبكة وسجلّ الطلبات

ستظهر لك حسابات تتضمّن قيم diff كبيرة وإجمالي طلبات مرتفع، وهي مرشّحة أساسية لإجراء المزيد من التحقيقات. تساعد الملاحظتان "العميل المعرّض للخطر" و "طلب شراء محتمل أن يكون احتياليًا" في تحديد أولويات هذه الحسابات.

8. الرصد على نطاق واسع

في خطوة التحليل النهائية هذه، ستعرض الشبكة على نطاق أوسع. بدلاً من البدء بحساب واحد، ستطلب البحث عن روابط بين مجموعة من الحسابات المريبة.

يساعدك ذلك في معرفة ما إذا كانت التحقيقات المستقلة المتعددة هي في الواقع جزء من شبكة تزوير أكبر.

تنفيذ طلب البحث الموسّع

نفِّذ الطلب التالي في دفتر الملاحظات.

%%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

فهم النتائج

يعرض هذا الطلب رسمًا بيانيًا معقّدًا يوضّح كيفية تداخل الحسابات المريبة المحدّدة ومشاركة الموارد. أنت الآن بصدد رصد الاحتيال على نطاق واسع، وتحديد مجموعات من الأنشطة التي قد تستدعي اتّخاذ إجراءات منسّقة.

9. تنظيف

لتجنُّب تحمّل رسوم على حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا الدرس التطبيقي حول الترميز، عليك حذف مجموعة البيانات والرسم البياني للعلاقات.

نفِّذ عبارات SQL التالية لتنظيف بيئتك.

DROP PROPERTY GRAPH IF EXISTS fraud_demo.FraudDemo;
DROP SCHEMA IF EXISTS fraud_demo CASCADE;

10. تهانينا

تهانينا! لقد أنشأت بنجاح حلاً لرصد الاحتيال باستخدام BigQuery Graph.

لقد تعلّمت كيفية:

  • تحميل البيانات من Cloud Storage إلى BigQuery
  • تحديد رسم بياني للسمات باستخدام لغة تعريف البيانات (DDL)
  • يمكنك الاستعلام عن الرسم البياني باستخدام GQL للعثور على علاقات بسيطة ومعقّدة.
  • يمكنك الجمع بين تحليل الرسوم البيانية وبيانات النشاط الإعلاني لتحديد المخاطر.
  • تصوُّر الشبكات على نطاق واسع

مزيد من المراجع