انتقل إلى المحتوى الرئيسي

الوحدة 5 — المتغيّرات الدورية والتواريخ والمُدد

التاريخ أغنى متغيّرات البيانات الواقعية وأسوأها استغلالًا. فهو بصورته الخامّ غير قابل للاستخدام؛ وإذا فُكّك تفكيكًا جيّدًا حمل موسميّات وعادات أسبوعية وآثارًا تقويمية. وتبيّن هذه الوحدة كيف يُفتَح، ولماذا تشترط حالةٌ خاصّة — الدورات — معالجةً غير متوقّعة.

تفكيك التاريخ: عمود يصير عشرة متغيّرات

الطابع الزمني الخامّ لا يعلّم النموذج شيئًا. فلا بدّ من استخلاص المكوّنات التي تحمل انتظامًا:

df["السنة"]        = df["date"].dt.year
df["الشهر"] = df["date"].dt.month
df["يوم_الأسبوع"] = df["date"].dt.dayofweek # 0 = الاثنين
df["الساعة"] = df["date"].dt.hour
df["نهاية_أسبوع"] = df["يوم_الأسبوع"].isin([5, 6]).astype(int)
df["بداية_شهر"] = (df["date"].dt.day <= 5).astype(int)

ويجيب كلّ متغيّر من هذه عن سؤال عمليّ مختلف: فالسنة تلتقط اتّجاهًا عامًّا، والشهر موسميّة، ويوم الأسبوع عادات استهلاك، والساعة إيقاعات يومية. أمّا المؤشّرات الثنائية (نهاية الأسبوع، بداية الشهر) فتُجسّد آثار حدودٍ لا يجدها النموذج الخطّي وحده.

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

مشكلة الدورات: ديسمبر ويناير جاران

هذا هو الفخّ الخاصّ بالمتغيّرات الزمنية. لنرمّز الشهر من 1 إلى 12. فالفارق عند النموذج بين يناير (1) وديسمبر (12) يساوي 11، بينما هذان الشهران متجاوران في الحقيقة. والمشكلة نفسها بين الحادية عشرة مساءً ومنتصف الليل، أو بين الأحد والاثنين.

والأثر عمليّ: فانتظامٌ يعبر حدّ الدورة — ارتفاع نشاط من ديسمبر إلى يناير — يصير غير مرئيّ، لأنّ النموذج يرى قيمتَين شديدتَي التباعد.

ويحلّ ترميز one-hot من الوحدة 4 المسألة بإلغاء كلّ ترتيب، لكنّه يفقد الاتّصال: فلا يبقى فبراير أقرب إلى يناير منه إلى يوليو. وهذا مقبول في اثني عشر شهرًا، لكنّه غير محتمل في دقائق اليوم.

الترميز الدوري بالجيب والجيب المتمّم

الحلّ الأنيق يضع الدورة على دائرة. فتُحوّل القيمة إلى زاوية ثمّ يُؤخَذ جيبها وجيبها المتمّم:

xsin=sin(2πvP),xcos=cos(2πvP)x_{\sin} = \sin\left(\frac{2\pi v}{P}\right), \qquad x_{\cos} = \cos\left(\frac{2\pi v}{P}\right)

حيث vv القيمة و PP دور الدورة (12 للشهور، و24 للساعات، و7 للأيّام).

import numpy as np
df["شهر_جيب"] = np.sin(2 * np.pi * df["الشهر"] / 12)
df["شهر_متمم"] = np.cos(2 * np.pi * df["الشهر"] / 12)

فيحلّ عمودان محلّ المتغيّر، وتُدرَك الخاصية المطلوبة: إذ يصير ديسمبر ويناير جارَين هندسيًّا على الدائرة، وكذلك أيّ زوج من القيم المتتالية. ولماذا دالّتان لا واحدة؟ لأنّ الجيب وحده مُلتبِس — فهو يأخذ القيمة نفسها عند موضعَين مختلفَين من الدائرة. أمّا زوج الجيب والجيب المتمّم فيحدّد الموضع تحديدًا لا لبس فيه.

ويخدم هذا الترميز النماذج الحسّاسة للمسافات والنماذج الخطّية بصفة خاصّة. أمّا الأشجار، التي تقسم بالعتبات، فتتعامل معه لكنّها تستفيد منه أقلّ: إذ تستطيع عزل «الشهر = 12» بسلسلة من القطوع.

المُدد والحداثة والفوارق: أكثرها تنبّؤًا غالبًا

أنفع المتغيّرات ليست التواريخ نفسها بل الفوارق بين التواريخ. وهي تجيب عن أسئلة عمليّة مباشرةً:

  • القِدَم: عدد الأيّام منذ التسجيل؛
  • الحداثة: عدد الأيّام منذ آخر شراء — وهو حرف R في إطار RFM من الدورة السابقة؛
  • المدّة: الزمن المنقضي بين مرحلتَين من عملية؛
  • الزمن حتّى الحدث: الأيّام المتبقّية قبل انتهاء عقد.
df["القدم_أيام"] = (df["تاريخ_المرجع"] - df["تاريخ_التسجيل"]).dt.days

وثمّة احتراز جوهريّ في تاريخ المرجع. فالنموذج الموجَّه إلى الإنتاج يجب أن يُحسَب فيه القِدَم بالنسبة إلى لحظة التنبّؤ لا إلى تاريخ ثابت من مجموعة التدريب. وإلّا انزلق المتغيّر مع الزمن وتدهور النموذج في الإنتاج في صمت.

أخطر التواريخ ما يأتي بعد الحدث

استخدام تاريخ لاحق للحدث المتنبَّأ به يُنشئ تسرّبًا هائلًا. فالتنبّؤ بهجر الخدمة بمتغيّر «الأيّام منذ آخر تواصل مع خدمة العملاء»، وهذا التواصل يقع أثناء الإلغاء، يعطي نموذجًا تامًّا وغير قابل للاستخدام. فاسأل عن كلّ متغيّر زمنيّ: هل هذا التاريخ معلوم لحظة وجوب التنبّؤ؟ وهذا موضوع الوحدة 8.

الخلاصة

  • التاريخ الخامّ لا يعلّم شيئًا: فكّكه إلى سنة وشهر ويوم أسبوع وساعة، مع مؤشّرات حدود، والأعياد والعطل إن أمكن.
  • ترقيم الدورة يجعل ديسمبر ويناير متباعدَين تعسّفًا، فيحجب الانتظامات العابرة للحدّ.
  • الترميز الدوري بـالجيب والجيب المتمّم يضع الدورة على دائرة فيعيد الجِوار؛ والزوج يرفع لَبس الدالّة الواحدة.
  • الفوارق بين التواريخ (القِدَم والحداثة والمدّة) أكثر المتغيّرات تنبّؤًا غالبًا، وتُحسَب بالنسبة إلى لحظة التنبّؤ.

الوحدة التالية: متغيّرات النصّ، مع حقيبة الكلمات و n-grams وترجيح TF-IDF.