الوحدة 1 — ما يميّز السلسلة الزمنية عن سائر البيانات
الكثير من الأخطاء في التنبّؤ لا تأتي من نموذج ضعيف بل من التعامل مع سلسلة زمنية كما لو كانت بيانات جدولية عاديّة. تُخصَّص هذه الوحدة لبناء الفروق الجوهريّة قبل أيّ سطر من الكود، ولإحضار الخيط الأحمر: الطلب اليوميّ لشبكة صيدليّات على أربع سنوات، الذي سنتنبّأ به على أفق 28 يومًا.
التبعيّة الزمنية تُغيّر الفرضيّة الأساسيّة
في التعلّم المُشرَف الكلاسيكيّ نفترض أنّ المشاهدات مستقلّة ومتماثلة التوزيع. وهذه الفرضية هي التي تُبرّر خلط البيانات قبل التقسيم، وحساب متوسّط الأخطاء كأنّها معاينات مستقلّة، وتقدير التعميم بتحقّق متقاطع طيّاتٍ عشوائيّة. أمّا في السلسلة الزمنية فليس شيء من ذلك صحيحًا. مبيعات اليوم تعتمد على مبيعات الأمس، وعلى موسم السنة، وعلى ما إذا كانت العطلة قريبة أو بعيدة. الترتيب هو المعلومة الأولى، وحذفه بخلطٍ ما يُدمّر الإشارة قبل أن يبدأ التدريب.
يتجلّى ذلك بمثال بسيط: إذا كانت سلسلة المبيعات تنمو مع الوقت (اتّجاه صاعد)، وخلطنا الصفوف ثمّ درّبنا نموذجًا يتوقّع مبيعات يوم مجهول، فإنّ متوسّط سنة 2027 يصبح متاحًا لتوقّع يوم من سنة 2024. هذا تسرّب المستقبل: النموذج يعرف ما لم يكن ليعرفه في الإنتاج، والنتيجة أداء وهميّ في الاختبار وانهيار عند النشر.
التردّد والأفق والدقّة الزمنية
كلّ سلسلة زمنية تُعرَّف بثلاث حجرات:
- تردّد أخذ العيّنات: يوميّ، أسبوعيّ، شهريّ، بالساعة… لا نبني نموذجًا على تردّد لا يعنين ا. مبيعاتنا أُخذت يوميًا، فسنعمل يوميًا.
- أفق التنبّؤ: عدد الخطوات المستقبليّة المطلوبة. عندنا 28 يومًا. توقّع اليوم القادم مسألة، وتوقّع 28 يومًا مسألة أصعب بكثير، ومقاييس التقييم يجب أن تعكس ذلك.
- الدقّة: هل نريد رقمًا يوميًا لكلّ صيدليّة، أم مجموعًا وطنيًا؟ نُصعّد أو نُنزّل حسب الحاجة، لكنّ التنبّؤ بالتجميع أسهل من التنبّؤ بمكوّناته، فلا نخلط.
التقسيم دون خلط: قاعدة لا تُنقض
من أوّل قرار عمليّ إلى آخر تقييم، لا نخلط أبدًا سلسلة زمنية. التقسيم يجرى بالترتيب: كلّ ما جاء قبل تاريخ معيَّن للتدريب، وما جاء بعده للتحقّق، وما جاء بعد ذلك للاختبار. ولا يُختار تاريخ الفصل عشوائيًا، بل يُوضع بحيث يترك للاختبار عددًا من الأفق الكامل يكفي للحكم.
import pandas as pd
df = pd.read_csv("ventes_pharmacies.csv", parse_dates=["date"])
df = df.sort_values("date").reset_index(drop=True)
# قاعدة الوحدة 1: التقسيم بالترتيب، بلا خلط.
date_fin_tr = "2027-06-30"
date_fin_val = "2027-08-31"
df_tr = df[df["date"] <= date_fin_tr]
df_val = df[(df["date"] > date_fin_tr) & (df["date"] <= date_fin_val)]
df_te = df[df["date"] > date_fin_val]
print(df_tr["date"].min(), "→", df_tr["date"].max(), " | تدريب :", len(df_tr))
print(df_val["date"].min(), "→", df_val["date"].max(), " | تحقّق :", len(df_val))
print(df_te["date"].min(), "→", df_te["date"].max(), " | اختبار :", len(df_te))
الوحدة 9 ستعود إلى هذا التقسيم لتحوّله إلى تحقّق متدرّج بأصول متعدّدة، وهو الطريقة الحقيقيّة لقياس أداء نموذج تنبّؤ. لكنّ التقسيم أعلاه هو الحدّ الأدنى، وأيّ تنازل عنه يُبطل التقييم من أوّله.
فخّ تسرّب المستقبل يتّخذ أشكالًا كثيرة
بخلاف التصنيف الجدوليّ، حيث تسرّب المتغيّرات نادرًا ما يكون خفيًّا، تسرّب المستقبل في السلاسل الزمنية يمرّ من مسالك متعدّدة يجب أن نتعلّم اكتشافها:
- تسوية عالميّة: حساب متوسّط وانحراف على كامل السلسلة لتوحيدها قبل التقسيم. الحلّ: تُحسَب الإحصائيّات على التدريب وحده، ثمّ تُطبَّق على التحقّق والاختبار.
- متغيّرات مُشتقّة من الهدف: مثل «متوسّط المبيعات في الأسبوع» محسوبًا من نافذة تعبر الحاضر. الحلّ: نستعمل حصريًا متغيّرات مؤخّرة (تأخّرات) لا تنظر إلى الأمام.
- متنبّئات خارجية غير معروفة في الإنتاج: مثل استعمال «مبيعات المنافس اليوم» لتنبّؤ اليوم نفسه، بينما المنافس لن يُخبرنا. الوحدة 7 مخصّصة لهذا التمييز الحاسم.
- اختيار وسائط فائقة على مجموعة الاختبار: كلاسيكيّ. الوسائط تُختار على التحقّق، والاختبار لا يُلمس إلّا مرّة واحدة في النهاية.
قبل تشغيل أيّ نموذج، أنشئ هدفًا اصطناعيًا: توقّع «متوسّط السلسلة كلّها». إن كان نموذجك يهزم هذه القاعدة على مجموعة الاختبار الزمنية بأداء مثاليّ، فأنت أمام تسرّب مستقبل شبه مؤكّد. راجع طريقة اشتقاق المتغيّرات قبل الاستمرار.
مفردات صغيرة تُوفّر ساعات
قبل الانتقال إلى الوحدة التالية، لنُثبّت مصطلحات سترافقنا: الاتّجاه (trend) هو الحركة البطيئة على المدى الطويل؛ والموسميّة (seasonality) هي النمط الدوريّ ذو الطول الثابت (7 أيّام أسبوعيًا، 365 يومًا سنويًا)؛ والدورة (cycle) هي تذبذب بطول متغيّر لا مرتبط بالتقويم؛ والضجيج (noise) هو ما يبقى بعد نزع الثلاثة. والتأخّر (lag) k هو قيمة السلسلة قبل k خطوات، وسيكون أشيع أداة في هذه الدورة. أمّا الأفق (horizon) H فهو عدد الخطوات المستقبليّة التي نتنبّأ بها في مرّة واحدة.
الخلاصة
- في السلسلة الزمنية، الترتيب معلومة؛ فرضيّة الاستقلال في التعلّم المُشرَف لا تنطبق ولا يجوز خلط الصفوف.
- ثلاث حجرات تُعرِّف كلّ مسألة: التردّد والأفق والدقّة؛ نضبطها قبل النموذج، لا بعده.
- التقسيم يجري بالترتيب؛ ويحسم مبكرًا موقع تاريخي الفصل، وسنُوسّعه إلى تحقّق متدرّج في الوحدة 9.
- تسرّب المستقبل يتخفّى في التسوية العالميّة، والمتغيّرات المُشتقّة من الهدف، والمتنبّئات غير المتاحة في الإنتاج؛ اكتشافه مبكرًا يُنقذ المشروع.
الوحدة التالية: نُفكِّك الإشارة إلى اتّجاه وموسميّة وبواقٍ، ونتعلّم قراءة كلّ مكوّن على حدة.