الوحدة 3 — البيانات على S3 ومخزن الميزات
كلّ مهمّة تدريب داخل SageMaker تبدأ بسؤال واحد: أين البيانات؟ الإجابة الافتراضيّة هي Amazon S3. تشرح هذه الوحدة كيف تنظّم بيانات نموذج التسرّب لتصمد خمس سنوات من تجارب متعاقبة، ولماذا يبقى Feature Store استثمارًا مؤجّلًا حتّى تصير الفرق متعدّدة.
S3 ليست قاعدة بيانات، بل نظام ملفّات كائنيّ
S3 يخزّن كائنات داخل دلاء (buckets)، مع مفاتيح تشبه مسارات الملفّات. لا وجود لجداول ولا لفهارس، بل قراءة/كتابة بايتات خام. لذا فتنظيم المفاتيح هو ما يعوّض غياب الاستعلامات. اصطلاح صالح لخيطنا الأحمر:
s3://<bucket>/churn/
├── raw/ 2024-01-01/telecom.csv # البيانات كما وُصلت
├── raw/ 2024-06-15/telecom.csv # لقطة جديدة
├── processed/ v1/train.parquet # بعد التنظيف الأوّل
├── processed/ v1/valid.parquet
├── processed/ v2/train.parquet # نسخة معالجة جديدة
├── models/ xgboost-2024-07-01/model.tar.gz # مخرَج تدريب
└── predictions/ 2024-07/batch-scores.parquet # نتائج التسجيل
القاعدة الوحيدة: لا تكتب على raw/ أبدًا. البيانات الخامّ لا تُعدَّل، بل تُنسخ إلى processed/ بعد المعالجة. هذه القاعدة توفّر أسابيع من التنقيب في السجلّات عندما يسأل شخص «من أين جاء هذا العمود بالضبط؟».
CSV يوم الاستكشاف، Parquet يوم الإنتاج
يُغري CSV لأنّ أيّ محرّر نصوص يقرأه. لكنّه أسوأ صيغة ممكنة للتعلّم الآليّ في مقياس كبير:
- كلّ عمود مخزَّن كنصّ، فيصير قراءته يستلزم تحويلًا تلقائيًّا مخاطرًا (
"01"سلسلة أم عدد؟) - لا ضغط
- لا يمكن قراءة عمود واحد دون قراءة الملفّ كلّه
Parquet يعالج الثلاث دفعةً واحدة: تخزين عموديّ مع أنواع مضبوطة، وضغط snappy افتراضيّ يقلّص الحجم بعامل 5 إلى 10، وقراءة عمود منفرد بلا الاحتياج لبقيّة الجدول. لجدول التسرّب المكوّن من 100 ألف سطر:
import pandas as pd
df = pd.read_csv("s3://churn/raw/2024-01-01/telecom.csv")
df.to_parquet(
"s3://churn/processed/v1/train.parquet",
engine="pyarrow",
compression="snappy",
index=False,
)
يجب أن يكون هذا التحويل خطوة ثابتة عندك بمجرّد أن يعبر حجم البيانات بضع مئات من الميغابايت.
التشفير: ما لا ينبغي أن يكون خيارًا
على S3، التشفير في الاستراحة (at rest) مجّانيّ وشفّاف. لا يوجد سبب معقول لتركه معطّلًا. خياران:
- SSE-S3 (AES-256): مفتاح تديره AWS. اختيار افتراضيّ حسن.
- SSE-KMS: مفتاح تديره في AWS KMS. أفضل عندما تحتاج إلى تسجيل من يفكّ التشفير ومتى، أو إلى دور IAM مختلف من دور القراءة.
اضبط التشفير على مستوى الدلو كلّه لا كلّ كائن على حدة:
import boto3
s3 = boto3.client("s3")
s3.put_bucket_encryption(
Bucket="my-churn-bucket",
ServerSideEncryptionConfiguration={
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "alias/churn-key",
}
}],
},
)
مفتاح إضافيّ من ملف السياسة (Bucket Policy): رفض قراءة/كتابة أيّ اتّصال غير HTTPS. سطر واحد يُغلق باب اعتراض الشبكة نهائيًّا.
SageMaker Feature Store: متى، ولماذا يُؤجَّل غالبًا
الفكرة بسيطة: مخزن ميزات مركزيّ يضمن أنّ متغيّر «متوسّط استهلاك الشهر الأخير» يُحسب بنفس الصيغة في التدريب والإنتاج. Feature Store يوفّر:
- متجرًا متّصلًا (Online Store): DynamoDB مُدار للقراءة بميليثوانٍ عند التوقّع في الوقت الحقيقيّ.
- متجرًا غير متّصل (Offline Store): مجلّد S3 بصيغة Parquet مقرونة بميزة الوقت للتدريب والتحليل.
للفريق الواحد ذي النموذج الواحد، Feature Store استثمار مبالغ فيه: مجلّد S3 منظّم يفي بالغرض. يصير الاستثمار مبرَّرًا حين:
- عدّة نماذج (احتيال، تسرّب، توصية) تستهلك نفس الميزة.
- التباعد بين التدريب والخدمة (training-serving skew) صار مشكلة موثّقة في الإنتاج.
- المؤسّسة تريد تسجيلًا للتحكّم في من يستعمل أيّ ميزة.
سنعود إلى Feature Store بتفصيل أكبر في الدورة 33 (متاجر الميزات)؛ اكتفِ في هذه الدورة بمعرفة متى ينبغي التفكير فيه.
قراءة البيانات في مهمّة التدريب
عندما ننتقل إلى الوحدة 4 (مهامّ التدريب)، لن تُقرأ البيانات مباشرةً من داخل الدفتر. ستُمرَّر إلى المهمّة عبر قنوات (channels):
from sagemaker.inputs import TrainingInput
train_input = TrainingInput(
s3_data="s3://my-churn-bucket/churn/processed/v1/train.parquet",
content_type="application/x-parquet",
)
valid_input = TrainingInput(
s3_data="s3://my-churn-bucket/churn/processed/v1/valid.parquet",
content_type="application/x-parquet",
)
TrainingInput يبلّغ SageMaker: «انسخ هذا المسار من S3 إلى /opt/ml/input/data/train/ داخل الحاوية قبل تشغيل الشيفرة». التنظيم الجيّد لمجلّدات S3 يُترجم هنا مباشرةً إلى شيفرة أوضح.
TrainingInput(input_mode="File") ينسخ كلّ البيانات إلى الع تاد قبل البدء (افتراضيّ، مناسب للأحجام الصغيرة). input_mode="FastFile" يبثّ عند القراءة، مفيد لملفّات ضخمة. لأحجامنا (بضع مئات من الميغابايت) الوضع الافتراضيّ يكفي وأبسط.
الخلاصة
- نظّم دلو S3 بمسارات معنويّة (
raw/,processed/v1/,models/)؛ لا تعدّل الخام أبدًا. - Parquet مضغوط يفوق CSV في الحجم وسرعة القراءة، اعتمده بمجرّد أن تعبر عتبة بضع مئات من الميغابايت.
- شفّر الدلو بـSSE-S3 أو SSE-KMS، ومنع أيّ اتّصال HTTP في السياسة.
- Feature Store استثمار يُبرَّر عند نماذج متعدّدة أو تباعد تدريب/خدمة موثّق؛ اكتفِ حتّى ذلك بمجلّد S3 منظّم.
الوحدة التالية: مهامّ التدريب المُدارة وحاوية XGBoost المدمجة على نفس البيانات.