فهرست مطالب
هدف از تحلیل احساسات (Sentiment Analysis) چیست؟
تاکنون با تکنیکهای معروف بردارسازی مانند Bag-of-Words (مقاله bag of words چیست) و TF-IDF (مقاله TF-IDF چیست) آشنا شدیم. بعد از بهدستآوردن بردار عددی کلمات، میتوانیم آنها را در پروژههای مختلفی به کار ببریم.
تحلیل احساسات با پایتون یکی از معروفترین پروژههای classification در حوزه NLP است. بنابراین ما در این مقاله به صورت اختصاصی در مورد آن صحبت می کنیم!
هدف پروژههای تحلیل احساسات با پایتون، دستهبندی کردن یک نظر یا متن دلخواه به سه صورت مثبت (positive) و منفی (negative) یا خنثی (neutral) است.
به زبان خودمانیتر: در تحلیل احساسات با پایتون هدف تشخیص این است که یک متن دلخواه، حاوی حس مثبت است یا منفی یا خنثی، مثلاً "از طعم غذا راضی هستم" حاوی حس مثبت نسبت به طعم غذا است، ولی "ظاهر طرف به دلم ننشست" نشاندهنده حس منفی است و "به رستوران رفتم" حاوی حس یا قطبیت خنثی است.
فرض کنید که شما صاحب یک شرکت، بیزینس یا یک کسبوکار هستید و یک محصول یا سرویسی را به مشتریان و مخاطبان خود ارائه میدهید. هرچند وقت یکبار برای بررسی عملکرد خود، باید به بازخورد و نظرات مشتریانتان توجه کنید، اما این کار میتواند بسیار زمانبر باشد و با گسترش زمان و پیشرفت کسبوکارتان، سختتر نیز بشود. اینجاست که تحلیل احساسات به کمک شما میآید تا بتوانید نظرات و انتقادات ثبت شده در سایت، شبکههای اجتماعی و… را که به صورت دادۀ متنی دارید، بررسی و تحلیل نمایید.
به طور مشابه برای بررسی گفتمان سیاسی (political discourse)، جامعهشناسی دیجیتال (digital sociology) یا استخراج اطلاعات (information extraction) نیز میتوان از تحلیل احساسات استفاده کرد.
در دوره آموزش متن کاوی فارسی با شبکههای عصبی با تمرکز روی زبان فارسی، جدیدترین تکنیکهای پردازش زبان طبیعی با کدنویسی فراوان آموزش داده میشود.
مثال تحلیل احساسات با پایتون
به جمله زیر که نظر یک کاربر در مورد یک فیلم است، توجه کنید:
"This movie was amazing."
این جمله بهصورت “این فیلم فوقالعاده بود.” ترجمه میشود. در این جمله، تشخیص کلمهای که بار معنایی مثبت (فوقالعاده یا amazing) دارد، آسان است. حالا به جمله بعدی دقت کنید:
"That movie was amazingly bad."
که بهصورت “آن فیلم فوقالعاده بد بود.” ترجمه میشود. این جمله برخلاف جمله قبلی، کمی پیچیدهتر است! زیرا کلمهای که به تنهایی بار معنایی مثبت دارد (فوقالعاده یا amazingly) همراه با کلمه دیگری با بار معنایی منفی (بد یا bad)، ترکیب شده و باعث ایجاد بار معنایی منفیتری (فوقالعاده بد یا amazingly bad) برای جمله شده است و کلمه bad نقش منفی ساز پیدا کرده است.
جمله زیر، یک جمله دیگری از نظرات ثبت شده در یکی از شبکههای اجتماعی است:
"It's not unattractive!"
که بهصورت خودمانی “خیلی هم بد نیست!” ترجمه میشود. این جمله از دو جمله قبلی نیز پیچیدهتر است!
بهاینترتیب، تحلیل احساسات چیزی فراتر و پیچیدهتر از پیدا کردن کلمات مثبت و منفی است. استفاده از نفی (negations)، اصطلاحات (idioms)، زبان یا لهجه مخصوص (slang)، عبارتهای طعنهآمیز (sarcasm) و پیچیدگی جملات، تحلیل احساسات با پایتون را دشوارتر میکند.
به زبان خودمانیتر: در نگاه اول، تحلیل احساسات ساده به نظر میرسد و صرفاً باید لیستی از کلمات مثبت و منفی پیدا کرده و داخل متنها یک جستجو ساده بزنیم. در عمل ولی با پیچیدگیهای زبانی روبرو هستیم که در هر زبانی وجود دارد. البته در زبان شیرین فارسی، کار کمی پیچیدهتر است. ما تعداد متنوعی ضربالمثل و کنایه داریم که بهراحتی معنی جمله تغییر میدهند. گاهی تشخیص کنایهها برای انسان سخت است چه برسد به ماشین.
اگر میخواهید کار بر روی پروژههای واقعی NLP را یاد بگیرید، دوره آموزش پردازش زبان طبیعی مقدماتی را از دست ندهید.
تحلیل احساسات با پایتون براساس هستان شناسی (Ontology-Based)
اگر عبارت “sentiment analysis in Python” (تحلیل احساسات با پایتون) را در گوگل جستجو کنیم، احتمالاً پیادهسازیهایی را ببینیم که از کتابخانه TextBlob استفاده کردهاند. TextBlob کتابخانهای ساده است که امکان پیادهسازی بسیاری از تسکهای NLP مانند توکنسازی (tokenization)، تشخیص نقش دستوری کلمات (part-of-speech tagging)، تشخیص زبان (language detection) و تحلیل احساسات (sentiment analysis) را مستقیما ارائه می دهد. به راحتی میتوانیم آن را نصب و تست کنیم.
برای نصب کتابخانه TextBlob از دو خط کد زیر استفاده کنید:
pip install -U textblob
python -m textblob.download_corpora
برای تست اولیه آن میتوانیم کد زیر را اجرا کنیم (متغیر text شامل متنی از کتاب آلیس در سرزمین عجایب با کمی تغییر است):
from textblob import TextBlob
text = "That was a narrow escape, Alice said. A good deal frightened at the sudden change. But very glad to find herself still in existence;"
blob = TextBlob(text)
for sentence in blob.sentences:
print(sentence.raw, sentence.sentiment.polarity)
نتیجه زیر را بهعنوان خروجی خواهیم داشت:
That was a narrow escape, Alice said. -0.2
A good deal frightened at the sudden change. 0.35
But very glad to find herself still in existence; 0.65
در تحلیل احساسات با پایتون، یکی از مقادیری که TextBlob میتواند بازگرداند، مقداری به نام polarity است که عددی اعشاری بین بازه [1,1-] است و هرچقدر به 1 نزدیک تر باشد، یعنی جمله مثبتتر و هر چقدر به 1- نزدیک تر باشد، یعنی جمله منفیتر است.
بنابراین در TextBlob جمله اول را که دارای کلمات narrow و escape است، با امتیاز 0.2- بهصورت “کمی منفی” و جمله سوم را که دارای کلمه glad است، با امتیاز “0.65” به صورت “مثبت” تشخیص داده است.
البته تشخیص TextBlob برای جمله دوم با امتیاز 0.35 خیلی درست نیست. این امتیاز نشان میدهد که جمله مثبت است، اما وقتی آلیس با حالت ترسیده میگوید که معامله خوبی است! یعنی در کل جملۀ مثبتی نیست و بهتر بود منفی تشخیص داده میشد.
برای فهم بهتر نحوه عملکرد TextBlob در تحلیل احساسات با پایتون، جمله اولی را کمی تغییر میدهیم تا ببینیم TextBlob چگونه امتیاز polarity را محاسبه میکند و چه تاثیری روی امتیاز polarity میگذارد:
def polarity(text):
polarity_score = TextBlob(text).sentences[0].sentiment.polarity
print(f"{text} \t {polarity_score}")
return
# original sentence, positive
polarity("A good deal frightened at the change.")
# remove 'a good deal', you get neutral
polarity("Frightened at the change.")
# what if we add a negation, and change the noun
polarity("Happy at the change.")
# or add just the word very
polarity("Very frightened at the change.")
خروجی کد بالا به این صورت خواهد بود:
A good deal frightened at the change. 0.7
Frightened at the change. 0.0
Happy at the change. 0.8
Very frightened at the change. 0.2
طبق این نتیجه، کلمه frightened، کلمهای خنثی است اما کلمه very frightened همانند کلمه happy کلمهای مثبت تلقی شده است، که این نتیجه کاملا متناقض است (frightened به معنای ترسیده، very frightened به معنای بسیار ترسیده و happy به معنای خوشحال است).
TextBlob برای محاسبه امتیاز polarity جملات، به polarity صفتها (به همراه برخی قوانین اضافی برای مدیریت کلمات و عبارات منفیساز) توجه میکند. اگرچه کاملا مشخص است که کلمه frightened کلمهای منفی است، امتیاز polarity صفر به آن اختصاص داده شده؛ زیرا TextBlob به جای نقش صفت، آن را به عنوان یک فعل در نظر گرفته است!
بنابراین، TextBlob امتیازات مربوط به صفتها را از کجا آورده است و چطور تحلیل احساسات با پایتون را انجام میدهد؟
امتیازها مستقیماً از یک فایل خوانده میشوند که شامل بیش از 2900 کلمه است که این کلمات عمدتا از صفتها و برخی افعال تشکیل شدهاند. لیست این کلمه ها را میتوانید در TextBlob GitHub repository مشاهده کنید.
در این فایل دو آیتم برای کلمه amateur داریم:
TextBlob برای محاسبه امتیاز polarity جملات، به polarity صفتها (به همراه برخی قوانین اضافی برای مدیریت کلمات و عبارات منفیساز) توجه میکند. اگرچه کاملا مشخص است که کلمه frightened کلمهای منفی است، امتیاز polarity صفر به آن اختصاص داده شده؛ زیرا TextBlob به جای نقش صفت، آن را به عنوان یک فعل در نظر گرفته است!
میبینیم که کلمه amateur دو معنای کاملاً متفاوت و متضاد دارد. در حالت اول یعنی “lacking professional skill or expertise” به معنای “کسی که تجربه و تخصص کافی در یک زمینه ندارد”، بار معنایی منفی (negative) دارد و در حالت دوم یعنی “engaged in as a pastime” به معنای “کسی که یک حرفه یا حوزهای را به عنوان یک سرگرمی و نه به عنوان یک حرفه دنبال میکند”، بار معنایی خنثی (neutral) دارد.
همچنین هر کلمه دو ID متفاوت دارد: wordnet_id و cornetto_synset_id. این IDها نشاندهنده دو دیکشنری اصلی و مهم هستند:
- WordNet که قبلا، در lemmatizer کتابخانه NLTK با آن کار کردیم.
- Cornetto، که یک منبع لغوی (lexical resource) برای زبان هلندی (Dutch) است.
WordNet و Cornetto، دو دیکشنری با توضیحات اضافه هستند که بین مفاهیم ارتباط ایجاد میکنند. گاهی اوقات به چنین دیکشنری هایی، ontologies نیز گفته میشود که برای پیدا کردن موارد زیر میتوان از آنها استفاده کرد:
- کلمات مترادف (Synonyms)
- واژههای فراشمول (Hypernyms) و زیرشمول (Hyponyms):
معنای یک واژه خاص (hyponym) به طور کامل توسط یک واژه عام دیگر (hypernym) که معنای فراگیرتری دارد، پوشش داده شود. به طور مثال، ماشین (hyponym) نوعی وسیله نقلیه (hypernym) است.
- کلمات جزء (Holonyms) و کلمات کل (Meronyms): انگشت (holonyms) بخش یا جزئی از دست (meronyms) است.
این اطلاعات، اطلاعات جذابی هستند و هرکسی که در حوزه NLP کار میکند باید با آنها آشنا باشد.
از مبحث اصلی یعنی تحلیل احساسات با پایتون، با استفاده از کتابخانه TextBlob دور نشویم.
همانطور که برای متن آلیس در سرزمین عجایب دیدیم، TextBlob از رویکردی مبتنی بر دیکشنری (dictionary-based) استفاده میکند. در این رویکرد، هر کلمه دارای polarity (مثبت یا منفی) و ثابت است، اما به دلایل مختلفی نتایج این رویکرد، چندان قابل استناد نیست. زیرا:
- چرا باید امتیاز ثابت باشد؟ چرا متناسب با شرایط و موضوع، امتیازها تغییر نمیکنند؟
- نمیتوان کلمات جدیدی را که در دیکشنری نیستند، مدیریت کرد. اصطلاحا به این کلمات out-of-vocabulary یا OOV گفته میشود.
- به context کلمات توجه نمیکند. به طور مثال، عبارت green beans با امتیاز 0.2-، عبارتی منفی است زیرا کلمه green در دیکشنری TextBlob، امتیازی منفی دارد در صورتی که معنی عبارت “green beans” لوبیا سبز است و خنثی است.
- امتیاز بعضی کلمات، سلیقهای و بدون هیچ دلیل موجهی در نظر گرفته شده است. چرا کلمه green باید منفی باشد، درحالیکه کلمه blue خنثی است؟
- دارای سوگیری (bias) است (میتوان آن را در برخی از کلمات دیکشنری TextBlob مشاهده کرد).
- هدف پروژههای تحلیل احساسات با پایتون، دستهبندی کردن یک متن دلخواه به دو صورت مثبت و منفی است.
- Sentiment Analysis یکی از معروفترین پروژههای classification در حوزه NLP است.
- استفاده از negations، idioms، slang، عبارتهای طعنهآمیز و پیچیدگی جملات، تحلیل احساسات را دشوارتر میکند.
- برای انجام تحلیل احساسات با پایتون، میتوان با استفاده از کتابخانه TextBlob که بر اساس دیکشنری کار میکند، sentiment score را محاسبه کرد. از مزایای TextBlob سادگی استفاده از آن است اما همزمان با سادگی، بسیار محدود است. بنابراین هنگام استفاده از آن باید بسیار دقت کرد.
در این مقاله، با کتابخانه TextBlob برای تحلیل احساسات با پایتون آشنا شدیم. در قسمت بعدی این مجموعه آموزشی، با تکنیک بردارسازی مهمی آشنا میشویم و میفهمیم word embeddings چیست.