Logo
تعلم الآلة (2026-2027) - تحليل المشاعر بالتصنيف الثنائي

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

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

تحليل المشاعر بالتصنيف الثنائي

حول المراجعة إلى أعداد كلمات، ثم إلى درجة بين 0 و1 بالانحدار اللوجستي.

الأهداف

  • شرح تحليل المشاعر (sentiment analysis) على أنه تصنيف ثنائي (binary classification): الدرجة (score) هي احتمال الصنف الإيجابي (positive class)
  • وصف ما يفعله CountVectorizer: الأحرف الصغيرة (lower case)، والرموز (tokens)، وكلمات التوقف (stop words)، والكلمات المفردة (unigrams) والأزواج (bigrams)، والمفردات (vocabulary)
  • حساب درجة مراجعة يدويا من الحد الثابت (bias) والأوزان (weights) والدالة السينية (sigmoid)
  • تدريب نموذج الدفتر (notebook) وتقييمه: مصفوفة الالتباس (confusion matrix)، والدقة (accuracy)، والضبط (precision)، والاستدعاء (recall)، وROC AUC
  • حساب درجات مراجعات جديدة باستخدام predict_proba، وشرح مواضع خطأ حقيبة الكلمات (bag of words)

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

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

  • الدفتر: Sentiment Analysis، انحدار لوجستي (logistic regression) على 50,000 مراجعة أفلام تسمية كل منها 0 أو 1
  • سيناريو من الواقع: أعط النص درجة من 0 إلى 1، من السلبية إلى الإيجابية
  • مرحلة المشروع (project milestone) هذا الأسبوع: عروض فرق المشاريع ومناقشاتها (Project Teams Presentations and Discussions)

السيناريو: حساب درجة مراجعة مطعم

المراجعةما تتوقعه الخطة
Best meal I've ever had and awesome service, too!0.9 أو أكثر
Long lines and poor customer serviceأقرب إلى 0

خطة الساعتين

الجزءما نفعلهالزمن
1 و2المشاعر في صورة احتمال؛ من النص إلى الأعداد باستخدام CountVectorizer40 دقيقة
3حساب درجة مراجعة يدويا20 دقيقة
4الدفتر في Colab: التدريب، والتقييم، وحساب الدرجات20 دقيقة
5حدود النموذج، ومشروعك10 دقائق
6تمارين مع الإجابات30 دقيقة

الجزء 1

المشاعر في صورة احتمال

التصنيف الثنائي على النص

ما تحليل المشاعر؟

تحليل المشاعر
إعطاء النص درجة من 0 إلى 1، حيث 0 مشاعر سلبية و1 مشاعر إيجابية.
المصطلحفي بيانات هذا الأسبوع
العينةمراجعة واحدة، أي سلسلة نصية
التسمية (label) y0 سلبية، 1 إيجابية
الخصائص (features) xأعداد الكلمات في المراجعة
الدرجة pاحتمال أن تكون التسمية 1

خط المعالجة

مخطط تدفق: المراجعة ثم التحويل إلى متجه ثم (الأعداد) حساب z ثم الضغط ثم القرار.

المراجعة

سلسلة نصية

التحويل إلى متجه

CountVectorizer

الأعداد

حساب z

b + Σ w·x

الضغط

p = σ(z)

القرار

p ≥ 0.5: إيجابية

الجزء 2

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

CountVectorizer وحقيبة الكلمات

حقيبة الكلمات

حقيبة الكلمات
احتفظ بقائمة من الكلمات المعروفة، هي المفردات، وعبر عن كل نص بعدد مرات ظهور كل كلمة من القائمة فيه.
  • لا يستطيع النموذج أن يعمل على النص: فهو يحتاج إلى أعداد
  • صف لكل نص، وعمود لكل مدخل في المفردات، والخلايا أعداد
  • يهمل ترتيب الكلمات: ولهذا تسمى حقيبة

CountVectorizer في الدفتر

python
vectorizer = CountVectorizer(
    ngram_range=(1, 2),
    stop_words='english',
    min_df=20)
x = vectorizer.fit_transform(
    df['Text'])
y = df['Sentiment']
من sklearn.feature_extraction.text
  1. الأحرف الصغيرة: تصبح pOOr هي poor
  2. الرموز: سلاسل طولها 2 أو أكثر من الحروف أو الأرقام أو _
  3. حذف كلمات التوقف: 318 كلمة مثل the وand، وحتى not
  4. إضافة الأزواج: أزواج الكلمات المتجاورة مثل customer service
  5. الإبقاء على المفردات: المدخلات الموجودة في 20 مراجعة على الأقل (min_df=20)
  6. عد كل مدخل: صف واحد لكل مراجعة

من الدفتر

مثال محلول: ما يبقيه المحول

python
text = vectorizer.transform(['The long l3ines   and; pOOr customer# service really turned me off...123.'])
text = vectorizer.inverse_transform(text)
print(text)

الخطوة 1: الأحرف الصغيرة والرموز

text
the, long, l3ines, and, poor, customer, service,
really, turned, me, off, 123

الخطوة 2: حذف كلمات التوقف

text
long, l3ines, poor, customer, service, really, turned, 123

الخطوة 3: إضافة الأزواج

text
long l3ines, l3ines poor, poor customer, customer service,
service really, really turned, turned 123

الخطوة 4: الإبقاء على المفردات

text
[array(['customer', 'long', 'poor', 'really', 'service', 'turned'],
      dtype='<U25')]

مثال محلول: ثلاث مراجعات في صورة مصفوفة أعداد

الكلمات المفردة وحدها. توقع الأعمدة، وخلية المراجعة 2 تحت awesome: فالمحول يعد

python
vec = CountVectorizer(stop_words='english')
x = vec.fit_transform(['Long lines and poor customer service',
    "Best meal I've ever had and awesome service, too!",
    'Awesome meal, awesome service'])
text
   awesome  best  customer  lines  long  meal  poor  service  ve
0        0     0         1      1     1     0     1        1   0
1        1     1         0      0     0     1     0        1   1
2        2     0         0      0     0     1     0        1   0

الجزء 3

حساب درجة مراجعة يدويا

الانحدار اللوجستي من الأسبوع 4، على أعداد الكلمات

معادلة الأسبوع 4

z = b + w1 x1 + w2 x2 + ... + wn xn
p = σ(z) = 11 + e-z
الرمز الرياضيالمعنى
bالحد الثابت، model.intercept_: هنا -0.0488
w_iوزن مدخل المفردات i، من model.coef_
x_iعدد مرات ظهور المدخل i: 0 في الغالب
σ وeالدالة السينية؛ وe = 2.71828، وσ(0) = 0.5

أي الكلمات تدفع بقوة أكبر؟

مخطط أعمدة لأدنى 12 وزنا، وفي مقدمتها disappointment وwaste وworst، ولأعلى 12 وزنا، وفي مقدمتها funniest و10 10 وexcellent
  • الوزن الأكبر من 0 يدفع نحو الإيجابية، والأصغر من 0 نحو السلبية
  • أدنى الأوزان: disappointment -2.1646، وwaste -2.1606، وworst -2.1519
  • أعلى الأوزان: funniest 1.6471، و10 10 1.4037، وexcellent 1.3094
  • لا كلمة معروفة إطلاقا: p = σ(-0.0488) = 0.4878

يدويا، الخطوة 1

مثال محلول: Long lines and poor customer service

ما الخصائص التي يراها النموذج؟

الخاصيةxww·x
customer1-0.1980-0.1980
lines1-0.1184-0.1184
long1-0.0284-0.0284
poor1-1.4874-1.4874
service1-0.4832-0.4832

الخطوة 2: حساب z

b = -0.0488، والأوزان مقربة إلى 4 منازل عشرية

Σ w x = -0.1980 - 0.1184 - 0.0284 - 1.4874 - 0.4832
Σ w x = -2.3154, z = -0.0488 + (-2.3154) = -2.3642

الخطوة 3: الدالة السينية والقرار

e2.3642 = 10.6355
p = 11 + 10.6355 = 0.0859

يدويا، الخطوة 1

مثال محلول: Best meal I've ever had

Best meal I've ever had and awesome service, too!

الخاصيةxww·x
awesome10.73100.7310
best10.70900.7090
meal10.00620.0062
service1-0.4832-0.4832
ve1-0.0820-0.0820

الخطوة 2: قيمتا z وp

تقول الخطة 0.9 أو أكثر

z = -0.0488 + 0.7310 + 0.7090 + 0.0062 - 0.4832 - 0.0820 = 0.8322
p = 11 + e-0.8322 = 11 + 0.4351 = 0.6968

لماذا ليست 0.9؟

إيجابية، لكن predict_proba تعطي 0.69682

  • تعلم النموذج من مراجعات الأفلام: وفيها service كلمة سلبية (-0.4832)
  • ووزن staff أيضا -0.4587، بينما لا يتجاوز وزن rude القيمة -0.0364
  • في النص القصير خصائص قليلة، لذا يبقى Σ w·x صغيرا وتبقى p قرب المنتصف
  • يعتمد الرقم على بيانات التدريب؛ ولو دربنا النموذج بالشيفرة نفسها على مراجعات مطاعم لتعلم أوزان المطاعم

جربها: مقياس المشاعر

الجزء 4

الدفتر في Colab

التدريب، والتقييم، وحساب الدرجات

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

text
https://colab.research.google.com/github/
jeffprosise/Machine-Learning/blob/master/
Sentiment%20Analysis.ipynb
اجمع الأسطر الثلاثة في عنوان واحد، أو اضغط "افتح Sentiment Analysis في Colab" في صفحة الدرس.
في الدفترغيره إلى
read_csv('Data/reviews.csv', ...)اقرأ الملف من المستودع (الشريحة التالية)
plot_confusion_matrix(...)ConfusionMatrixDisplay.from_estimator(...)
pickle.dump(..., open('Data/sentiment.pkl', 'wb'))احفظه في 'sentiment.pkl'

تحميل البيانات، وحذف التكرارات

python
url = ("https://raw.githubusercontent.com/"
       "jeffprosise/Machine-Learning/master/Data/reviews.csv")
df = pd.read_csv(url, encoding="ISO-8859-1")
df.groupby('Sentiment').describe()
df = df.drop_duplicates()

التحويل إلى متجهات والتقسيم

python
x = vectorizer.fit_transform(df['Text'])
y = df['Sentiment']

x_train, x_test, y_train, y_test = train_test_split(
    x, y, test_size=0.5, random_state=0)
  • x.shape هو (49581, 33752): 17,528 كلمة مفردة و16,224 زوجا
  • لا يختلف عن 0 إلا 0.30% من الخلايا البالغة 1.67 مليار: مصفوفة متفرقة (sparse matrix)
  • تقسيم 50/50: 24,790 مراجعة للتدريب، و24,791 للاختبار

تدريب النموذج

python
from sklearn.linear_model import LogisticRegression

model = LogisticRegression(max_iter=1000, random_state=0)
model.fit(x_train, y_train)
  • تتعلم fit 33,752 وزنا، وزنا لكل مدخل في المفردات، إضافة إلى الحد الثابت b
  • تعطي max_iter=1000 خوارزمية الحل (solver) مجالا لتتقارب رغم هذا العدد الكبير من الخصائص؛ واحتاج تشغيلنا إلى 78 تكرارا
  • لا جديد: LogisticRegression نفسه الذي استخدمناه في الأسبوع 4

مصفوفة الالتباس

على مراجعات الاختبار الـ24,791

مصفوفة الالتباس لنموذج المشاعر: 10792 و1577 في صف Negative، و1456 و10966 في صف Positive
python
ConfusionMatrixDisplay.from_estimator(
    model, x_test, y_test,
    display_labels=['Negative', 'Positive'],
    cmap='Blues',
    xticks_rotation='vertical')

مثال محلول: تقييم النموذج

TN 10792، FP 1577، FN 1456، TP 10966. توقع الدقة A، والضبط P والاستدعاء R للصنف الإيجابي

A = 10792 + 1096624791 = 0.8777
P = 1096610966 + 1577 = 0.8743, R = 1096610966 + 1456 = 0.8828

ROC AUC: الحكم على الدرجات

python
from sklearn.metrics import roc_auc_score

probabilities = model.predict_proba(x_test)
roc_auc_score(y_test, probabilities[:, 1])

جربها: حرك العتبة

حساب درجات مراجعات جديدة

حسبت كلتيهما يدويا. توقع الناتج

python
reviews = ['Long lines and poor customer service',
           "Best meal I've ever had and awesome service, too!"]
model.predict_proba(vectorizer.transform(reviews))[:, 1]
text
[0.08594148 0.69681757]

الجزء 5

أين تخطئ حقيبة الكلمات

دقتها 88%، ومع ذلك يسهل خداعها

النفي يضيع

المراجعةالخصائصp
The food was goodfood وgood0.5885
The food was not good??

ترتيب الكلمات يضيع

المراجعةp
Great food but terrible service0.2591
Terrible food but great service0.2591

قبل أن تتمرن

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

  • قراءة Data/reviews.csv في Colab من مجلد غير موجود هناك
  • استدعاء plot_confusion_matrix: استخدم ConfusionMatrixDisplay.from_estimator
  • fit_transform على المراجعات الجديدة: النص الجديد يحتاج إلى vectorizer.transform([...])
  • تمرير سلسلة نصية مفردة إلى transform: فهي تحتاج إلى قائمة من النصوص
  • قراءة predict_proba(...)[0][0]: درجة المشاعر هي العمود 1
  • توقع أن تقلب not الدرجة بينما تحذفها stop_words='english'

مشروع فريقك

مرحلة المشروع: العروض والمناقشات

  • هذا الأسبوع: عروض فرق المشاريع ومناقشاتها
  • الأسبوع القادم، التسليم النهائي: الشيفرة في مستودع على GitHub، وفيديو مدته 5 دقائق، والمقترح، والعرض التقديمي، والشعار
  • إضافة إلى ذلك: واجهة مستخدم للمشروع (للهاتف المحمول أو الويب أو سطح المكتب)
  • في مشروعك نصوص؟ حولها إلى متجهات، ودرب، واحسب الدرجات باستخدام predict_proba، واحفظ النموذج والمفردات معا

الخلاصة

  1. تحليل المشاعر تصنيف ثنائي: الدرجة هي p، احتمال الإيجابية
  2. CountVectorizer: أحرف صغيرة، ورموز، وحذف كلمات التوقف، وكلمات مفردة وأزواج، والمفردات وحدها
  3. الدرجة هي σ(b + Σ w·x): كل كلمة معروفة تدفع بمقدار وزنها
  4. نموذج الدفتر: الدقة 0.8777، وROC AUC 0.9452 على 24,791 مراجعة اختبار
  5. تهمل حقيبة الكلمات الترتيب، ومع حذف كلمات التوقف تهمل النفي؛ وتعكس الأوزان بيانات التدريب

الجزء 6

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

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

نحو 5 دقائق

التمرين 1: التحويل إلى متجه يدويا

The waiter was rude and the food was cold.

text
tokens:   the, waiter, was, rude, and, the, food, was, cold
kept:     waiter, rude, food, cold
n-grams:  waiter, rude, food, cold, waiter rude, rude food, food cold

نحو 5 دقائق

التمرين 2أ: احسب الدرجة يدويا

The waiter was rude and the food was cold. لا توجد في المفردات إلا هذه الكلمات الأربع؛ b = -0.0488. احسب z وp والتنبؤ.

الخاصيةw
waiter-0.0937
rude-0.0364
food0.2302
cold-0.2052
z = -0.0488 + (-0.1051) = -0.1539
p = 11 + 1.1664 = 0.4616

نحو 5 دقائق

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

Excellent food, friendly staff, highly recommend! b = -0.0488

Σ w x = 3.3489, z = 3.3001, p = 11 + 0.0369 = 0.9644

نحو 5 دقائق

التمرين 3: اختيار عتبة

الهدف: إيجاد أكبر عدد من المراجعات السلبية. احسب TN / (TN + FP) عند العتبتين. أي العتبتين تفوز، وبأي ثمن؟

tTN, FPFN, TP
0.310232, 21371028, 11394
0.711251, 11182054, 10368
t = 0.3: 1023212369 = 0.8272, t = 0.7: 1125112369 = 0.9096

نحو 10 دقائق

التمرين 4: في Colab

  1. شغل الدفتر مع التغييرات الثلاثة؛ واحسب درجتي مراجعتي السيناريو باستدعاء واحد
  2. احسب درجتي The food was good وThe food was not good
  3. أعد الملاءمة باستخدام CountVectorizer(ngram_range=(1, 2), min_df=20): مع الإبقاء على كلمات التوقف
  4. التقسيم نفسه (random_state=0)، ثم أعد التدريب: ما عدد الخصائص، والدقة، وقيمة ROC AUC؟
  5. احسب درجتي مراجعتي الطعام مرة أخرى. ما الذي تغير، ولماذا؟

الإجابات

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

السؤالتشغيلنا
مراجعتا السيناريو[0.08594148 0.69681757]
مراجعتا الطعام، مع حذف كلمات التوقف0.5885 و0.5885
مع الإبقاء على كلمات التوقف: الخصائص، والدقة، وAUC74,938، و0.8967، و0.9574
مراجعتا الطعام، مع الإبقاء على كلمات التوقفgood 0.7082، وnot good 0.2912
السببأصبح not good خاصية، ووزنها -0.7838

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

Mahmoud Abasتحليل المشاعر بالتصنيف الثنائي