Logo
تعلم الآلة (2026-2027) - التوصيات المعتمدة على المحتوى

في نافذة الطباعة اختر «حفظ كملف PDF» كوجهة.

تعلم الآلة، الأسبوع 9

التوصيات المعتمدة على المحتوى

صف كل فيلم بكلماته، وقس مدى التشابه بين فيلمين بتشابه جيب التمام، وأوص بالأفلام الأقرب.

الأهداف

  • شرح كيف يختار نظام التوصية المعتمد على المحتوى (content-based) الأفلام: المحتوى المشابه يوصى به أولا
  • تحويل النص إلى متجهات أعداد (count vectors) باستخدام CountVectorizer، وبيان وظيفة stop_words وmin_df
  • حساب تشابه جيب التمام (cosine similarity) يدويا: الضرب النقطي (dot product)، والطولان، والقسمة
  • بناء مصفوفة التشابه (similarity matrix) باستخدام cosine_similarity وقراءة صف واحد منها
  • تتبع get_recommendations سطرا بسطر وشرح مواضع خطئها
  • إعداد عرض مشروع فريقك لمناقشة هذا الأسبوع

الأسبوع 9 من الخطة

موقع الدرس من المقرر

  • الدفتر (notebook): Movie Recommendations، قاعدة بيانات من 4,803 أفلام بأنواعها وكلماتها المفتاحية وطاقم تمثيلها ومخرجيها
  • سيناريو من الواقع: توصيات الأفلام، نموذج يأخذ عنوان فيلم ويعيد أفلاما مشابهة
  • مرحلة المشروع: عروض فرق المشاريع ومناقشاتها (Project Teams Presentations and Discussions)

خطة الساعتين

الجزءما نفعلهالزمن
1الفكرة، ومثال محلول يدويا35 دقيقة
2الدفتر: المتجهات ومصفوفة التشابه25 دقيقة
3get_recommendations ومواضع خطئها20 دقيقة
4عروض المشاريع والمناقشة10 دقائق
5تمارين مع الإجابات، ثم الخلاصة30 دقيقة

الجزء 1

الفكرة

محتوى متشابه، ذوق متشابه

ما نظام التوصية المعتمد على المحتوى؟

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

الوصفة في أربع خطوات

  1. الوصف: صف كل فيلم بنص واحد يضم عنوانه، وأنواعه، وكلماته المفتاحية، وطاقم تمثيله، ومخرجه
  2. التحويل إلى متجهات: عد كم مرة تظهر كل كلمة من المفردات (vocabulary) في ذلك النص
  3. المقارنة: احسب تشابه جيب التمام لكل زوج من الأفلام
  4. التوصية: لفيلم أعجب المشاهد، أعد الأفلام صاحبة أعلى تشابه

من النص إلى الأعداد: CountVectorizer

python
texts = ['Action Adventure Fantasy Science Fiction',
         'Adventure Fantasy Action']
cv = CountVectorizer(stop_words='english')
m = cv.fit_transform(texts)
print(cv.get_feature_names_out())
print(m.toarray())
text
['action' 'adventure' 'fantasy' 'fiction' 'science']
[[1 1 1 1 1]
 [1 1 1 0 0]]
المخرجات
  • تبني fit المفردات: كل كلمة مختلفة، بحروف صغيرة، ومرتبة
  • تعطي transform كل نص صفا من الأعداد، بعمود لكل كلمة
  • يحذف stop_words='english' كلمات التوقف (stop words)، أي الكلمات الشائعة جدا مثل the وof
  • يضيع ترتيب الكلمات: لا يبقى إلا الأعداد

تشابه جيب التمام

cos(A, B) = A · B‖A‖   ‖B‖
A · B = a1 b1 + a2 b2 + ... + an bn ‖A‖ = √(a12 + a22 + ... + an2)
  • A وB متجها الأعداد لفيلمين، وn عدد كلمات المفردات
  • a_i وb_i عدد مرات ظهور الكلمة i في كل فيلم
  • A · B هو الضرب النقطي، و‖A‖ هو طول A

قراءة قيمة جيب التمام

  • 1: يشير المتجهان إلى الاتجاه نفسه، أي المزيج نفسه من الكلمات
  • 0: لا يشترك الفيلمان في أي كلمة إطلاقا
  • الأعداد لا تكون سالبة أبدا، لذا تقع قيمة جيب التمام عندنا دائما بين 0 و1
  • الاتجاه وحده هو المهم: مضاعفة كل أعداد فيلم لا تغير قيمة جيب التمام

يدويا

مثال محلول: خمسة أفلام

أول خمسة صفوف من movies.csv، باستخدام العمود genres وحده. أعجب Avatar أحد المشاهدين: أي فيلم نوصي به؟

الفيلمgenres
AvatarAction Adventure Fantasy Science Fiction
Pirates of the Caribbean: At World's EndAdventure Fantasy Action
SpectreAction Adventure Crime
The Dark Knight RisesAction Crime Drama Thriller
John CarterAction Adventure Science Fiction

الخطوة 1: المفردات

text
['action' 'adventure' 'crime' 'drama' 'fantasy' 'fiction' 'science' 'thriller']
cv.get_feature_names_out()

الأعمدة بترتيب المفردات

الخطوة 1: متجهات الأعداد

action, adventure, crime, drama, fantasy, fiction, science, thriller

الفيلممتجه الأعدادالكلمات
Avatar[1 1 0 0 1 1 1 0]5
Pirates of the Caribbean[1 1 0 0 1 0 0 0]3
Spectre[1 1 1 0 0 0 0 0]3
The Dark Knight Rises[1 0 1 1 0 0 0 1]4
John Carter[1 1 0 0 0 1 1 0]4

الخطوة 2: الأطوال

الفيلممجموع المربعاتالطول ‖v‖
Avatar5√5 = 2.2361
Pirates of the Caribbean3√3 = 1.7321
Spectre3√3 = 1.7321
The Dark Knight Rises4√4 = 2.0000
John Carter4√4 = 2.0000

الخطوة 3: الضرب النقطي مع Avatar

الفيلمالكلمات المشتركةA · B
Pirates of the Caribbeanaction, adventure, fantasy3
Spectreaction, adventure2
The Dark Knight Risesaction1
John Carteraction, adventure, fiction, science4

A = Avatar، وB = Pirates of the Caribbean

الخطوة 4: قيمة واحدة لجيب التمام

cos(A, B) = 3√5 × √3 = 3√15 = 33.8730 = 0.7746

A = Avatar في كل الصفوف

الخطوة 4: الأفلام الثلاثة الأخرى

الفيلم Bالحسابcos(A, B)
Spectre2 / (2.2361 × 1.7321) = 2 / 3.87300.5164
The Dark Knight Rises1 / (2.2361 × 2) = 1 / 4.47210.2236
John Carter4 / (2.2361 × 2) = 4 / 4.47210.8944

الخطوة 5: الترتيب والتوصية

الترتيبالفيلمcos(A, B)
1John Carter0.8944
2Pirates of the Caribbean0.7746
3Spectre0.5164
4The Dark Knight Rises0.2236

التحقق باستخدام scikit-learn

python
from sklearn.metrics.pairwise import cosine_similarity

cv = CountVectorizer(stop_words='english')
m = cv.fit_transform(df['genres'].head(5))
sim = cosine_similarity(m)
sim[0]
text
array([1.        , 0.77459667, 0.51639778,
       0.2236068 , 0.89442719])
الصف 0 = Avatar، وهو نتائجنا اليدوية
خريطة حرارية (heatmap) لمصفوفة تشابه جيب التمام 5 في 5 لمتجهات الأنواع الخمسة: 1 على القطر، و0.8944 بين Avatar وJohn Carter، و0.2236 بين Avatar وThe Dark Knight Rises

جربها: جيب التمام خطوة بخطوة

الجزء 2

الدفتر على 4,803 أفلام

المتجهات ومصفوفة التشابه

افتح الدفتر في Colab

text
https://colab.research.google.com/github/
jeffprosise/Machine-Learning/blob/master/
Movie%20Recommendations.ipynb
اجمع الأسطر الثلاثة في عنوان واحد، أو اضغط رابط Colab في صفحة الدرس.

تحميل البيانات

python
import pandas as pd

url = ('https://raw.githubusercontent.com/'
       'jeffprosise/Machine-Learning/'
       'master/Data/movies.csv')
df = pd.read_csv(url)
df.shape
  • (4803, 24): 4,803 أفلام، و24 عمودا
  • من بينها: title وgenres وkeywords وcast وdirector
  • وأيضا الميزانية والإيرادات ومدة العرض والأصوات: لا يستخدمها هذا النموذج
  • حجم الملف نحو 23 MB، لذا تستغرق الخلية بضع ثوان

احتفظ بخمسة أعمدة، واملأ الفجوات

python
df = df[['title', 'genres', 'keywords', 'cast', 'director']]
df = df.fillna('')  # Fill missing values with empty strings

نص واحد لكل فيلم: العمود features

python
df['features'] = (df['title'] + ' ' + df['genres'] + ' ' +
                  df['keywords'] + ' ' + df['cast'] + ' ' +
                  df['director'])
  • تلصق الأعمدة الخمسة في سلسلة نصية واحدة، بينها مسافات
  • تصبح الأسماء كلمات عادية: الاسم الأول للمخرج واسم عائلته كلمتان
  • مثال: يعطي العنوان The Dark Knight Rises الكلمات dark وknight وrises (وthe من كلمات التوقف)

تحويل الأفلام الـ4,803 كلها إلى متجهات

python
vectorizer = CountVectorizer(stop_words='english', min_df=20)
word_matrix = vectorizer.fit_transform(df['features'])
word_matrix.shape

عمود features نفسه، مع stop_words='english'

كيف يشكل min_df المفردات

min_dfالكلمات المحتفظ بها
117,286
53,852
20 (الدفتر)918
50271

مصفوفة التشابه

python
from sklearn.metrics.pairwise import cosine_similarity

sim = cosine_similarity(word_matrix)
sim.shape
  • (4803, 4803): sim[i, j] هو قيمة جيب التمام بين الفيلمين i وj
  • متماثلة (symmetric): sim[i, j] يساوي sim[j, i]
  • القطر يساوي 1.0 في 4,794 فيلما، أما الأفلام الـ9 الأخرى فلم تبق فيها أي كلمة، لذا كل قيم صفها 0

متجهات حقيقية من word_matrix

مثال محلول: Skyfall وSpectre

كل الأعداد تساوي 1 في المتجهين

الكلمات منSkyfallSpectreالمشتركة
الأنواع332: action, adventure
الكلمات المفتاحية563: spy, secret, agent
أسماء طاقم التمثيل والإخراج766
المجموع151511

A = Skyfall، وB = Spectre

Skyfall وSpectre: قيمة جيب التمام

cos(A, B) = 11√15 × √15 = 1115 = 0.7333

الجزء 3

توليد التوصيات

get_recommendations سطرا بسطر

العثور على صف الفيلم

python
def get_recommendations(title, df, sim, count=10):
    # Get the row index of the specified title in the DataFrame
    index = df.index[df['title'].str.lower() == title.lower()]

    # Return an empty list if there is no entry for the specified title
    if (len(index) == 0):
        return []

    # Get the corresponding row in the similarity matrix
    similarities = list(enumerate(sim[index[0]]))
  • مطابقة العنوان لا تفرق بين الحروف الكبيرة والصغيرة: 'skyfall' تعمل أيضا
  • العنوان غير المعروف يعيد [] بدلا من خطأ
  • تقرن enumerate كل قيمة (score) برقم فيلمها، وفي Skyfall: (0, 0.1732), (1, 0.1333), (2, 0.7333), ...

الترتيب، ثم التخطي، ثم إعادة العناوين

python
    recommendations = sorted(similarities, key=lambda x: x[1], reverse=True)
    top_recs = recommendations[1:count + 1]
    titles = []
    for i in range(len(top_recs)):
        title = df.iloc[top_recs[i][0]]['title']
        titles.append(title)
    return titles

get_recommendations('Skyfall', df, sim)

Skyfall: التوصيات العشر

أعمدة أفقية لأعلى عشر قيم لتشابه جيب التمام مع Skyfall: Spectre 0.7333، وQuantum of Solace 0.5729، وJohnny English Reborn 0.4140، نزولا إلى Sanctum وBlackthorn عند 0.3651

A = Mulan (10 كلمات)، وB = Shrek (15 كلمة)

لماذا يحصل Mulan على Shrek؟

cos(A, B) = 3 + 2√10 × √15 = 512.2474 = 0.4082

استكشف: أي فيلم، وأي توصية

مواضع الخطأ

  • المتجهات الفارغة: تفقد 9 أفلام كل كلماتها بعد min_df=20، لذا كل قيمة في صفها 0
  • العناوين المكررة: فيلمان اسمهما Batman، والدالة تستخدم دائما الأول
  • التعادل مع الفيلم نفسه: في 14 صفا لا يكون الفيلم هو العنصر 0، لذا قد يتخطى [1:] الفيلم الخطأ
  • المحتوى وحده: لا يرى النموذج التقييمات أبدا، لذا لا يستطيع التمييز بين فيلم جيد وفيلم سيئ

أحد المتجهات الفارغة الـ9

مثال محلول: Sharkskin

text
["Pirates of the Caribbean: At World's End", 'Spectre', 'The Dark Knight Rises']
المخرجات

الجزء 4

عروض فرق المشاريع ومناقشاتها

مرحلة المشروع هذا الأسبوع

مشروع فريقك

عرض فريقك

  1. الفكرة، أو الورقة البحثية، وسبب أهميتها
  2. البيانات: المصدر، والاستكشاف، والتنظيف
  3. الخصائص (features) والمتغير الهدف (target variable) التي اخترتها
  4. النموذج الذي نفذته وطريقة تقييمك له
  5. ما ستحسنه بعد ذلك

قبل التمارين

الأخطاء الشائعة

  • قراءة Data/movies.csv في Colab، حيث لا يوجد المجلد
  • نسيان fillna('')، فيعطل النص المفقود CountVectorizer
  • إعادة العنصر 0: الفيلم المفضل يوصي بنفسه
  • جمع الكلمات المشتركة ونسيان القسمة على الطولين
  • الثقة بقائمة دون قيمها (المتجهات الفارغة، والتعادلات، والعناوين المكررة)
  • توقع أن تحسب كلمة نادرة من العنوان بعد أن حذفها min_df

الجزء 5

التمارين: دورك

نحو 30 دقيقة، والإجابات تلي كل مهمة

نحو 10 دقائق

التمرين 1: فيلم سادس

  • الصف 11 من الملف، Quantum of Solace، أنواعه Adventure Action Thriller Crime
  • اكتب متجه أعداده على الكلمات الـ8 نفسها، واحسب طوله
  • احسب قيمة جيب التمام بينه وبين كل من الأفلام الخمسة في المثال المحلول
  • أي فيلمين توصي بهما لمشاهد أعجبه؟

الإجابات

التمرين 1: الإجابة

  • A = Quantum of Solace = [1 1 1 0 0 0 0 1]، و‖A‖ = √4 = 2
الفيلم BA · Bcos(A, B)
Spectre33 / (2 × 1.7321) = 0.8660
The Dark Knight Rises33 / (2 × 2) = 0.7500
Pirates of the Caribbean22 / (2 × 1.7321) = 0.5774
John Carter22 / (2 × 2) = 0.5000
Avatar22 / (2 × 2.2361) = 0.4472

نحو 5 دقائق

التمرين 2: الأعداد والطول

  • ثلاثة نصوص قصيرة: X = space war space alien، وY = space alien robot، وZ هو X مكتوبا مرتين
  • استخدم المفردات alien, robot, space, war واكتب X وY وZ متجهات أعداد
  • احسب cos(X, Y) وcos(Z, Y) وcos(X, Z)
  • ماذا يفعل تكرار النص بقيمة جيب التمام الخاصة به؟

الإجابات

التمرين 2: الإجابة

  • X = [1, 0, 2, 1]، وY = [1, 1, 1, 0]، وZ = [2, 0, 4, 2]
cos(X, Y) = 3√6 × √3 = 34.2426 = 0.7071
cos(Z, Y) = 6√24 × √3 = 68.4853 = 0.7071

نحو 10 دقائق

التمرين 3: القيم في Colab

  1. شغل الدفتر حتى sim = cosine_similarity(word_matrix)
  2. انسخ get_recommendations واجعلها تعيد أزواجا (title, score)، مع تقريب القيمة إلى 4 منازل عشرية
  3. اطبع أعلى 5 نتائج للعنوان 'The Dark Knight Rises'
  4. تحقق من القيمة الأولى يدويا من word_matrix: الضرب النقطي ومجموعا المربعات

الإجابات

التمرين 3: الإجابة

الترتيبالفيلمالقيمة
1The Dark Knight0.7924
2Batman Begins0.7348
3Harsh Times0.4667
4The Killer Inside Me0.4648
5Amidst the Devil's Wings0.4619
cos(A, B) = 19√25 × √23 = 195 × 4.7958 = 0.7924

نحو 5 دقائق

التمرين 4: غير min_df

  • الشكل (4803, 3852): تبقى كلمات أكثر بكثير
  • يبقى Spectre أولا، لكن قيمته تنخفض من 0.7333 إلى 0.5500: في كل متجه الآن 20 كلمة، والمشتركة ما زالت 11
  • من الوافدين الجدد: Casino Royale (0.3500) وGoldfinger (0.2635)
cos(A, B) = 11√20 × √20 = 1120 = 0.55

الخلاصة

  1. يقترح نظام التوصية المعتمد على المحتوى العناصر التي يكون محتواها الأقرب إلى عنصر أعجبك
  2. يحول CountVectorizer النص إلى متجهات أعداد، ويحدد stop_words وmin_df الكلمات التي تحسب
  3. تشابه جيب التمام هو الضرب النقطي مقسوما على الطولين: بين 0 و1 للأعداد
  4. تعطي cosine_similarity المصفوفة كاملة، وصف مرتب واحد منها هو قائمة توصيات
  5. انظر دائما إلى القيم: فالمتجهات الفارغة والتعادلات والعناوين المكررة تعطي قوائم مضللة

افتح هذا الدرس

Mahmoud Abasالتوصيات المعتمدة على المحتوى