في نافذة الطباعة اختر «حفظ كملف 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 | المشاعر في صورة احتمال؛ من النص إلى الأعداد باستخدام CountVectorizer | 40 دقيقة |
| 3 | حساب درجة مراجعة يدويا | 20 دقيقة |
| 4 | الدفتر في Colab: التدريب، والتقييم، وحساب الدرجات | 20 دقيقة |
| 5 | حدود النموذج، ومشروعك | 10 دقائق |
| 6 | تمارين مع الإجابات | 30 دقيقة |
الجزء 1
المشاعر في صورة احتمال
التصنيف الثنائي على النص
ما تحليل المشاعر؟
- تحليل المشاعر
- إعطاء النص درجة من 0 إلى 1، حيث 0 مشاعر سلبية و1 مشاعر إيجابية.
| المصطلح | في بيانات هذا الأسبوع |
|---|---|
| العينة | مراجعة واحدة، أي سلسلة نصية |
التسمية (label) y | 0 سلبية، 1 إيجابية |
الخصائص (features) x | أعداد الكلمات في المراجعة |
الدرجة p | احتمال أن تكون التسمية 1 |
خط المعالجة
المراجعة
سلسلة نصية
التحويل إلى متجه
CountVectorizer
حساب z
b + Σ w·x
الضغط
p = σ(z)
القرار
p ≥ 0.5: إيجابية
الجزء 2
من النص إلى الأعداد
CountVectorizer وحقيبة الكلمات
حقيبة الكلمات
- حقيبة الكلمات
- احتفظ بقائمة من الكلمات المعروفة، هي المفردات، وعبر عن كل نص بعدد مرات ظهور كل كلمة من القائمة فيه.
- ▸لا يستطيع النموذج أن يعمل على النص: فهو يحتاج إلى أعداد
- ▸صف لكل نص، وعمود لكل مدخل في المفردات، والخلايا أعداد
- ▸يهمل ترتيب الكلمات: ولهذا تسمى حقيبة
CountVectorizer في الدفتر
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عد كل مدخل: صف واحد لكل مراجعة
من الدفتر
مثال محلول: ما يبقيه المحول
text = vectorizer.transform(['The long l3ines and; pOOr customer# service really turned me off...123.'])
text = vectorizer.inverse_transform(text)
print(text)الخطوة 1: الأحرف الصغيرة والرموز
the, long, l3ines, and, poor, customer, service,
really, turned, me, off, 123الخطوة 2: حذف كلمات التوقف
long, l3ines, poor, customer, service, really, turned, 123الخطوة 3: إضافة الأزواج
long l3ines, l3ines poor, poor customer, customer service,
service really, really turned, turned 123الخطوة 4: الإبقاء على المفردات
[array(['customer', 'long', 'poor', 'really', 'service', 'turned'],
dtype='<U25')]مثال محلول: ثلاث مراجعات في صورة مصفوفة أعداد
الكلمات المفردة وحدها. توقع الأعمدة، وخلية المراجعة 2 تحت awesome: فالمحول يعد
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']) 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
| الرمز الرياضي | المعنى |
|---|---|
b | الحد الثابت، model.intercept_: هنا -0.0488 |
w_i | وزن مدخل المفردات i، من model.coef_ |
x_i | عدد مرات ظهور المدخل i: 0 في الغالب |
σ وe | الدالة السينية؛ وe = 2.71828، وσ(0) = 0.5 |
أي الكلمات تدفع بقوة أكبر؟

- ▸الوزن الأكبر من 0 يدفع نحو الإيجابية، والأصغر من 0 نحو السلبية
- ▸أدنى الأوزان:
disappointment-2.1646، وwaste-2.1606، وworst-2.1519 - ▸أعلى الأوزان:
funniest1.6471، و10 101.4037، وexcellent1.3094 - ▸لا كلمة معروفة إطلاقا:
p = σ(-0.0488) = 0.4878
يدويا، الخطوة 1
مثال محلول: Long lines and poor customer service
ما الخصائص التي يراها النموذج؟
| الخاصية | x | w | w·x |
|---|---|---|---|
customer | 1 | -0.1980 | -0.1980 |
lines | 1 | -0.1184 | -0.1184 |
long | 1 | -0.0284 | -0.0284 |
poor | 1 | -1.4874 | -1.4874 |
service | 1 | -0.4832 | -0.4832 |
الخطوة 2: حساب z
b = -0.0488، والأوزان مقربة إلى 4 منازل عشرية
الخطوة 3: الدالة السينية والقرار
يدويا، الخطوة 1
مثال محلول: Best meal I've ever had
Best meal I've ever had and awesome service, too!
| الخاصية | x | w | w·x |
|---|---|---|---|
awesome | 1 | 0.7310 | 0.7310 |
best | 1 | 0.7090 | 0.7090 |
meal | 1 | 0.0062 | 0.0062 |
service | 1 | -0.4832 | -0.4832 |
ve | 1 | -0.0820 | -0.0820 |
الخطوة 2: قيمتا z وp
تقول الخطة 0.9 أو أكثر
لماذا ليست 0.9؟
إيجابية، لكن predict_proba تعطي 0.69682
- ▸تعلم النموذج من مراجعات الأفلام: وفيها
serviceكلمة سلبية (-0.4832) - ▸ووزن
staffأيضا -0.4587، بينما لا يتجاوز وزنrudeالقيمة -0.0364 - ▸في النص القصير خصائص قليلة، لذا يبقى
Σ w·xصغيرا وتبقىpقرب المنتصف - ▸يعتمد الرقم على بيانات التدريب؛ ولو دربنا النموذج بالشيفرة نفسها على مراجعات مطاعم لتعلم أوزان المطاعم
جربها: مقياس المشاعر
الجزء 4
الدفتر في Colab
التدريب، والتقييم، وحساب الدرجات
افتح الدفتر في Colab
https://colab.research.google.com/github/
jeffprosise/Machine-Learning/blob/master/
Sentiment%20Analysis.ipynb| في الدفتر | غيره إلى |
|---|---|
read_csv('Data/reviews.csv', ...) | اقرأ الملف من المستودع (الشريحة التالية) |
plot_confusion_matrix(...) | ConfusionMatrixDisplay.from_estimator(...) |
pickle.dump(..., open('Data/sentiment.pkl', 'wb')) | احفظه في 'sentiment.pkl' |
تحميل البيانات، وحذف التكرارات
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()التحويل إلى متجهات والتقسيم
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 للاختبار
تدريب النموذج
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(max_iter=1000, random_state=0)
model.fit(x_train, y_train)- ▸تتعلم
fit33,752 وزنا، وزنا لكل مدخل في المفردات، إضافة إلى الحد الثابتb - ▸تعطي
max_iter=1000خوارزمية الحل (solver) مجالا لتتقارب رغم هذا العدد الكبير من الخصائص؛ واحتاج تشغيلنا إلى 78 تكرارا - ▸لا جديد:
LogisticRegressionنفسه الذي استخدمناه في الأسبوع 4
مصفوفة الالتباس
على مراجعات الاختبار الـ24,791

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 للصنف الإيجابي
ROC AUC: الحكم على الدرجات
from sklearn.metrics import roc_auc_score
probabilities = model.predict_proba(x_test)
roc_auc_score(y_test, probabilities[:, 1])جربها: حرك العتبة
حساب درجات مراجعات جديدة
حسبت كلتيهما يدويا. توقع الناتج
reviews = ['Long lines and poor customer service',
"Best meal I've ever had and awesome service, too!"]
model.predict_proba(vectorizer.transform(reviews))[:, 1][0.08594148 0.69681757]الجزء 5
أين تخطئ حقيبة الكلمات
دقتها 88%، ومع ذلك يسهل خداعها
النفي يضيع
| المراجعة | الخصائص | p |
|---|---|---|
| The food was good | food وgood | 0.5885 |
| The food was not good | ? | ? |
ترتيب الكلمات يضيع
| المراجعة | p |
|---|---|
| Great food but terrible service | 0.2591 |
| Terrible food but great service | 0.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.
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 |
food | 0.2302 |
cold | -0.2052 |
نحو 5 دقائق
التمرين 2ب: مراجعة إيجابية جدا
Excellent food, friendly staff, highly recommend! b = -0.0488
نحو 5 دقائق
التمرين 3: اختيار عتبة
الهدف: إيجاد أكبر عدد من المراجعات السلبية. احسب TN / (TN + FP) عند العتبتين. أي العتبتين تفوز، وبأي ثمن؟
| t | TN, FP | FN, TP |
|---|---|---|
| 0.3 | 10232, 2137 | 1028, 11394 |
| 0.7 | 11251, 1118 | 2054, 10368 |
نحو 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 |
| مع الإبقاء على كلمات التوقف: الخصائص، والدقة، وAUC | 74,938، و0.8967، و0.9574 |
| مراجعتا الطعام، مع الإبقاء على كلمات التوقف | good 0.7082، وnot good 0.2912 |
| السبب | أصبح not good خاصية، ووزنها -0.7838 |
افتح هذا الدرس
Mahmoud Abas|تحليل المشاعر بالتصنيف الثنائي