العودة للدورة|إتقان مقابلات تصميم الأنظمة: بنية قابلة للتوسع من التقدير إلى الإنتاج
معمل

ابنِ محرك بحث وتوصية

40 دقيقة
متقدم
محاولات مجانية غير محدودة

التعليمات

في هذا المختبر، ستبني المكونات الأساسية لنظام بحث وتوصية منتجات من الصفر بلغة TypeScript. هذا هو النظام بالضبط الذي ستصممه في سؤال مقابلة "صمم بحث المنتجات للتجارة الإلكترونية" -- لكن هنا ستُنفّذه فعليًا.

نظرة عامة على البنية

المستندات (كتالوج المنتجات)
المقسّم (تصغير الأحرف، كلمات التوقف، التجذير)
الفهرس المقلوب (مصطلح → قوائم نشر مع TF)
مسجّل BM25 (ترتيب حسب الصلة)
نتائج البحث

سجل تفاعلات المستخدم
┌────────────────────┬────────────────────┐
│ التصفية            │ التصفية المبنية    │
│ التعاونية          │ على المحتوى        │
│ (تشابه الجيب تمام  │ (متجهات الخصائص)  │
│  على تقييمات       │                    │
│  المستخدمين)       │                    │
└────────┬───────────┴─────────┬──────────┘
         │                     │
         ▼                     ▼
     المُوصي الهجين (مزج + بداية باردة)
     التوصيات

دليل خطوة بخطوة

ملف 1: المقسّم (src/search/tokenizer.ts)

ابنِ مقسّم نصوص يُحضّر النص الخام للفهرسة. يجب أن يقوم المقسّم بـ:

  1. تحويل النص إلى أحرف صغيرة
  2. التقسيم على الأحرف غير الأبجدية الرقمية (المسافات، علامات الترقيم)
  3. إزالة كلمات التوقف الإنجليزية (a, an, the, is, are, was, were, in, on, at, to, for, of, and, or, but, not, with, this, that, it, be, have, do, will, can، إلخ)
  4. تطبيق مجذّر بسيط يزيل اللواحق الإنجليزية الشائعة:
    • "ing" -> إزالة (مثلًا "running" -> "runn")
    • "ed" -> إزالة (مثلًا "played" -> "play")
    • "s" في النهاية -> إزالة (مثلًا "shoes" -> "shoe")
    • "ly" -> إزالة (مثلًا "quickly" -> "quick")
    • أزل اللاحقة فقط إذا كان الجذر المتبقي 3 أحرف على الأقل

صدّر دالة tokenize(text: string): string[].

ملف 2: الفهرس المقلوب (src/search/inverted-index.ts)

ابنِ فهرسًا مقلوبًا يربط المصطلحات بقوائم النشر. يجب أن يقوم الفهرس بـ:

  1. قبول المستندات عبر addDocument(docId: string, text: string)
  2. تقسيم النص باستخدام المقسّم الخاص بك
  3. بناء قوائم نشر حيث يحتوي كل إدخال على { docId, termFrequency }
  4. تتبع أطوال المستندات (عدد الرموز لكل مستند) لحساب BM25
  5. تتبع العدد الإجمالي للمستندات ومتوسط طول المستند
  6. توفير getPostings(term: string): PostingEntry[] لاسترجاع قائمة النشر لمصطلح
  7. توفير getDocLength(docId: string): number و getAvgDocLength(): number

ملف 3: مسجّل BM25 (src/search/bm25-scorer.ts)

نفّذ خوارزمية ترتيب BM25. يجب أن يقوم المسجّل بـ:

  1. قبول الفهرس المقلوب كتبعية
  2. استخدام المعاملات القياسية: k1 = 1.2, b = 0.75
  3. تنفيذ score(query: string, docId: string): number لحساب درجة BM25
  4. تنفيذ search(query: string, topK?: number): SearchResult[] لإرجاع أعلى K مستند مرتبة بدرجة BM25
  5. استخدام معادلة BM25 الصحيحة:
    • IDF(t) = log((N - df + 0.5) / (df + 0.5) + 1)
    • مساهمة الدرجة لكل مصطلح = IDF * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * docLen / avgDocLen))

ملف 4: الإكمال التلقائي (src/search/autocomplete.ts)

ابنِ خدمة إكمال تلقائي مبنية على البادئة. يجب أن تقوم الخدمة بـ:

  1. الاحتفاظ بقائمة مصطلحات مع درجات الشعبية
  2. قبول إدخالات جديدة عبر addEntry(term: string, score: number)
  3. تنفيذ suggest(prefix: string, limit?: number): AutocompleteResult[] التي:
    • تجد جميع المصطلحات التي تبدأ بالبادئة (بأحرف صغيرة)
    • ترتب حسب درجة الشعبية تنازليًا
    • تعيد limit نتيجة على الأكثر (افتراضي 10)
  4. دعم تحديث الدرجات عبر updateScore(term: string, delta: number) (مثلًا زيادة 1 عند كل بحث)

ملف 5: التصفية التعاونية (src/recommendation/collaborative-filter.ts)

نفّذ التصفية التعاونية المبنية على المستخدم. يجب أن يقوم المرشّح بـ:

  1. تخزين تقييمات المستخدم-العنصر عبر addRating(userId: string, itemId: string, rating: number)
  2. حساب تشابه الجيب تمام بين مستخدمَين بناءً على العناصر المقيّمة مشتركًا
  3. تنفيذ findSimilarUsers(userId: string, topK?: number): SimilarUser[]
  4. تنفيذ recommend(userId: string, topN?: number): Recommendation[] التي:
    • تجد أعلى K مستخدمين مشابهين
    • تجمع العناصر التي قيّمها هؤلاء المستخدمون بدرجة عالية ولم يقيّمها المستخدم المستهدف
    • تتنبأ بدرجة باستخدام المتوسط المرجح لتقييمات المستخدمين المشابهين
    • تعيد أعلى N توصية مرتبة حسب الدرجة المتوقعة

ملف 6: التصفية بالمحتوى (src/recommendation/content-filter.ts)

نفّذ التصفية المبنية على المحتوى مع متجهات خصائص العناصر. يجب أن يقوم المرشّح بـ:

  1. تسجيل العناصر مع متجهات الخصائص عبر addItem(itemId: string, features: number[])
  2. بناء ملف المستخدم بحساب متوسط متجهات خصائص العناصر التي أعجبته
  3. تنفيذ buildUserProfile(likedItemIds: string[]): number[]
  4. تنفيذ recommend(likedItemIds: string[], topN?: number): Recommendation[] التي:
    • تبني متجه ملف المستخدم
    • تحسب تشابه الجيب تمام بين ملف المستخدم وكل عنصر ليس في likedItemIds
    • تعيد أعلى N عنصر مرتبة حسب التشابه

ملف 7: المُوصي الهجين (src/recommendation/hybrid-recommender.ts)

ابنِ مُوصيًا هجينًا يمزج بين المقاربتين التعاونية والمبنية على المحتوى. يجب أن يقوم المُوصي بـ:

  1. قبول كل من المرشّح التعاوني والمرشّح بالمحتوى كتبعيات
  2. تنفيذ recommend(userId: string, likedItemIds: string[], topN?: number): Recommendation[]
  3. معالجة البداية الباردة: إذا كان المستخدم لديه أقل من عتبة قابلة للتكوين (افتراضي 5) من التقييمات، إعطاء وزن أكبر لنتائج المحتوى (مثلًا 70% محتوى، 30% تعاوني)
  4. للمستخدمين النشطين: إعطاء وزن أكبر لنتائج التعاون (مثلًا 70% تعاوني، 30% محتوى)
  5. إزالة التكرار (نفس العنصر من كلا المصدرين): الاحتفاظ بالدرجة الأعلى
  6. إعادة النتائج النهائية مرتبة حسب الدرجة الممزوجة

ملف 8: نقطة الدخول الرئيسية (src/index.ts)

اربط كل شيء معًا في عرض توضيحي:

  1. إنشاء مستندات منتجات نموذجية (5 على الأقل)
  2. فهرستها باستخدام الفهرس المقلوب
  3. البحث باستخدام مسجّل BM25 وطباعة النتائج
  4. إضافة إدخالات الإكمال التلقائي وعرض الاقتراحات
  5. إعداد تقييمات المستخدمين وعرض توصيات التصفية التعاونية
  6. إعداد خصائص العناصر وعرض توصيات التصفية بالمحتوى
  7. عرض المُوصي الهجين مع مستخدم بداية باردة ومستخدم نشط

تلميحات

  • للمجذّر، فحص بسيط للواحق كافٍ -- لست بحاجة لتنفيذ خوارزمية Porter Stemmer الكاملة
  • لتشابه الجيب تمام، عالج حالة المتجه الصفري (أعد 0 عندما يكون طول أي من المتجهين صفرًا)
  • في التصفية التعاونية، احسب التشابه فقط على العناصر التي قيّمها كلا المستخدمين (العناصر المقيّمة مشتركًا)
  • للمُوصي الهجين، استخدم Map لإزالة التكرار حسب itemId والاحتفاظ بالدرجة الأعلى
  • معادلة IDF في BM25 المستخدمة هنا تتضمن "+1" داخل log لتجنب IDF سالب للمصطلحات التي تظهر في أكثر من نصف المستندات

معايير التقييم

المقسّم يصغّر الأحرف بشكل صحيح ويقسم على الأحرف غير الأبجدية الرقمية ويزيل كلمات التوقف من المجموعة المقدمة ويطبّق المجذّر بإزالة اللواحق (ing, ed, ly, s) فقط عندما يكون الجذر المتبقي 3 أحرف على الأقل10 نقاط
الفهرس المقلوب addDocument يقسّم النص بشكل صحيح ويحسب ترددات المصطلحات لكل مستند ويبني قوائم نشر مع كائنات PostingEntry ويتتبع أطوال المستندات ويحافظ على docCount ومتوسط طول المستند بدقة15 نقاط
مسجّل BM25 ينفّذ المعادلة الصحيحة مع k1=1.2 وb=0.75: IDF = log((N - df + 0.5) / (df + 0.5) + 1)، درجة المصطلح = IDF * (tf * (k1+1)) / (tf + k1 * (1 - b + b * docLen/avgDocLen))؛ دالة search تسجّل جميع المستندات وتصفّي الأصفار وترتب تنازليًا وتعيد أعلى K20 نقاط
الإكمال التلقائي addEntry يخزّن المصطلحات بأحرف صغيرة مع الدرجات، suggest يصفّي بالبادئة بأحرف صغيرة ويرتب حسب الدرجة تنازليًا ويعيد limit نتيجة على الأكثر، وupdateScore يعدّل درجات المصطلحات الموجودة بشكل صحيح10 نقاط
التصفية التعاونية تخزّن التقييمات في خرائط متداخلة وتحسب تشابه الجيب تمام فقط على العناصر المقيّمة مشتركًا (تعالج حالة المتجه الصفري)، findSimilarUsers تصفّي التشابه الإيجابي وتعيد أعلى K، recommend تولّد تنبؤات باستخدام المتوسط المرجح لتقييمات المستخدمين المشابهين وتعيد أعلى N مرتبة15 نقاط
التصفية بالمحتوى تخزّن متجهات خصائص العناصر، buildUserProfile تحسب متوسط متجهات الخصائص للعناصر المُعجب بها (تتخطى العناصر المفقودة)، cosineSimilarity تعالج المتجهات ذات الطول الصفري، recommend تحسب التشابه مع ملف المستخدم لجميع العناصر غير المُعجب بها وتعيد أعلى N مرتبة حسب التشابه10 نقاط
المُوصي الهجين يتحقق من عدد تقييمات المستخدم مقابل coldStartThreshold ويطبّق الأوزان الصحيحة (بارد: 0.3 تعاوني / 0.7 محتوى، نشط: 0.7 تعاوني / 0.3 محتوى) ويضرب الدرجات من كلا المصدرين ويزيل التكرار حسب itemId مع الاحتفاظ بالدرجة الأعلى ويعيد أعلى N مرتبة حسب الدرجة الممزوجة15 نقاط
نقطة الدخول الرئيسية تنشئ 5 مستندات منتجات على الأقل وتفهرسها وتجري بحث BM25 وتطبع النتائج وتعرض اقتراحات الإكمال التلقائي وتُعدّ تقييمات المستخدمين للتصفية التعاونية وتُعدّ خصائص العناصر للتصفية بالمحتوى وتعرض التوصيات الهجينة لمستخدم بداية باردة ومستخدم نشط5 نقاط

قائمة التحقق

0/8

حلك

محاولات مجانية غير محدودة
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.