كنا نغرق في بحر البيانات: كيف أنقذنا ‘الإشراف الضعيف’ (Weak Supervision) من جحيم التسمية اليدوية؟

يا جماعة الخير، السلام عليكم ورحمة الله.

اسمحولي اليوم أحكيلكم قصة صارت معي ومع فريقي قبل فترة، قصة فيها شوية يأس، وشوية قهوة، وكثير من الكود. كنا شغالين على مشروع طموح لتحليل مشاعر العملاء لمنتج جديد، وعندنا كنز… أو بالأحرى، جبل ضخم من البيانات: مئات الآلاف من التعليقات والمراجعات على وسائل التواصل الاجتماعي ومنتديات النقاش. المشكلة؟ كلها بيانات خام، غير مسماة (unlabeled). يعني مجرد نصوص مرمية قدامنا، ما بنعرف أيها إيجابي وأيها سلبي.

اجتمعنا في المكتب، والكل متحمس. واحد من الشباب، الله يجزيه الخير، فتح ملف إكسل وبدأ يحسب: “لو كل واحد فينا سمّى (label) ٥٠٠ تعليق في اليوم… وبافتراض إنه ما أكلنا ولا شربنا ولا نمنا… بنخلص بعد ٨ شهور!”.

ساد صمت رهيب في الغرفة. ٨ شهور؟ والمشروع لازم يتسلم بعد شهرين! وقتها حسيت حالي بغرق حرفيًا. كل هاي البيانات اللي المفروض تكون كنز، تحولت لعبء ثقيل. فكرة إني أقضي أنا وفريقي شهور طويلة في عمل روتيني ممل ومضنٍ زي تسمية البيانات كانت كابوس. زي ما بنحكي عنا في فلسطين، “شغلانة بتجيب الجلطة”.

في ليلة من الليالي، وأنا بقلّب في الأوراق البحثية وبشرب فنجان القهوة الثالث، لمحت مصطلح ما كان جديد عليّ، بس عمري ما جربته بشكل جدي: Weak Supervision أو “الإشراف الضعيف”. قرأت عنه أكثر، وشعرت بشعاع من الأمل. هل ممكن يكون هذا هو طوق النجاة اللي بنستناه؟ هل ممكن نعلّم الآلة بدون ما نكون إحنا نفسنا “المعلمين” اللي بنصحح كل واجب؟

ومن هنا بدأت رحلتنا اللي بدي أشارككم تفاصيلها اليوم. رحلة أنقذتنا من جحيم التسمية اليدوية وفتحت عيوننا على طريقة تفكير جديدة كليًا في التعامل مع البيانات.

ما هو الإشراف الضعيف (Weak Supervision)؟ وليش هو طوق النجاة؟

عشان نفهم الإشراف الضعيف، خلينا نرجع خطوة لورا. في عالم تعلم الآلة، الطريقة التقليدية هي “التعلم المُشرَف” (Supervised Learning). تخيل إنك بتعلّم طفل صغير يميز بين القطط والكلاب. بتجيبله آلاف الصور (بيانات)، وبتقوله على كل صورة: “هاي قطة”، “هذا كلب” (تسميات – labels). بعد فترة، بيصير الطفل قادر يميز لحاله. هاي الطريقة ممتازة، بس مشكلتها إنها بتحتاج “مُشرِف” (إنت) يقعد يسمّي كل صورة وصورة. وهذا هو بالضبط عنق الزجاجة في 90% من مشاريع الذكاء الاصطناعي اليوم: توفير بيانات مُسماة بجودة عالية وبكميات كبيرة.

الإشراف الضعيف بيجي ويقول: “طيب، شو رأيك لو ما اعتمدنا على مُشرِف واحد خبير، واعتمدنا على مجموعة من “المساعدين” اللي كل واحد فيهم عنده فكرة عن الموضوع، بس مش خبير 100%؟”.

الإشراف الضعيف هو جسر بين عالمين:

  • التعلم المُشرَف (Supervised Learning): يحتاج بيانات مسماة بدقة 100%، وهذا مكلف وبطيء.
  • التعلم غير المُشرَف (Unsupervised Learning): لا يحتاج أي تسميات، ولكنه غالبًا ما يُستخدم لاكتشاف الأنماط وليس للمهام التصنيفية المحددة.

الإشراف الضعيف هو فن استخدام مصادر تسمية “ضعيفة” (noisy)، “غير دقيقة”، أو “غير مباشرة” لإنشاء تسميات احتمالية (probabilistic labels) لكميات هائلة من البيانات، ومن ثم استخدام هذه التسميات لتدريب نموذج تعلم آلة قوي.

الفكرة عبقرية ببساطتها: بدلًا من السعي وراء الكمال في كل تسمية، نحن ن abraza (نحتضن) الفوضى والضوضاء، ونبني نظامًا يستخلص الحقيقة من بينها.

كيف بنولّد هاي التسميات “الضعيفة”؟ مصادر القوة في ضعفها

هنا يكمن جوهر الموضوع. من وين نجيب هاي التسميات “الضعيفة” أو “غير الدقيقة”؟ المصادر كثيرة، والإبداع هو سيد الموقف. هذه بعض الطرق اللي استخدمناها وما زلنا نستخدمها:

1. الوظائف الكاشفة (Labeling Functions – LFs): قلب الإشراف الضعيف النابض

هذا هو السلاح السري والأقوى. الوظيفة الكاشفة هي ببساطة دالة برمجية (مجموعة من الأكواد) بتكتبها بنفسك عشان تحاول تخمن تسمية نقطة البيانات. هي عبارة عن قاعدة بسيطة أو “حدس” برمجي. لا يشترط أن تكون صحيحة دائمًا، وهذا هو جمالها!

في مشروعنا لتحليل المشاعر، كانت بعض وظائفنا الكاشفة كالتالي:

  • LF based on Keywords: لو النص بيحتوي على كلمات مثل “ممتاز”، “رائع”، “شكراً”، “مبدعين”، فمن المرجح أنه إيجابي.
  • LF based on Negative Keywords: لو النص بيحتوي على كلمات مثل “سيء”، “مشكلة”، “بطيء”، “للأسف”، “خيبة أمل”، فمن المرجح أنه سلبي.
  • LF based on Regular Expressions: كنا نبحث عن أنماط معينة، مثل وجود علامتي استفهام أو أكثر مع كلمة “متى” (مثل “متى يوصل الطلب؟؟”)، وهذا قد يدل على استفسار أو عدم رضا (سلبي).
  • LF based on an External Model: استخدمنا نموذج تحليل مشاعر جاهز (pre-trained)، لكنه لم يكن دقيقًا للهجتنا العامية. بدلًا من اعتماده كحل نهائي، استخدمناه كوظيفة كاشفة! يعطينا تخمينًا، ونحن نأخذه بعين الاعتبار مع باقي الوظائف.

الفكرة هي أن تكتب العديد من هذه الوظائف، كل واحدة تغطي جانبًا صغيرًا من المشكلة. كل وظيفة كاشفة هي “خبير ضعيف” يساهم برأيه.

2. الاستدلال على البنية (Harnessing Data Structure)

أحيانًا، البيانات نفسها تحمل أدلة. في بعض المواقع، تجد أقسامًا مثل “قسم الشكاوى” أو “قسم الشكر والتقدير”. أي تعليق يُنشر في قسم الشكاوى هو على الأغلب سلبي. هذه معلومة هيكلية يمكن تحويلها لوظيفة كاشفة قوية جدًا.

3. الاستعانة بمصادر خارجية (Crowdsourcing) ولكن بذكاء

يمكن استخدام منصات مثل Amazon Mechanical Turk للحصول على تسميات من البشر. لكن بدلًا من أن تطلب من 3-5 أشخاص تسمية كل عنصر لضمان الجودة (وهذا مكلف)، يمكنك أن تطلب من شخص واحد فقط تسمية كل عنصر. النتيجة ستكون “ضعيفة” وغير موثوقة 100%، لكنها مصدر آخر من مصادر الإشراف الضعيف.

من الفوضى إلى النظام: نموذج التسمية (Label Model)

طيب يا أبو عمر، صار عنا لكل تعليق مجموعة من التسميات المتضاربة من وظائفنا الكاشفة. وحدة بتقول “إيجابي”، والثانية بتقول “سلبي”، والثالثة ما عندها رأي (abstain). شو نعمل بهاي الفوضى؟

هنا يأتي دور “نموذج التسمية” (Label Model). هذا هو العقل المدبر للعملية. هو نموذج إحصائي (غالبًا ما يكون نموذجًا توليديًا – generative model) يقوم بالآتي:

  1. يأخذ مخرجات جميع الوظائف الكاشفة لكل نقاط البيانات.
  2. يحلل أداء هذه الوظائف: يكتشف أيها أكثر دقة، وأيها يميل إلى التصويت معًا، وأيها يميل إلى التعارض.
  3. “يوازن” بين آراء كل الخبراء الضعفاء، ويعطي وزنًا أكبر للوظائف التي يثق بها أكثر.
  4. في النهاية، يُنتج تسمية واحدة “موحدة” لكل نقطة بيانات. لكنها ليست تسمية قاطعة (إيجابي/سلبي)، بل هي تسمية احتمالية (مثلاً: 90% إيجابي، 10% سلبي).

هذه التسميات الاحتمالية هي الذهب الخالص. الآن أصبح لدينا مئات الآلاف من التعليقات، وكل تعليق لديه تسمية احتمالية تم إنشاؤها تلقائيًا. لقد حولنا البيانات الخام غير المسماة إلى بيانات مسماة “بشكل ضعيف” ولكن بكمية هائلة.

مثال عملي: من الكود إلى النتيجة (مع مكتبة Snorkel)

الكلام النظري جميل، لكن “الحكي ما بيطعمي خبز”. خلينا نشوف كيف ممكن نطبق هذا الكلام عمليًا باستخدام مكتبة بايثون الشهيرة في هذا المجال: Snorkel.

تخيل أن لدينا DataFrame في Pandas اسمه df_unlabeled يحتوي على عمود text.


# استيراد المكتبات اللازمة
from snorkel.labeling import labeling_function, PandasLFApplier, LabelModel
from snorkel.labeling.model import MajorityLabelVoter

# تعريف الثوابت للتسميات
ABSTAIN = -1
NEGATIVE = 0
POSITIVE = 1

# --- الخطوة 1: كتابة الوظائف الكاشفة (Labeling Functions) ---

@labeling_function()
def contains_positive_keyword(x):
    """إذا احتوى النص على كلمات إيجابية"""
    positive_keywords = ["ممتاز", "رائع", "شكرا", "جميل"]
    return POSITIVE if any(word in x.text.lower() for word in positive_keywords) else ABSTAIN

@labeling_function()
def contains_negative_keyword(x):
    """إذا احتوى النص على كلمات سلبية"""
    negative_keywords = ["سيء", "مشكلة", "بطيء", "خيبة"]
    return NEGATIVE if any(word in x.text.lower() for word in negative_keywords) else ABSTAIN

@labeling_function()
def text_length_is_short(x):
    """النصوص القصيرة جدا (أقل من 3 كلمات) غالبا ما تكون سلبية أو شكاوى"""
    return NEGATIVE if len(x.text.split()) < 3 else ABSTAIN

# قائمة بكل الوظائف الكاشفة
lfs = [contains_positive_keyword, contains_negative_keyword, text_length_is_short]

# --- الخطوة 2: تطبيق الوظائف الكاشفة على البيانات غير المسماة ---
applier = PandasLFApplier(lfs=lfs)
L_train = applier.apply(df=df_unlabeled)

# L_train الآن هي مصفوفة تحتوي على تسميات من كل وظيفة لكل نقطة بيانات

# --- الخطوة 3: تدريب نموذج التسمية (Label Model) ---
# سيقوم هذا النموذج بتعلم دقة كل وظيفة كاشفة والترابط بينها
label_model = LabelModel(cardinality=2, verbose=True)
label_model.fit(L_train=L_train, n_epochs=500, log_freq=100, seed=123)

# --- الخطوة 4: الحصول على التسميات الاحتمالية ---
# هذا هو الخرج النهائي من عملية الإشراف الضعيف
probs_train = label_model.predict_proba(L=L_train)

# الآن لدينا 'probs_train' وهي مصفوفة احتمالات يمكننا استخدامها لتدريب أي نموذج نهائي

# --- الخطوة 5: تدريب النموذج النهائي (Discriminative Model) ---
# على سبيل المثال، يمكننا استخدام هذه الاحتمالات لتدريب نموذج XGBoost أو شبكة عصبونية
# from sklearn.linear_model import LogisticRegression
#
# # يمكننا تحويل الاحتمالات إلى تسميات قوية لتدريب نموذج أبسط
# labels_train = label_model.predict(L=L_train)
#
# final_model = LogisticRegression()
# final_model.fit(X=df_unlabeled['text_features'], y=labels_train) # تحتاج لتحويل النص إلى ميزات (features) أولاً

بهذه الخطوات، حولنا مشكلة استغرقت 8 أشهر من العمل اليدوي إلى بضع مئات من أسطر الكود وعملية استغرقت بضع ساعات من تشغيل الكمبيوتر. النتيجة؟ نموذج تحليل مشاعر فعال جدًا تم تدريبه على مجموعة بيانات ضخمة، وكل ذلك دون تسمية يدوية واحدة!

نصائح من خبرة “أبو عمر”

  • لا تبالغ في تعقيد وظائف الكشف (LFs): ابدأ بالبسيط جدًا. “Keep it simple, ya jama’a”. وظيفة تبحث عن كلمة واحدة أفضل من لا شيء. يمكنك دائمًا إضافة التعقيد لاحقًا.
  • الجودة أهم من الكمية (حتى في LFs): عدد قليل من الوظائف الكاشفة المدروسة جيدًا والتي تغطي جوانب مختلفة من المشكلة (coverage) أفضل من 100 وظيفة متشابهة ومرتبطة ببعضها البعض (correlated).
  • كرّر وحسّن (Iterate): الإشراف الضعيف هو عملية تكرارية. اكتب بعض الوظائف، درّب نموذج التسمية، وحلل أداءه. انظر إلى الحالات التي تفشل فيها وظائفك أو تتعارض، ثم اكتب وظائف جديدة لمعالجة هذه الحالات.
  • استخدم مجموعة بيانات صغيرة للتحقق (Validation Set): حتى لو كانت 100-200 نقطة بيانات فقط، قم بتسميتها يدويًا. هذه المجموعة الصغيرة (التي نسميها gold-standard) لا تقدر بثمن لتقييم مدى جودة نموذج التسمية الخاص بك، وتوجيه عملية تطوير وظائف الكشف.
  • أنت الخبير بمجالك (Domain Expert): أفضل الوظائف الكاشفة تأتي من فهمك العميق للبيانات والمشكلة. المصطلحات الخاصة بمجالك، الاختصارات، الأنماط المتكررة… كل هذه كنوز يمكنك تحويلها إلى وظائف كاشفة فعالة.

الخلاصة: وداعاً لملل التسمية، ومرحباً بالإبداع 💡

الإشراف الضعيف ليس مجرد تقنية، بل هو نقلة نوعية في التفكير. إنه يحول تركيزنا كمطورين وعلماء بيانات من كوننا “عمال تسمية” (labelers) إلى “معلمين” (teachers). بدلاً من إعطاء السمكة للنموذج (البيانات المسماة)، نحن نعلمه كيف يصطاد (عبر الوظائف الكاشفة).

هذا التحول يعني أن وقتنا الثمين يمكن استثماره في الإبداع، وفهم البيانات بشكل أعمق، وبناء حلول برمجية ذكية، بدلاً من إهداره في مهام متكررة ومملة.

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

يلا شدوا الهمة، وخلينا نبني المستقبل ببياناتنا، حتى لو ما كانت كلها مسماة. والله ولي التوفيق. 💪

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

خوارزميات

كنا نرهق قاعدة البيانات بسؤال ‘هل هذا موجود؟’: كيف أنقذنا ‘فلتر بلوم’ من جحيم الاستعلامات غير الضرورية؟

في هذه المقالة، أسرد لكم قصة حقيقية من واقع العمل، كيف أنقذنا نظامنا من ضغط الاستعلامات الهائل باستخدام هيكل بيانات بسيط وعبقري يُدعى "فلتر بلوم"....

21 مايو، 2026 قراءة المزيد
تسويق رقمي

كانت تحويلاتنا ضحية لحاصرات الإعلانات: كيف أنقذتنا واجهة برمجة تطبيقات التحويلات (CAPI) من جحيم التتبع المفقود؟

في هذه المقالة، أشارككم قصة حقيقية من قلب الميدان عن كيفية انهيار تتبع حملاتنا الإعلانية بسبب حاصرات الإعلانات، وكيف كانت واجهة برمجة تطبيقات التحويلات (CAPI)...

21 مايو، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

من الشاشات البيضاء إلى الحوار: فن تصميم حالات الواجهة (Loading, Empty, Error)

في هذا المقال، يأخذكم أبو عمر في رحلة من تجربته كمطور فلسطيني، ليكشف أسرار تصميم حالات الواجهة (التحميل، الفراغ، والخطأ). تعلم كيف تحول الشاشات الصامتة...

21 مايو، 2026 قراءة المزيد
الحوسبة السحابية

كنا ندفع ثمن الخوادم الخاملة: كيف أنقذتنا ‘الحوسبة بلا خوادم’ (Serverless) من جحيم التكاليف المهدرة؟

في هذه المقالة، أشارككم قصة حقيقية من تجربتي كمطور برمجيات عن كيفية انتقالنا من الخوادم التقليدية باهظة الثمن إلى معمارية الحوسبة بلا خوادم (Serverless). سنغوص...

21 مايو، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

كانت طلباتنا تتعثر في أوقات الذروة: كيف أنقذتنا ‘طوابير الرسائل’ (Message Queues) من جحيم الاختناقات؟

أشارككم قصة حقيقية من قلب المعركة البرمجية، كيف كاد تطبيقنا أن ينهار تحت ضغط المستخدمين في يوم إطلاق مهم، وكيف كانت "طوابير الرسائل" (Message Queues)...

21 مايو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

كانت بياناتنا المالية سجينة البنوك: كيف حررتها واجهات ‘الصيرفة المفتوحة’ (Open Banking)؟

من واقع تجربتي كمبرمج، كانت بياناتنا المالية حبيسة جدران البنوك الرقمية. في هذه المقالة، أسرد لكم كيف حولت واجهات برمجة التطبيقات للصيرفة المفتوحة (Open Banking)...

21 مايو، 2026 قراءة المزيد
البودكاست