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

الوحدة 5 — المقاربات الهجينة

كلّ مقاربة رأيناها حتّى الآن لها نقطة قوّة ونقطة ضعف. التعاونيّة تلتقط الأذواق الخفيّة لكنّها تعجز عن العناصر الجديدة، والمحتوى يعمل من اليوم الأوّل لكنّه يحبس المستخدم في فقاعة. المقاربات الهجينة ليست خيارًا فاخرًا، بل هي معيار الصناعة: كلّ نظام إنتاج رأيناه في Netflix وSpotify وYouTube هجين بشكل من الأشكال.

سبعة أنماط، ثلاثة عمليّة

صاغ Robin Burns في عام 2002 سبعة أنماط للتهجين. من الناحية العمليّة نستعمل ثلاثة أساسًا: الوزن، والتبديل، والإثراء. سنأخذ كلًّا منها بمثال ملموس.

النمط الأوّل: الوزن

نُشغّل نموذجَين مستقلَّين، ونأخذ متوسّطًا موزونًا لدرجاتهما:

score(u,i)=αscf(u,i)+(1α)scontenu(u,i)\text{score}(u,i) = \alpha \cdot s_{\text{cf}}(u,i) + (1-\alpha) \cdot s_{\text{contenu}}(u,i)

α\alpha بين 0 و1، يُضبَط على مجموعة تحقّق. المطلوب أن تكون درجات النموذجَين على مقياس واحد (تعيير Min-Max أو Z-score قبل الجمع).

import numpy as np

def scores_hybrides_ponderes(scores_cf, scores_contenu, alpha=0.6):
# تعيير كلّ نموذج على المقياس نفسه [0, 1]
def normaliser(s):
s = np.asarray(s, dtype=float)
mn, mx = s.min(), s.max()
return (s - mn) / (mx - mn + 1e-9)

return alpha * normaliser(scores_cf) + (1 - alpha) * normaliser(scores_contenu)

المزيّة: بسيط، شفّاف، يمكن ضبط α\alpha لكلّ فئة مستخدم. العيب: لا يستفيد من التكامل بين النموذجَين على مستوى القرار الفرديّ.

قاعدة تجريبيّة عمليّة: α\alpha عادةً بين 0.6 و0.8 (وزن أعلى للتصفية التعاونيّة) حين يكون المستخدم قد راكم تفاعلات كافية، وأدنى بكثير للمستخدمين الجُدد.

النمط الثاني: التبديل

نستعمل نموذجًا واحدًا في كلّ حالة، لكن نُبدّل بينهما بحسب السياق:

  • مستخدم جديد (أقلّ من 5 تفاعلات) → محتوى فقط، لعدم وجود إشارة تعاونيّة.
  • عنصر جديد (أقلّ من 20 تقييمًا) → محتوى فقط، لأنّ العوامل الكامنة للعنصر غير موثوقة.
  • الحالة الاعتياديّة → تصفية تعاونيّة، لأنّ إشارتها أقوى.
def hybride_par_commutation(user, item, historique_utilisateur, nb_tests_item):
if len(historique_utilisateur) < 5:
return score_contenu(user, item) # démarrage à froid utilisateur
if nb_tests_item < 20:
return score_contenu(user, item) # démarrage à froid item
return score_collaboratif(user, item)

المزيّة: كلّ مسار يخدم حالته بأفضل شكل. العيب: عتبات صلبة تُنتج قفزات في السلوك حول العتبة (متعلّم بأربع تفاعلات يحصل على توصيات مختلفة تمامًا عن متعلّم بست تفاعلات).

يمكن تنعيم القفزات بالنمط التالي.

النمط الثالث: إثراء العوامل بالمحتوى

نبقى في إطار تفكيك المصفوفة، لكنّنا نُثري الحساب بالمحتوى. الفكرة اقترحها Koren في عام 2008 باسم SVD++: بدل تعلّم عامل عنصر qiq_i من الصفر، نبدأه من تضمين وصف العنصر ثمّ نضبطه بالتدرّج.

qi=fθ(descriptioni)+Δqiq_i = f_\theta(\text{description}_i) + \Delta q_i

fθf_\theta شبكة صغيرة تُحوّل التضمين إلى فضاء العوامل (مثلًا 384 بُعدًا → 50 بُعدًا)، وΔqi\Delta q_i تعديل يتعلّمه النموذج من التقييمات.

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

في الوحدة السادسة سنبني نموذج «البُرجَين» الذي يُعمّم هذه الفكرة إلى شبكة كاملة.

دراسة حالة: Netflix

جائزة Netflix (2006-2009) بيّنت أن أفضل حلّ فرديّ فقد بفارق كبير أمام مزيج من أكثر من مئة نموذج مختلف. الفائز BellKor's Pragmatic Chaos جمع بين طرق قائمة على الجوار، وتفكيك المصفوفة، وآلات بولتزمان المقيّدة، وتنظيمات مختلفة. الدرس: التنوّع بين النماذج أهمّ من دقّة نموذج واحد، لأنّ الأخطاء إذا كانت مستقلّة تُلغى في المتوسّط.

في الإنتاج، لا يشغّل Netflix مئة نموذج للسرعة، لكنّ الاختيار النهائيّ لكلّ صفحة (Row) هجين: بعض الصفوف قائمة على الشعبيّة، وبعضها على تفكيك المصفوفة، وبعضها على شبكة عصبيّة، وبعضها على محتوى (رواية، دراما...). ما يراه المستخدم مزيج مدبَّر.

التغلّب على فقاعة الترشيح

المقاربة الهجينة تُتيح كسر الفقاعة بشكل طبيعيّ. مثلًا: 70% من التوصيات من التصفية التعاونيّة، 20% من المحتوى (لتغطية العناصر الجديدة)، 10% من الشعبيّة الخالصة (لتوسيع الأفق). هذا التنويع يُحسّن مقاييس التغطية وقد يُحسّن حتّى مقياس الاستدعاء الرئيسيّ، لأنّ المستخدم يكتشف أشياء تفوق حدس نموذج التصفية.

اختيار وزن الجمع بذكاء

α\alpha ثابت مفرط في البساطة. الشكل الأكثر تطوّرًا يجعل الوزن تكيّفيًّا: كلّ مستخدم له وزن خاصّ به بحسب موثوقيّة كلّ إشارة.

def alpha_adaptatif(nb_interactions_utilisateur, nb_ratings_moyen_items):
# التعاون يزن أكثر كلّما نضج المستخدم
a_user = min(1.0, nb_interactions_utilisateur / 30.0)
# التعاون يزن أكثر كلّما نضج العنصر
a_item = min(1.0, nb_ratings_moyen_items / 50.0)
# الوزن النهائيّ متوسّط قيمة عناصر الثقة
return 0.5 * a_user + 0.5 * a_item

α\alpha يقترب من 1 كلّما نضج الطرفان، ومن 0 حين يكونان جديدَين. هذا الشكل من الحكم الآليّ يُعمّم النمط التبديليّ إلى منحنى ناعم.

الترتيب العمليّ للبناء

ابنِ نموذج محتوى أوّلًا: يبدأ العمل من اليوم الأوّل. أضف تفكيك مصفوفة حين تتراكم بضع مئات آلاف التقييمات. اجمع بينهما بوزن ثابت أوّلًا، ثمّ بوزن تكيّفيّ حين تحتاج إلى قفزة في الأداء.

الخلاصة

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

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