EduFlow

الوحدة 1 · ما هو تعلّم الآلة

سير العمل وتقسيم بيانات التدريب والاختبار

18 دقراءة 3 دتمرين Python

الدرس في لمحة

حوّل جدول انقطاع العملاء إلى مصفوفة features اسمها X وهدف اسمه y، ثم قسّمه بـ train_test_split لتقيس النموذج على عملاء لم يرَهم قط.

  1. 1سير العمل من البداية إلى النهاية
  2. 2الـ Features والهدف
  3. 3حجز بيانات الاختبار
  4. 4ما الذي يمنحك إياه التقسيم

لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.

النموذج الذي يحقق 99% إما جيد جدًا وإما رأى الإجابات. ولا يمكنك معرفة أيّهما من الرقم وحده. أنفع عادة في تعلّم الآلة هي أن تضع جانبًا بيانات لا يراها النموذج أثناء التدريب، كي يكون لنتيجته عليها معنى.

سير العمل من البداية إلى النهاية

كل مشروع تعلّم موجَّه ستعمل عليه يتبع الحلقة نفسها بشكل عام. الخطوات مملّة عن قصد؛ وتخطّي إحداها هو الطريقة التي تفشل بها المشاريع.

سبع خطوات في حلقة: صياغة السؤال، وجمع بيانات معروفة الإجابة، والتقسيم، وخط الأساس، والتدريب، والتقييم، ثم الإطلاق والمراقبة، مع سهم من التقييم عائد إلى التدريب للتكرار. الصياغة الجمع التقسيم Baseline التدريب التقييم الإطلاق كرّر
سير عمل التعلّم الموجَّه

صُغ السؤال بدقة: ما الذي نتنبأ به، ولمن، وفي أيّ لحظة، وما الإجراء الذي سيتبع التنبؤ. بالنسبة إلى Cartwheel: “في 30 سبتمبر، لكل عميل طلب من قبل، تنبّأ بما إذا كان سيطلب خلال الـ 90 يومًا القادمة، كي يوجّه فريق التسويق عروض الاسترجاع”. اجمع أمثلة معروفة الإجابة: وهذا هو churn.csv. اقتطع جزءًا للاختبار. ابنِ خط أساس (baseline) (بعد درسين). درّب النماذج، وقيّمها، وكرّر، وعندها فقط أطلق النموذج وواصل مراقبته.

الـ Features والهدف

ينتظر scikit-learn شيئين: مصفوفة features اسمها X، فيها صف لكل مثال وعمود لكل feature، وهدفًا y فيه إجابة واحدة لكل صف. الـ DataFrame من pandas يصلح ليكون X، والـ Series يصلح ليكون y.

ستستخدم الآن الأعمدة الرقمية الثمانية. أما الأعمدة النصية مثل country فتحتاج إلى ترميز أولًا (القسم 4 يتولّى ذلك)، وavg_satisfaction فيه فجوات لا تقبلها بعض النماذج بعد.

Python
import pandas as pd

churn = pd.read_csv("churn.csv")
features = ["tenure_days", "orders", "total_spent", "avg_order_value",
            "days_since_last_order", "used_coupon", "support_tickets", "mobile_share"]
X = churn[features]
y = churn["churned"]
print(X.shape, y.shape)
print(y.value_counts())

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

حجز بيانات الاختبار

تخلط train_test_split الصفوف ثم تقسمها إلى جزأين. تدرّب على أحدهما وتقيس على الآخر.

Python
import pandas as pd
from sklearn.model_selection import train_test_split

churn = pd.read_csv("churn.csv")
features = ["tenure_days", "orders", "total_spent", "avg_order_value",
            "days_since_last_order", "used_coupon", "support_tickets", "mobile_share"]
X, y = churn[features], churn["churned"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)
print("train:", X_train.shape, "churn rate", round(y_train.mean(), 3))
print("test: ", X_test.shape, "churn rate", round(y_test.mean(), 3))

ثلاثة معاملات تقوم بالعمل:

  • test_size=0.25 يحجز ربع الصفوف: 100 عميل للاختبار و298 للتدريب. مع بضع مئات من الصفوف، تُعدّ نسبة 20–30% للاختبار معقولة؛ ومع الملايين تكفي 1–5%.
  • random_state=42 يثبّت الخلط فتحصل على التقسيم نفسه في كل تشغيل. وبدونه يُعاد الخلط مع كل تشغيل، فتتأرجح نتيجتك لأسباب لا علاقة لها بنموذجك.
  • stratify=y يُبقي نسبة الانقطاع متساوية في الجزأين (55%). فمع 100 صف للاختبار، قد يعطيك خلط سيئ الحظ بيانات اختبار نسبة الانقطاع فيها 45% أو 62%، وعندها يتغيّر كل رقم تحسبه عليها.

ترتيب القيم الأربع المُعادة ثابت: X_train, X_test, y_train, y_test. والخلط بينها مصدر شائع لنتائج لا معنى لها.

ما الذي يمنحك إياه التقسيم

فكّر في التقسيم على أنه عقد مع نفسك في المستقبل. كل ما تفعله من الآن فصاعدًا (اختيار الـ features، واختيار النماذج، وضبط الإعدادات) يحدث على جزء التدريب. ويبقى جزء الاختبار مختومًا حتى تصبح جاهزًا لنشر نتيجة. بـ X_train وy_train يمكنك تدريب أي نموذج تريده. وبـ X_test وy_test تحصل على إجابة صادقة واحدة عن سؤال “ما مدى نجاح هذا مع عملاء لم يرَهم؟”. هذا هو الرقم الذي يتنبأ بما سيحدث حين يستخدم فريق التسويق نموذجك في ديسمبر. في الدرس القادم ستدرّب أول نموذج وترى كم يمكن أن تكون الفجوة كبيرة بين هذين الرقمين.

أهم النقاط

  • كل مشروع تعلّم موجَّه يسير في الحلقة نفسها: صياغة السؤال، وجمع بيانات معروفة الإجابة، والتقسيم، وخط الأساس، والتدريب، والتقييم، ثم الإطلاق والمراقبة.
  • X جدول من الـ features فيه صف لكل مثال؛ وy هو عمود الإجابات المقابل له.
  • نتيجة النموذج على بيانات تدريبه تقول كم حفظ، لا كم يُحسن التنبؤ.
  • استخدم stratify=y في التصنيف ليحافظ جزءا التدريب والاختبار على توازن الفئات نفسه، وحدّد random_state ليكون التقسيم قابلًا للتكرار.
  • بيانات الاختبار مخصّصة للفحص الأخير؛ والنظر إليها أثناء اتخاذ القرارات يحوّلها إلى بيانات تدريب.

قراءات إضافية

تحقّق من فهمك

4 أسئلة

السؤال 1 من 4

درّبت نموذجًا على كل صفوف بيانات الانقطاع الـ 398، فحقق 0.99 على الصفوف نفسها. ماذا تستنتج؟

السؤال 2 من 4

ما الذي يغيّره stratify=y في train_test_split(X, y, test_size=0.25, stratify=y)؟

السؤال 3 من 4

لماذا نحذف customer_id من الـ features؟

السؤال 4 من 4

جرّبت عشرين إعدادًا للنموذج، واحتفظت بصاحب أفضل نتيجة على بيانات الاختبار، ثم نشرت تلك النتيجة. ما الخطأ؟

تدريب

تمرين Python

ابنِ X وy ثم قسّم البيانات

جهّز بيانات انقطاع العملاء للنمذجة.

  1. X: أعمدة الـ features الرقمية الثمانية: كل شيء ما عدا customer_id وcountry وsegment وavg_satisfaction والهدف.
  2. y: العمود churned.
  3. قسّم البيانات إلى X_train, X_test, y_train, y_test بحيث تكون بيانات الاختبار 25%، مع random_state=42، ومع بقاء نسبة الانقطاع متساوية في الجزأين.

ملفات البيانات: churn.csv

import pandas as pd
from sklearn.model_selection import train_test_split

churn = pd.read_csv("churn.csv")

# 1. Feature matrix: the eight numeric feature columns (no id, no target)
X = churn.drop(columns=["country", "segment", "avg_satisfaction"])
# 2. Target
y = churn["churned"]

# 3. Split: 25% test, random_state=42, keep the churn rate equal in both parts
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
جارٍ تحميل المحرّر…

Ctrl/⌘ + Enter للتشغيل · يعمل في بيئة معزولة داخل متصفّحك. لا شيء يغادر جهازك.

(لا مخرجات)

الفحوص

  • يحتوي X على الـ features الرقمية الثمانية بالضبط
  • y هو العمود churned (398 قيمة من 0 و1)
  • 298 صفًا للتدريب و100 صف للاختبار
  • يحافظ جزءا التدريب والاختبار على نسبة الانقطاع الكلية