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

الوحدة 1 — الفجوة بين التدريب والخدمة وعواقبها

مشهد شائع في فرق التعلّم الآليّ: نموذج تسجيل احتيال يعطي على المصادقة AUC عند 0,94، وبعد أسبوعين من الإنتاج يستقرّ عند 0,86. لم يتغيّر شيء في الشفرة، ولم يتغيّر توزيع المدفوعات. السبب في تسعين بالمائة من الحالات هو فجوة صامتة بين تعريفين للمتغيّر نفسه: واحد في دفتر التدريب، وآخر في خدمة القرار عند نقطة البيع.

متغيّر واحد، تنفيذان

خذ متغيّرًا واحدًا يبدو تافهًا: «عدد المعاملات لهذا العميل في الساعة الماضية».

في دفتر التدريب، تكتب المُهندِسة سطرًا بسيطًا في pandas:

window = df[df["timestamp"] > event_time - pd.Timedelta("1h")]
count_1h = window[window["customer_id"] == cust].shape[0]

في خدمة الإنتاج، يكتب مهندس آخر — بعد ثلاثة أشهر، على استعجال — استعلامًا في Redis:

key = f"tx:{cust_id}:1h"
count_1h = int(redis.get(key) or 0)

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

قياس الفجوة برقم واحد

ما يُنبّه فرقًا عديدة هو الرقم الآتي، الذي سنعيده في مشروع الوحدة 10. نعيد الحساب على مليون معاملة تاريخيّة بـكلا الطريقتين: طريقة الدفتر، وطريقة خدمة Redis كما لو أنّها اتّصلت بالنموذج في الماضي. ثمّ نُقارن قيمة القيمة.

في تجربة حقيقيّة على متجر إلكترونيّ في تونس، وجد الفريق أنّ 14 بالمائة من المعاملات كان لها فارق مُطلَق أكبر من 1 على العدّاد count_1h. النموذج المُدرَّب على نسخة الدفتر ثمّ المخدوم بنسخة Redis كان يستقبل مدخلًا مختلفًا في واحد من كلّ سبع مرّات. AUC انخفض بـ0,06 نقطة، ومعدّل الحجب الخاطئ لعملاء شرعيّين تضاعف ثلاث مرّات: خسارة تجاريّة مباشرة، ليست انحرافًا للمفهوم ولا نموذجًا سيّئًا.

لماذا لا يحلّ التدريب المتكرّر المشكلة

الردّ الشائع هو: «سنُعيد التدريب كلّ ليلة، إذًا سيتكيّف النموذج». هذا خطأ منطقيّ. النموذج يستقبل في الإنتاج مدخلات مختلفة عمّا رأى في التدريب — لا مسألة تحديث بل مسألة اتّساق. إعادة التدريب لا تُصلح فجوة بين حسابين، بل تجمّد نسخة ثابتة من الحساب الخاطئ.

ما يَعِد به مخزن المتغيّرات

الفكرة الجوهريّة بسيطة: تعريف واحد للمتغيّر، تنفيذ واحد، مسؤول واحد، ومُخرَج مضمون متطابق بين الحالتين. المتغيّر يُكتب مرّة، بمنطق ماديّ صريح، ثمّ يُقدَّم بشكلين — قيم تاريخيّة كاملة للتدريب، وأحدث قيمة بزمن استجابة منخفض للخدمة — عبر واجهة واحدة يستدعيها دفتر البيانات ومُخدَم الاستدلال على السواء.

يُدخل هذا ثلاثة مكاسب مباشرة، سنعود إليها بالتفصيل في الوحدات التالية: إلغاء الفجوة بالبناء (لا بالاختبار)، وإعادة الاستعمال بين النماذج (نموذج التسويق يستعمل نفس عدّاد count_1h)، والعقد الواضح بين مالك المتغيّر ومستهلكه (نسخة، دورة تجديد، متطلّبات جودة).

متى لا يستحقّ الأمر

كلّ عدّة تأتي بكلفتها. مخزن المتغيّرات يضيف بنية تحتيّة (Redis أو DynamoDB أو Cassandra للجانب المتّصل، ونظام دُفعات للتجسيد)، ومسؤوليّات (من يملك المتغيّر؟ من يراقبه؟)، وبطء أوّليًّا في الدورة. لا يستحقّ إن كان لديك:

  • نموذج واحد، مُهندسة واحدة، بلا خدمة إنتاجيّة بعد
  • متغيّرات مُشتقّة عند لحظة الاستعلام فقط من المدخلات (بلا تجميع تاريخيّ)
  • تدفّق منخفض جدًّا يسمح بإعادة الحساب في الإنتاج بلا قيد زمنيّ

يستحقّ حين يجتمع اثنان أو أكثر من الأعراض: أكثر من نموذج، تجميعات على نافذة زمنيّة، قيود زمن استجابة صارمة، أو فرق متعدّدة.

الفجوة ليست دائمًا رقميّة

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

الخلاصة

  • الفجوة بين التدريب والخدمة تنشأ حين يُكتب متغيّر مرّتين، فيبدو أنّه نفسه ويكون مختلفًا في تفاصيل صغيرة لها أثر تراكميّ كبير.
  • تُقاس بمقارنة قيمة بقيمة على بيانات تاريخيّة، ولا تُصلحها إعادة التدريب لأنّها ليست انحرافًا زمنيًّا بل خطأ اتّساق.
  • يَعِد مخزن المتغيّرات بـتعريف واحد، تنفيذ واحد، مسؤول واحد، مع تسليم مزدوج للتدريب والخدمة.
  • الحكم على «هل نحتاجه» يقوم على عدد النماذج، ووجود تجميعات نافذة، ومتطلّبات زمن الاستجابة، لا على الموضة.

الوحدة التالية: تشريح مخزن المتغيّرات مكوّنًا مكوّنًا، لنُميّز بين ما هو ضروريّ وما هو خيار تنفيذ.