الوحدة 3 — البيانات على Cloud Storage وBigQuery
الوحدتان السابقتان جهّزتا المشروع والدفتر. هذه الوحدة تُنشئ العمود الفقريّ للبيانات: أين تعيش المعاملات الخامّة، كيف تتحوّل إلى خصائص جاهزة للتدريب، وكيف تُقدَّم إلى Vertex AI بشكل مُوثَّق قابل لإعادة الاستعمال. القرارات هنا تتحكّم بأداء التدريب وكلفته للأشهر المقبلة.
دلوان لهدفين مختلفين
Cloud Storage (GCS) هو نظام الملفّات الشيئيّ. للفيل الأحمر نُنشئ دلوين:
gsutil mb -l europe-west1 -c standard gs://fraud-features-lab
gsutil mb -l europe-west1 -c standard gs://fraud-models-lab
# دورة حياة: نُبقي إصدارات نموذج 90 يومًا
gsutil lifecycle set lifecycle.json gs://fraud-models-lab
القاعدة: دلو لكلّ نوع فنّيّ. الخلط بين الميزات والنماذج والسجلّات في دلو واحد يُصعّب سياسات الاحتفاظ، يُشوِّش الفواتير، ويُعقِّد سياسات IAM. سياسة اليوم على النماذج (احتفاظ 90 يومًا) تختلف عن سياسة السجلّات (احتفاظ 30 يومًا) وعن سياسة الميزات المشتركة (احتفاظ دائم مع نسخة إقليميّة ثانية).
فئات التخزين: standard للاستعمال اليومي؛ nearline بعد 30 يومًا؛ coldline بعد 90؛ archive بعد سنة. lifecycle.json أدناه ينقل ملفّات النماذج القديمة تلقائيًّا:
{
"lifecycle": {
"rule": [
{"action": {"type": "SetStorageClass", "storageClass": "NEARLINE"},
"condition": {"age": 30}},
{"action": {"type": "Delete"}, "condition": {"age": 365}}
]
}
}
تنسيقات الملفّات: Parquet قبل CSV
لأيّ مجموعة بيانات جدوليّة أكبر من بضعة ميغابايت، Parquet هو الخيار الافتراضيّ:
- ضغط عموديّ بكفاءة عالية (ثلث حجم CSV بالمتوسّط).
- قراءة عمود واحد لا تستدعي قراءة الجدول كلّه.
- الأنواع (تاريخ، عدد صحيح، منطقيّ) محفوظة، لا تُفقَد كما في CSV.
في الفيل الأحمر، جدول المعاملات (2 مليار سطر تاريخيًّا) بCSV يزن نحو 700 غيغا، وبParquet نحو 220 غيغا مع كسب سرعة قراءة عشرين ضعفًا.
CSV يبقى مبرَّرًا حين يستقبل الملفّ نظامٌ لا يقرأ Parquet (مثل تصدير إلى تطبيق قديم). داخل السلسلة التقنيّة كلّها، Parquet دائمًا.
من BigQuery إلى إطار بيانات
BigQuery هو مستودع التحليل الذي يستقبل الأحداث الخامّة من نظام الدفع. الجدول الأساسيّ للفيل الأحمر:
fraud-detection-lab.transactions.raw
- event_ts TIMESTAMP
- card_hash STRING
- amount NUMERIC
- merchant_country STRING
- device_id STRING
- is_fraud BOOL (توسيم مصرفيّ يصل بتأخّر أسبوع)
استخراج البيانات إلى ذاكرة الدفتر:
from google.cloud import bigquery
client = bigquery.Client(project="fraud-detection-lab")
sql = """
SELECT
card_hash,
amount,
merchant_country,
device_id,
IF(is_fraud, 1, 0) AS y
FROM `fraud-detection-lab.transactions.raw`
WHERE DATE(event_ts) BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
AND DATE_SUB(CURRENT_DATE(), INTERVAL 8 DAY)
"""
df = client.query(sql).to_dataframe(create_bqstorage_client=True)
ملاحظتان بالغتا الأهمّية:
INTERVAL 8 DAYعلى الحدّ الأعلى: التوسيم يصل متأخّرًا أسبوعًا (تحكيم النزاعات)، فأخذ آخر يوم يعني تدريبًا على بيانات ناقصة التوسيم. هذه فخّ من فخاخ MLOps الكلاسيكيّة.- مسح الفهرس الزمنيّ:
DATE(event_ts)يمنع BigQuery من استعمال تقسيم الجدول علىevent_tsبكفاءة، إن كان مقسَّمًا. البديل الأداءيّ الأصحّ:event_ts >= TIMESTAMP_SUB(...)بدلDATE(event_ts) >= ....
تصدير مباشر إلى GCS
لتفادي تمرير مليونَي سطر عبر ذاكرة الدفتر، يُفضَّل التصدير المباشر من BigQuery إلى Parquet على GCS، ثمّ قراءتها في التدريب:
EXPORT DATA OPTIONS(
uri='gs://fraud-features-lab/features/2026-09-05/*.parquet',
format='PARQUET',
compression='SNAPPY',
overwrite=true
) AS
SELECT ... FROM `fraud-detection-lab.transactions.raw` WHERE ...
نتيجة الاستعلام تُقسَّم على عدّة ملفّات (تُشير إليها * في المسار)، ما يُتيح للتدريب قراءتها بالتوازي.