الرقم المرتفع ليس دليلًا
خمسة أشهر في تدريس معامل تنقيب البيانات بجامعة النيل. الـAccuracy المرتفعة جدًا تكون في الغالب معلومة عن التجربة لا عن الموديل — تسريب، أو تنظيف جرى قبل التقسيم، أو سجلات مكرّرة — وردّ الفعل الذي تستحقّه هو الشك لا الاحتفال.
Teaching · Machine learning · Evaluation
تشغيل الكود وإجراء التجربة يبدوان من الخارج شيئًا واحدًا. الـNotebook نفسه، وضغطات المفاتيح نفسها، والرقم نفسه في النهاية. والفرق هو أن يكون ثمّة من يستطيع أن يقول لماذا ينبغي أن يُصدَّق ذلك الرقم — أو ألّا يكون.
قضيت خمسة أشهر معيدًا مساعدًا في جامعة النيل، أدرّس معامل تنقيب البيانات. وكان الهدف من المقرّر ألّا يتعامل الطالب مع الـData Mining باعتباره تدريبَ موديل فقط، بل سلسلةً كاملة: الـPreprocessing، والتحليل الاستكشافي للبيانات، والتصنيف والتجميع، واختيار الـFeatures، وتقييم الموديل — بـPython وPower BI.
كان أغلب الطلاب قد درسوا أساسيات البرمجة والإحصاء. ولم تكن الفجوة في كتابة الكود؛ كانت في سبب كل خطوة، وفي ما تعنيه النتيجة التي ظهرت أمامهم.
الرقم المرتفع أول ما يستحقّ الشك
يطبع الـNotebook نتيجة 99% Accuracy، فيسعد الطالب.
وسعادته ليست في غير موضعها. الرقم المرتفع يشبه تمامًا الغاية التي كان العمل من أجلها. لم يظهر خطأ، وليس في المخرجات ما يقول غير ذلك.
ومع ذلك، فأول ردّ فعل صحيح ليس الاحتفال، بل الشك. في الغالب يكون قد حدث واحد من خمسة أشياء، وليس فيها واحد يُحسَب فضيلةً للموديل.
الـTarget تسرّب إلى الـFeatures: عمود سُجِّل بعد أن صارت النتيجة معروفة، ولا يبدو مختلفًا عن الأعمدة التي بجواره. وحذف عمود لا تفهمه يبدو تهوّرًا أكبر من إبقائه.
أو نُفِّذ الـPreprocessing على الـDataset كلها قبل الـSplit، لأن التنظيف مرة واحدة ثم التقسيم بعده هو الترتيب الطبيعي لأي عمل. يبدو تنظيمًا، لا قرارًا.
أو يشترك الـTraining والـTest في سجلات مكرّرة، ولم يحذف أحد التكرار، لأن سطورًا أكثر تُقرأ على أنها بيانات أكثر.
أو تكون الفئات غير متوازنة، فيتوقّع الموديل الفئة الأكبر في كل مرة، وهو ما يعطي 99% على بيانات نسبتها 99 إلى 1. والـAccuracy هي الرقم الوحيد الذي يخفي ذلك.
أو لم يحدث خطأ من الأساس: هناك Feature واحدة صادقة تفصل الفئات وحدها تقريبًا، والمشكلة لم تكن يومًا بالصعوبة التي بدت عليها.
الرقم المرتفع ليس دليلًا على جودة الموديل. أحيانًا يكون أول دليل على وجود خطأ في التجربة.
السؤال عن الـAlgorithm سؤال ثانٍ
أكثر شيء كنت أصحّحه هو أن يبدأ الطالب بالموديل قبل أن يفهم البيانات. كان السؤال الأول عند كثير منهم: أيّ Algorithm نستخدم؟ والسؤال الأول ليس هذا، بل: ما المشكلة الموجودة في هذه البيانات أصلًا؟ وما الذي نحاول توقّعه أو اكتشافه؟
وتكلفة هذا الترتيب ليست الوقت. تستطيع أن تجرّب خمسة Models من دون أن تقابل العمود الذي يسرّب الإجابة. ولا واحد منها سيذكره. وكلها سترجّع رقمًا.
كل خطوة في الوصفة قرار
يُعامَل الـPreprocessing كأنه قائمة ثابتة: احذف الـNulls، طبّق Encoding، اعمل Scaling، ثم شغّل الموديل. وكل بند فيها قرار قد يغيّر معنى البيانات. حذف الصفوف ذات القيم المفقودة قد يحذف فئة كاملة من المستخدمين — الفئة التي تميل إلى ترك الحقل فارغًا. وملء القيم بالمتوسط قد يصنع قيمة لم تحدث في الواقع. وتحويل الـCategories إلى أرقام قد يجعل الموديل يتعامل معها كأن بينها ترتيبًا لا وجود له، فيقرأ الرقم 3 على أنه أكبر من الرقم 1 على نحو ما.
المشكلة لم تكن يومًا أن الطلاب لا يعرفون الأوامر؛ بل أن الأمر كان يُنفَّذ قبل أن يسأل أحد ما الذي سيفعله بالبيانات.
الامتحان وُزّع قبل بداية الفصل
الـTest Set ليست مجرّد ما لم تستخدمه بعدُ من البيانات. هي محاكاة للمستقبل.
وكنت أشرحها لهم هكذا. تُوزَّع ورقة الامتحان في أول الفصل الدراسي، قبل أن تُشرح المادة. ولا يفتحها أحد أصلًا. ثم يجمع المدرّس كل نسخة، ويضعها في درج مغلق، ويُجلِس الطلاب أنفسهم أمام الورقة نفسها في نهاية الفصل.
ليس هذا امتحانًا عادلًا، ولا يجعله إغلاق الدرج عادلًا. كانت الورقة في القاعة بينما رُتِّب الفصل الدراسي كله حولها. وتلك الأسئلة هي التي حدّدت ما راجعه الطلاب: أيّ الموضوعات شُرِح مرّتين وأيّها مُرَّ عليه مرورًا سريعًا، وأيّ الأمثلة جرى التدريب عليها، وما الذي اختار كل واحد أن يحفظه في الليلة السابقة. ولم يكن أحد بحاجة إلى الغش حتى يكفّ الامتحان عن قياس ما وُضِع لقياسه.
والـTest Set تفقد استقلالها بالطريقة نفسها. تُنظَّف الـDataset كلها، أو يُختار أفضل الـFeatures باستخدامها كاملة، ثم تُقسَّم بعد ذلك. على الورق يوجد Split. لكن عمليًا، معلومات من الاختبار دخلت في بناء التجربة. وسواء تدرّب الموديل على تلك السطور حرفيًا أم لم يتدرّب، فليست تلك هي المسألة — تمامًا كما أن الدرج المغلق ليس هو المسألة.
والنسخة الأهدأ من هذا تقسيم عشوائي لا تحتمله البيانات. سجلات مرتّبة زمنيًا، أو عدة سطور للمستخدم نفسه، تُخلط كأنها سحبات مستقلة، فيصبح الاختبار أقرب إلى بيانات التدريب مما سيكون عليه الواقع.
الـMetric تتبع الخطأ الذي لا تستطيع تحمّله
كان كثير من الطلاب يكتبون الجملة نفسها: «حقّق الموديل Accuracy وPrecision وRecall مرتفعة.» أمّا السؤال عن أيّ الثلاثة أهمّ في هذه المشكلة، ولماذا، فسؤال آخر لا يطرحه شيء في الـNotebook.
والفجوة ليست في حساب الـMetrics، بل في ربطها بتكلفة الخطأ. في الفحص الطبي، قد يكون تفويت حالة إيجابية أخطر من إرسال حالة سليمة إلى مراجعة ثانية. وهذا يجعل الـRecall هو الرقم الذي تدافع عنه، مهما قالت الـAccuracy. وفي كشف الاحتيال، قد تتجاوز الـAccuracy 99% بينما الموديل لم يكتشف أي حالة احتيال تقريبًا، لأن الاحتيال لا يكاد يوجد في البيانات أصلًا.
الـMetric لا تصير ذات معنى إلا حين تستطيع أن تقول: ما الخطأ الذي لا أستطيع تحمّله؟ وقبل ذلك هي رقم طبعه الـNotebook.
تغيير الطبيب من دون تحليل
حين كانت النتيجة تخرج سيئة، كان ردّ الفعل المعتاد تغيير الموديل. Random Forest لم ينجح؟ نجرّب XGBoost. لم يتحسّن؟ نجرّب Neural Network. وهي الخطوة الوحيدة التي تجعلها الأدوات سهلة: يتغيّر سطر واحد، ويبقى كل شيء آخر في مكانه.
وتغيير الـAlgorithm قبل فحص البيانات يشبه تغيير الطبيب من دون إجراء أي تحليل. أولًا تنظر إلى البيانات. هل الـLabels صحيحة؟ هل في هذه الـFeatures ما يحمل معلومة فعلية عن الـTarget؟ هل حجم البيانات كافٍ؟ هل الفئات غير متوازنة؟ هل المشكلة قابلة للتعلّم من هذه البيانات أصلًا؟ وأين تقع الأخطاء بالتحديد؟
ولا واحد من هذه الأسئلة يجيب عنه Algorithm مختلف.
النتيجة السيئة ليست دائمًا فشلًا. أحيانًا تكون أول معلومة صادقة قالتها لك البيانات عن المشكلة.
ليست مشكلة طلاب فقط
من السهل أن يُقرأ ما سبق كله على أنه قائمة بأخطاء الطلاب. وهو ليس كذلك.
عندما يُدرَّس الـData Mining بوصفه سلسلة أوامر جاهزة، من الطبيعي أن يتعلّم الطالب أن النجاح يعني تشغيل الـNotebook والوصول إلى رقم مرتفع. وهذا درس رشيد يُتعلَّم من مقرّر تُرصد درجاته على هذا النحو، ومن يوجّه جهده إلى ما تُرصد عليه الدرجات إنما يفعل ما طُلب منه.
وقد يكافئ المنهج النتيجة النهائية ولا يكافئ جودة التجربة. هل جرى تجنّب الـData Leakage؟ هل كانت الـMetric مناسبة للمشكلة، وهل قُورن الموديل بـBaseline؟ هل حُلِّلت الحالات التي أخطأ فيها، وهل يستطيع الطالب أن يفسّر قراراته؟ كل واحد من هذه الأسئلة يمكن أن تُرصد عليه درجة، ورصدها يغيّر ما يُنفَق فيه الأسبوع. ولا واحد منها يحتاج موديلًا أفضل.
والعمل الذي يثير إعجابي ليس أعلى الأعمال رقمًا، بل العمل الذي لاحظ صاحبه أن النتيجة غير منطقية، فتوقّف وراجع البيانات بدل أن يضع الرقم في العرض.
ولو كنت أصمّم مقرّرًا في الـData Mining، لقلّلت عدد الـAlgorithms التي يمرّ عليها الطالب، ولأعطيته وقتًا أطول بكثير مع Dataset واحدة. تعلّم ثلاثة Models بعمق أفضل من تشغيل عشرة من دون فهم.
التدريس أظهر الأسئلة التي كنت أتجاوزها
فهم الفكرة واستخدامها شيئان مختلفان. كنت أستطيع تنفيذ خطوة في دقائق، لكنّ اضطراري إلى شرح سببها لطالب كان يُظهِر الأسئلة التي كنت أتجاوزها: لماذا هذا الـMetric دون غيره؟ ولماذا كان هذا الـSplit مناسبًا لهذه البيانات؟ وما الافتراض الذي يقوم عليه الموديل؟ وماذا يحدث حين لا يتحقّق؟
وجعلني ذلك أقلّ اهتمامًا بحفظ الأدوات، وأكثر اهتمامًا بالسؤال الذي يسبق استخدامها. والأخطاء التي سبقت هي ما يحدث حين يُتجاوَز ذلك السؤال، وقد كنت أتجاوزه أنا أيضًا.
ثلاثة أشياء قبل أول خلية
العادة التي تستحقّ أن تُكتسب من أول يوم تكلّف دقيقة. قبل تشغيل أي خلية في الـNotebook، اكتب ثلاثة أشياء. السؤال الذي تحاول الإجابة عنه. والنتيجة التي تتوقّعها، ولماذا. والشيء الذي لو ظهر سيجعلك تشكّ في التجربة.
والثاني له إجابة تستطيع حسابها قبل أن تبدأ: الدرجة التي يبلغها موديل يتوقّع الفئة الأكبر في كل مرة. وهو الرقم الذي يجب أن تتجاوزه الـ99%.
والثالث يقوم بمعظم العمل. أن تقرّر مسبقًا ما الذي سيبدو خطأً هو ما يحميك من رقم يصل وهو يشبه النجاح، لأنك عندئذ ستكون راغبًا في تصديقه. إذا كُتِبت من قبل، صارت الـ99% سببًا للتوقّف. وإذا اكتُشِفت بعدها، فهي في الشرائح بالفعل.
ولا يتغيّر شيء آخر في الـNotebook. ضغطات المفاتيح نفسها.
أكبر خطأ في الـData Mining ليس اختيارَ Algorithm ضعيف؛ بل الوصولَ إلى نتيجة قوية لا تستطيع أن تقول لماذا تثق بها.