خانه / علم داده / پردازش زبان طبیعی / دست به کد: تحلیل احساسی نظرات کاربران درباره یک فیلم

دست به کد: تحلیل احساسی نظرات کاربران درباره یک فیلم

در بخش اول از مجموعه مقالات آموزشی پردازش متن، با مفاهیم پایه متن کاوی و همچنین کتابخانه فارسی هضم برای کار با متون فارسی آشنا شدید. در ادامه این سری آموزشی با بررسی یکی از مسابقات پردازش متن سایت معروف کگل، به صورت عملی با جنبه های نوین این شاخه از علم داده و تحلیل احساسی نظرات کاربران درباره یک فیلم و تعیین مثبت و منفی بودن یک نظر  آشنا خواهیم شد. روش اصلی این کار هم ایجاد بردار عددی متناظر با هر نظر به کمک روش صندوقچه کلمات و ساخت یک مدل جنگل تصادفی براساس داده های برچسب خورده و اعمال این مدل بر روی نظرات جدید خواهد بود. البته، هدف از این مسابقه پردازش متن کگل، آشنایی عملی با مفهوم یادگیری عمیق از طریق به کارگیری الگوریتم Word2Vec گوگل و کاربرد آن در حوزه تحلیل احساسات بود که این نوشتار بخش اول ازین آموزش را شامل می شود و به تدریج سایر آموزش ها هم بر روی سایت قرار خواهد گرفت.

در نوشتار حاضر، مفاهیم پایه پردازش متن بخصوص مفهوم صندوقچه کلمات (Bag of Words) و کار با کتابخانه NLTK پایتون به صورت مقدماتی آموزش داده خواهد شد.

با توجه به خریداری شدن کگل توسط گوگل، برای باز شدن صفحات اصلی آموزش و داده ها نیاز به وی پی ان خواهید داشت.

NLP چیست؟

NLP یا پردازش زبان طبیعی، مجموعه تکنیک هایی است که برای درک متون و استخراج اطلاعات مفید از آنها استفاده می شود. در این مقاله با بارگزاری و پاکسازی نظرات کاربران سایت سینمایی IMDB تا حدودی با این تکنیک ها آشنا خواهید شد. بعد از پاکسازی و پردازش اولیه نظرات کاربران، به کمک مدل صندوقچه کلمات (Bag of Words) هر نظر را به یک بردار عددی تبدیل می کنیم و سپس به کمک الگوریتم جنگل تصادفی، مدلی برای پیش بینی نظرات کاربران خواهیم ساخت و نهایتاً  پیش بینی خواهیم کرد که یک نظر کاربر، لایک محسوب می شود یا دیسلایک.

با اینکار می توانیم به صورت خودکار ، نظر کلی کاربران برای یک فیلم یا سریال را به دست آوریم. توضیح اینکه منظور از مدل در مباحث داده کاوی و یادگیری ماشین، ساخت الگوریتمی است که به کمک آن بتوان رفتار داده ها را پیش بینی کرد.

پیش از شروع کار

این آموزش بر مبنای زبان پایتون نوشته شده است. بنابراین اگر تابحال از پایتون استفاده نکرده اید، توصیه می شود از این بخش برای آشنایی با این ساختار استفاده کنید. در صورتی که با پایتون و تکنیک های NLP آشنایی دارید، این آموزش مناسب شما نخواهد بود.

توصیه می کنیم از توزیع پایتون آناکوندا استفاده کنید که تمام کتابخانه لازم و ضروری را داشته، کار با آن ساده است و نصب و به روزرسانی کتابخانه های آن هم به راحتی انجام می پذیرد. بعد از نصب آناکوندا، با بالاآوردن یک کتابچه IPython، کدهای زیر در سلول های کتابچه وارد کرده و در صورت نیاز، برای خودتان یادداشت برداری کنید. از طرفی می توانید از کتابچه های آنلاین مایکروسافت یا سایت خود کگل (بخش Scripts) هم استفاده کنید و همانجا کدها را نوشته و تست نمایید.

در طول این آموزش، ما از ماژول های مختلف پایتون برای پردازش متن، یادگیری عمیق، جنگل های تصادفی و سایر مفاهیم استفاده خواهیم کرد. فایل ها و کتاب های زیادی درباره ی NLP و پردازش متن و بخصوص کتابخانه اصلی پردازش متن در پایتون یعنی NLTK نوشته شده است. این آموزش نیز آموزش جامع پایتون یا  NLP نبوده و تنها به منظور کمک به یادگیری و ایجاد یک دید کلی درباره تکنیک های پردازش متن آماده شده است. کد این آموزش در اینجا قرار داده شده است.

خواندن داده ها

فایل های ضروری استفاده شده در آموزش را می توانید از این بخش دانلود کنید. اولین فایل مورد نیاز، فایل unlabeledTrainData.tsv است که شامل اطلاعات نظرات کاربران به تعداد ۲۵۰۰۰ تا برای فیلم های IMDB است که هر کدام دارای برچسب مثبت یا منفی برای نمایش احساسات کاربر می باشد. ( معمولاً برای ساختن یک مدل مناسب، داده های اولیه که در اینجا تعدادی از نظرات بازدید کنندگان سایت است، توسط کاربران انسانی بررسی و برچسب مثبت و منفی آنها تعیین می شود)

پس از آن باید فایل tsv (فایلی که داده های آن در هر سطر با تب tab از هم جدا شده اند) را درون برنامه پایتون خود باز کنیم. بنابراین اول یک فایل پایتون خالی درون پای چارم یا هر محیط ویرایشگر پایتون که می پسندید، باز کنید یا یک سلول جدید درون کتابچه پایتون خود ایجاد کنید و مطابق زیر، فایل فوق را باز کرده، محتوای آنرا در یک متغیر به نام train بارگزاری کنید.

برای انجام این عمل، ما از کتابخانه pandas استفاده می کنیم. این کتابخانه تابع read_csv را برای خواندن و نوشتن فایل های متنی داده ای ارائه می دهد. اگر شما پیش ازین از pandas استفاده نکرده اید نیاز به نصب آن خواهید داشت هر چند توزیع های معروف پایتون مثل Anaconda و Canopy به صورت خودکار این کتابخانه های اصلی را درون خود دارند:


1
2
3
4
5
# Import the pandas package, then use the "read_csv" function to read
# the labeled training data
import pandas as pd      
train = pd.read_csv("labeledTrainData.tsv", header=, \
                    delimiter="\t", quoting=3)

در اینجا، “header=0” بدین معناست که اولین خط (سطر شماره ۰) فایل شامل نام ستون هاست.  با استفاده از “delimiter=\t” تعیین می شود که جداکننده فیلدها تب (tab) می باشد.   عبارت quoting=3 بیان می کند که پایتون از دابل کوتیشن چشم پوشی کند،  در غیر اینصورت در تلاش برای خواندن فایل دچار مشکل شده و با خطا روبرو خواهد شد.

با اجرای دستور فوق، تمام داده های موجود در فایل، به صورت جدولی با ۲۵۰۰۰ سطر و سه ستون درون متغیر train قرار خواهند گرفت (یک ماتریس ۳*۲۵۰۰۰)

با استفاده از کد زیر می توان اطمینان حاصل کرد که ۲۵۰۰۰ سطر و سه ستون خوانده شده است:


1
2
3
4
5
>>> train.shape
(25000, 3)

>>> train.columns.values
array([id, sentiment, review], dtype=object)

سه ستون با نام های id، (احساس یا حالت) sentiment و نظر داریم. به اولین نظر موجود در این جدول بارگزاری شده در حافظه با دستور print یک نگاه می اندازیم :


1
print train["review"][10]

یک نظر باید متنی شبیه به این باشد :

1
2
3
4
5
"With all this stuff going down at the moment with MJ i've started listening to his music, watching the odd documentary here and there, watched The Wiz and watched Moonwalker again.
Maybe i just want to get a certain insight into this guy who i thought was really cool in the eighties just to maybe make up my mind whether he is guilty or innocent.
Moonwalker is part biography, part feature film which i remember going to see at the cinema when it was originally released. Some of it has subtle messages about MJ's feeling towards the press and also the obvious message of drugs are bad m'kay.

<br/><br/>..."

اطلاعات بالا، شامل تگ های اچ تی ام ال مانند <br/>، اختصارات، علائم نقطه گذاری و همه ی داده های اضافی و نامعتبریست که هنگام خواندن اطلاعات از وب سایتها پیش می آید. زمانی را برای مشاهده ی سایر نظرات هم اختصاص دهید تا با مشکلات و داده های نامعتبر بیشتر آشنا شوید. در بخش بعد به چگونگی تمیز کردن متن برای یادگیری ماشین می پردازیم.

پاکسازی داده و پردازش متن

حذف کدهای html به کمک کتابخانه BeautifulSoup

ابتدا به حذف تگ های اچ تی ام ال می پردازیم. به این منظور، از کتابخانه ی معروف BeautifulSoup که برای خواندن و پردازش اطلاعات وب سایتها نوشته شده است، استفاده خواهیم کرد. اگر قبلا این کتابخانه را نصب نکرده اید به نصب آن در خط فرمان سیستم خود به صورت زیر بپردازید (البته نصب کتابخانه ها را با هر روشی که می خواهید می توانید انجام دهید، مثلاً در پای چارم، باید به قسمت تنظیمات، بخش مفسرهای پایتون بروید و بعد از انتخاب مفسر پایتون مورد نظر، علامت + کنار آن را بزنید تا صفحه جستجو و نصب کتابخانه ها باز شود):


1
$ pip install BeautifulSoup4

سپس داخل فایل پایتونی که ایجاد کرده اید آنرا بارگزاری کرده و برای استخراج متن خالص و بدون برچسب HtML، از آن به شکل زیر استفاده می کنیم:


1
2
3
4
5
6
7
8
9
10
# Import BeautifulSoup into your workspace
from bs4 import BeautifulSoup            

# Initialize the BeautifulSoup object on a single movie review    
example1 = BeautifulSoup(train["review"][10])  

# Print the raw review and then the output of get_text(), for
# comparison
print train["review"][10]
print example1.get_text()

تابع ()get_text متن یک نظر را بدون تگ ها و نشانه گذاری های HTML به ما برمی گرداند. اگر نگاهی به مستندات BeautifulSoup  بیندازید، مشاهده خواهید کرد که این کتابخانه از آنچه برای این مجموعه داده نیاز دارید بسیار قوی تر است. با این حال به دلیل دردسرهای روشهای معمول حذف برچسب ها مثل استفاده از عبارات باقاعده ، حتی برای برنامه های ساده ای مانند مثال ما نیز بهترین روش استفاده از کتابخانه هایی استاندارد مانند BeautifulSoup است.

بررسی نقطه گذاری، اعداد و ایست واژه ها: عبارات منظم و NLTK

در زمان پاکسازی داده ها ما باید به ابتدا به هدف اصلی فرآیند پردازش متن فکر کنیم و بر اساس آن، راه حلی برای آن حذف اضافات در نظر بگیریم. برای بسیاری از موارد، حذف علائم نقطه گذاری جزء نیازهای ما خواهد بود چون ما اکثراً به خود متن و کلمات آن کار خواهیم داشت و علائم نقطه گذاری را جزء کلمات محسوب نمی کنیم. هر چند اگر بخواهیم به صورت دقیق تر و هوشمندتر به تحلیل احساسات کاربران بپردازیم، ممکن است این علائم نقطه گذاری هم در بیان نظر واقعی یک کاربر به ما کمک کنند : اگر علائمی مانند !!! یا : – ( به عنوان روشی برای بیان احساس، استفاده شده باشد، حذف آن، داده ای ارزشمند را از بین خواهد برد. در این آموزش برای سادگی، ما تمام نقطه گذاری ها را حذف می کنیم. اما برای دقت بیشتر مدلی که قصد ساخت آنرا داریم، می توانید از علائم نقطه گذاری هم استفاده کنید.

برای مطالعه :   آشنایی با الگوریتم های ضروری یادگیری ماشین - بخش اول : مقدمه

به طور مشابه، در این آموزش ما اعداد را هم حذف می کنیم، اما می توانیم روشهای دیگری هم برای کار با اعداد در متون به کار بریم مثلاً آنها را به معادل حرفی و غیر عددیشان تبدیل کنیم (مثلا به جای ۹۷ قرار دهیم نود و هفت) ویا تمام اعداد را با یک عبارت جایگزین مثل NUM جایگزین کنیم.

برای حدف نقاط و اعداد، ما از کتابخانه اصلی عبارات باقاعده در پایتون یعنی re استفاده می کنیم. این کتابخانه به صورت پیش فرض در پایتون وجود دارد و برای استفاده از آن نیاز به نصب چیزی نداریم. برای آگاهی از جزئیات نحوه ی کار با عبارات منظم به اینجا مراجعه نمایید. کد زیر را اجرا کنید:


1
2
3
4
5
6
import re
# Use regular expressions to do a find-and-replace
letters_only = re.sub("[^a-zA-Z]",           # The pattern to search for
                      " ",                   # The pattern to replace it with
                      example1.get_text() )  # The text to search
print letters_only

مرور کامل عبارات منظم از محدوده ی این آموزش فراتر است، اما در حال حاضر لازم است بدانید که [] برای فیلترگذاری روی کاراکترها و ^ بیانگر نفی یا not است. به عبارت دیگر، جمله ی re.sub() در کد بالا بیان می کند که “هر چیزی به غیر از حروف کوچک و بزرگ را بیاب و آن را با فضای خالی جایگزین کن”.

در مرحله بعد متن به دست آمده را به حروف کوچک تبدیل کرده و سپس کلمات آن را جداسازی می کنیم (بعبارتی tokenization در زبان NLP):


1
2
lower_case = letters_only.lower()        # Convert to lower case
words = lower_case.split()               # Split into words

در نهایت باید تعداد تکرار لغاتی که معنی خاصی ندارند را مشخص کنید. ایست واژه ها کلماتی هستند که با وجود تکرار فراوان در متن دارای اهمیت کمی از نظر معنایی می باشند. از جمله این کلمات در فارسی می توان به “اگر”، “و”، “ولی”، “که” و غیره اشاره کرد. در نگاه اول تصور بر این است که فقط کلمات ربط و تعریف، ایست واژه هستند ولی بسیاری از افعال، افعال کمکی، اسمها، قید ها و صفات نیز به عنوان ایست واژه شناخته شده اند. در انگلیسی لغاتی مانند a، and، is و the جزء ایست واژه ها می باشند. به راحتی می توان از یک پکیج پایتون که حاوی لیستی از ایست واژه ها باشد، برای حذف آنها از لیست کلمات یک نظر استفاده کرد. بیایید یک لیست از ایست واژه ها را از ابزار زبان طبیعی (Natural Language Toolkit) یا NLTK ایمپورت کنیم. چنانچه پیش از این کتابخانه ی مدنظر را نصب نکرده اید، ابتدا بایستی کتابخانه را نصب کرده و به شکل زیر پکیج های داده ی آن را نصب کنیم:


1
2
import nltk
nltk.download()  # Download text data sets, including stop words

حال می توانید برای به دست آوردن لیستی از ایست واژه ها از nltk استفاده نمایید.


1
2
from nltk.corpus import stopwords # Import the stop word list
print stopwords.words("english")

کد فوق به شما اجازه می دهد تا لیست ایست واژه ها در زبان انگلیسی را مشاهده کنید. برای حذف ایست واژه ها از نظرات کد زیر را می نویسیم:


1
2
3
# Remove stop words from "words"
words = [w for w in words if not w in stopwords.words("english")]
print words

این کد، هر کلمه در ایست واژه ها را بررسی کرده و تمام تطبیق های یافت شده با اعضای این لیست را حذف می کند. بعد از این مراحل، نظر داده شده، باید به شکل زیر درآمده باشد:


1
2
3
4
5
6
7
8
9
[u'stuff', u'going', u'moment', u'mj', u've', u'started', u'listening',
u'music', u'watching', u'odd', u'documentary', u'watched', u'wiz',
 u'watched', u'moonwalker', u'maybe', u'want', u'get', u'certain',
 u'insight', u'guy', u'thought', u'really', u'cool', u'eighties', u'maybe',
 u'make', u'mind', u'whether', u'guilty', u'innocent', u'moonwalker',
 u'part', u'biography', u'part', u'feature', u'film', u'remember', u'going',
 u'see', u'cinema', u'originally', u'released', u'subtle', u'messages'
, u'mj', u'feeling', u'towards', u'press', u'also', u'obvious', u'message'
, u'drugs', u'bad', u'm', u'kay',.....]

نگران علامت u قرار کرفته در هر لغت نباشید. این علامت تنها بیانگر نمایش داخلی هر کلمه به عنوان یک رشته ی یونیکد در پایتون است.

کارهای زیاد دیگری نیز وجود دارد که می توانیم آنها را بر روی داده اعمال کنیم. برای مثال، ریشه یابی لغوی پورتر (Porter Stemming) و ریشه یاب گرامری یا Lemmatizing (هردو در NLTK در دسترس اند) به ما اجازه می دهند تا کلمات با پسوند مشابه مانند messages، messaging و message را تشخیص دهیم. Stemming فقط به خود کلمه نگاه می کند و مثلا “ها” یا “می” را از اول و آخر کلمه حذف می کند. اما Lemmatizing به بستر کلمه یعنی کلمات اطراف نیز حساس است و بنابراین برای اینکه شکل درست و اصلی یک کلمه را برگرداند، باید نوع کلمه را دقیق بداند. شناسایی این کلمات در موارد خاص می تواند مفید باشد. در این آموزش برای سهولت کار به این ویژگی ها پرداخته نخواهد شد.

اعمال همزمان همه ی کدها

حال به درج کد کاملی از پاکسازی یک نظر می پردازیم. توجه داشته باشید که شما باید این کد را جهت پاکسازی هر ۲۵۰۰۰ نظر موجود در داده های آموزشی اعمال کنید. برای اینکه کد ما قابل استفاده مجدد باشد. یک تابع ایجاد می کنیم که در هر زمان بتوان به فراخوانی آن پرداخت:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def review_to_words( raw_review ):
    # Function to convert a raw review to a string of words
    # The input is a single string (a raw movie review), and
    # the output is a single string (a preprocessed movie review)
    #
    # 1. Remove HTML
    review_text = BeautifulSoup(raw_review).get_text()
    #
    # 2. Remove non-letters        
    letters_only = re.sub("[^a-zA-Z]", " ", review_text)
    #
    # 3. Convert to lower case, split into individual words
    words = letters_only.lower().split()                            
    #
    # 4. In Python, searching a set is much faster than searching
    #   a list, so convert the stop words to a set
    stops = set(stopwords.words("english"))                  
    #
    # 5. Remove stop words
    meaningful_words = [w for w in words if not w in stops]  
    #
    # 6. Join the words back into one string separated by space,
    # and return the result.
    return( " ".join( meaningful_words ))

دو کار جدید در این کد نهایی انجام شده است : اول اینکه ما لیست ایست واژه ها را به یک نوع داده ی متفاوت، یک مجموعه، تبدیل کردیم. این امر جهت تسریع کار انجام می شود. زمانی که ما دهها یا هزاران بار تابع را فراخوانی می کنیم، به سرعت بالایی نیاز داریم و جستجوی یک عنصر در یک مجموعه در پایتون، به مراتب سریعتر از جستجوی آن در یک لیست است.

دوم اینکه، در خط آخر تابع فوق، مجدداً کلمات به دست آمده را به هم دیگر میچسبانیم تا یک رشته واحد ایجاد شود. این موضوع، کار با یک نظر را ساده تر خواهد کرد همچنین خروجی و نمایش آن هم بهتر خواهد بود.

پس از تعریف تابع بالا، اگر شما این تابع را برای یک نظر فراخوانی کنید:


1
2
clean_review = review_to_words( train["review"][] )
print clean_review

همان خروجی مشابه با اجرای گام به گام مراحل بالا را خواهید دید.

حال این تابع را برای پاکسازی یک باره ی تمام مجموعه آموزشی می نویسیم (این عمل بسته به کامپیوتر شما ممکن است چندین دقیقه طول بکشد):


1
2
3
4
5
6
7
8
9
10
11
12
# Get the number of reviews based on the dataframe column size
num_reviews = train["review"].size

# Initialize an empty list to hold the clean reviews
clean_train_reviews = []

# Loop over each review; create an index i that goes from 0 to the length
# of the movie review list
for i in xrange( , num_reviews ):
    # Call our function for each one, and add the result to the list of
    # clean reviews
    clean_train_reviews.append( review_to_words( train["review"][i] ) )

گاهی اوقات انتظار برای اجرای این کد می تواند آزار دهنده باشد. این عمل که بتوان حالت اجرای پروسس را مشاهده نمود می تواند مفید باشد. برای اینکه پس از پردزش هر ۱۰۰۰ نظر، وضعیت فعلی روند پردازش، نمایش داده شود، می توان کد زیر را به کد قبل اضافه کرد:


1
2
3
4
5
6
7
print "Cleaning and parsing the training set movie reviews...\n"
clean_train_reviews = []
for i in xrange( , num_reviews ):
    # If the index is evenly divisible by 1000, print a message
    if( (i+1)%1000 == ):
        print "Review %d of %d\n" % ( i+1, num_reviews )                                                                    
    clean_train_reviews.append( review_to_words( train["review"][i] ))

ایجاد بردار ویژگی برای هر نظر (با استفاده از scikit-learn)

حال که نظرات را در داده های آموزشی پاکسازی و مرتب کردیم، به چگونگی تبدیل آنها به نوع عددی برای یادگیری ماشین می پردازیم. یک روش معمول برای اینکار، روش صندوقچه ی کلمات (Bag of Words) است. مدل صندوقچه کلمات، ابتدا یک فرهنگ لغت (لیست تمام کلمات) از تمام فایلهای متنی موجود ایجاد می کند و سپس هر سند را با استفاده از شمارش تعداد دفعاتی که هر کلمه از این فرهنگ لغت در آن ظاهر شده است، مدلسازی می کند.

به عنوان مثال، دو جمله زیر زیر در نظر گرفته شده است:

برای مطالعه :   علم داده به زبان ساده - یادگیری آماری #1

جمله ی ۱: “The cat sat on the hat”

جمله ی ۲: “The dog ate the cat and the hat”

در این دو جمله فرهنگ لغت زیر را داریم:

{ the, cat, sat, on, hat, dog, ate, and }

برای بدست آوردن مدل صندوقچه ی کلمات مثال فوق، تعداد دفعاتی که هر کلمه در هر جمله تکرار شده است را می شماریم. در جمله ی ۱، کلمه ی the، دو بار ظاهر شده است و کلمات cat، sat ، on و hat هر کدام یکبار ظاهر شده اند. بنابراین بردار ویژگی ها برای جمله ۱ به صورت زیر است:

{ the, cat, sat, on, hat, dog, ate, and }

Sentence 1: { 2, 1, 1, 1, 1, 0, 0, 0 }

و به طور مشابه برای جمله ی ۲ خواهیم داشت:

{ ۱, ۱, ۱, ۱, ۰, ۰, ۱, ۳}

این برداری که برای مدلسازی یک جمله ایجاد کرده ایم، بردار ویژگی ما را تشکیل می دهد که یک کمیت عددی به ازای هر جمله است و می تواند ورودی بسیاری از الگوریتم های یادگیری ماشینی باشد که تنها اعداد را به عنوان ورودی قبول می کنند.

در داده های IMDB ما تعداد زیادی نظر داریم که باعث ایجاد فرهنگ لغت بزرگی خواهد شد. برای محدود کردن اندازه ی بردارهای ویژگی، می توانیم برای فرهنگ لغت خود اندازه ی ماکزیمم تعیین کنیم. در زیر ما از ۵۰۰۰ کلمه ی دارای تکرار بیشتر، برای ساخت فرهنگ لغت استفاده کرده ایم (بخاطر داشته باشید که ایست واژه ها حذف شده اند).

ما از ماژول feature_extraction در scikit-learn، برای ایجاد ویژگی های صندوقچه ی کلمات استفاده می کنیم. در صورتی که scikit-learn را نصب نکرده اید. ابتدا باید به نصب آن بپردازید (برای دریافت فایل اینجا را کلیک کنید).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
print "Creating the bag of words...\n"
from sklearn.feature_extraction.text import CountVectorizer

# Initialize the "CountVectorizer" object, which is scikit-learn's
# bag of words tool.  
vectorizer = CountVectorizer(analyzer = "word",   \
                             tokenizer = None,    \
                             preprocessor = None, \
                             stop_words = None,   \
                             max_features = 5000)

# fit_transform() does two functions: First, it fits the model
# and learns the vocabulary; second, it transforms our training data
# into feature vectors. The input to fit_transform should be a list of
# strings.
train_data_features = vectorizer.fit_transform(clean_train_reviews)

# Numpy arrays are easy to work with, so convert the result to an
# array
train_data_features = train_data_features.toarray()

برای مشاهده ی ابعاد آرایه دو بعدی ایجاد شده از داده های آموزشی کد زیر را اجرا کنید:


1
2
>>> print train_data_features.shape
(25000, 5000)

این ماتریس یا آرایه دوبعدی دارای ۲۵۰۰۰ سطر و ۵۰۰۰ ویژگی است یعنی به ازای هر نظر، یک آرایه ۵۰۰ تایی از میزان تکرار کلمات گلچین شده (۵۰۰ کلمه پرتکرار) ایجاد کرده ایم. توجه داشته باشید که CountVectorizer با استفاده از تنظیمات پیش فرض خود به طور خودکار عمل پیش پردازش، تفکیک کلمات ( (tokenization و حذف ایست واژه ها (برای هر یک با جایگزینی None) را انجام می دهد. ما می توانیم از این متد پیش ساخته یا از تابع مخصوص خود استفاده کنیم. برای جزئیات بیشتر مستندات تابع را ببینید. با این حال در این آموزش ما از تابع خودمان استفاده کردیم تا نحوه ی اجرای این عملیات را مرحله به مرحله مشاهده کنیم و امکان سفارشی سازی آن برایمان فراهم باشد.

حال که با مدل صندوقچه ی کلمات آشنا شدید بیایید به بررسی فرهنگ لغت بپردازیم:


1
2
3
# Take a look at the words in the vocabulary
vocab = vectorizer.get_feature_names()
print vocab

اگر بخواهید حتی می توانید تعداد موجود از هر کلمه در فرهنگ لغت را چاپ کنید:


1
2
3
4
5
6
7
8
9
import numpy as np

# Sum up the counts of each vocabulary word
dist = np.sum(train_data_features, axis=)

# For each, print the vocabulary word and the number of times it
# appears in the training set
for tag, count in zip(vocab, dist):
    print count, tag

جنگل های تصادفی

تا اینجا به ازای هر نظر، یک بردار ویژگی عددی بر اساس مدل صندوقچه ی کلمات ایجاد کردیم. اگر به خاطر داشته باشید در مجموعه داده آموزشی ۲۵ هزارتایی ما، برچسب خوب یا بد هر نظر هم موجود است. بنابراین می توانیم از یکی از روشهای معمول دسته بندی استفاده کنیم و یک مدل اولیه برای پیش بینی دسته یا طبقه هر نظر (خوب یا بد) ایجاد کنیم که اینکار هم با کتابخانه معروف یادگیری ماشین پایتون یعنی scikit-learn   به راحتی انجام پذیر است. در اینجا ما قصد داریم از روش دسته بندی جنگل های تصادفی استفاده کنیم. در این روش، به ازای یک مجموعه داده آموزشی و برچسب های موجود، درختهای تصمیم گیری مختلفی (جنگلی از درختها) ساخته می شود و هنگام ورود یک داده جدید، هر درخت به صورت جداگانه تصمیم میگیرد که این داده به کدام دسته تعلق دارد و نهایتاً برد با دسته ایست که بیشترین آراء درختان را از آن خود کرده است. این الگوریتم تنظیمات مختلفی مانند زمان اجرا و تعداد درختان ایجاد شده و مانند آن دارد و یکی از بهترین روشهای دسته بندی در حوزه یادگیری ماشین است که البته این الگوریتم Random Forest در scikit-learn وجود دارد. در زیر، ما تعداد درختان را به طور پیش فرض بر روی مقدار مناسب، ۱۰۰ تنظیم می کنیم. درختان بیشتر ممکن است (شاید هم نباشد) عملکرد بهتری داشته باشند، اما مطمئناً زمان اجرای طولانی تری خواهند داشت. به همین ترتیب، درج ویژگی های بیشتر برای هر نظر نیز باعث طولانی تر شدن زمان اجرا می شود.


1
2
3
4
5
6
7
8
9
10
11
print "Training the random forest..."
from sklearn.ensemble import RandomForestClassifier

# Initialize a Random Forest classifier with 100 trees
forest = RandomForestClassifier(n_estimators = 100)

# Fit the forest to the training set, using the bag of words as
# features and the sentiment labels as the response variable
#
# This may take a few minutes to run
forest = forest.fit( train_data_features, train["sentiment"] )

تابع fit در این الگوریتم مشابه سایر الگوریتم های دسته بندی، دو پارامتر اصلی میگیرد : آرایه عددی حاوی ویژگی های داده و برچسب هر داده (دسته ای که به آن تعلق دارد) . بعد از ساخت یک جنگل تصادفی از داده های آموزشی،‌در مرحله بعد، کافیست از تابع transform آن استفاده کنیم تا مشخص شود به ازای یک داده ورودی، چه دسته بندی ای برای ما پیش بینی می شود.

آزمایش مدل ساخته شده و ارسال آن برای مسابقه

تنها کاری که باقی مانده، اجرای جنگل های تصادفی بر روی مجموعه آزمایشی و ایجاد یک فایل پاسخ (submission) است. اگر تا کنون اینکار را نکرده اید. هم اینک فایل testData.tsv را از اینجا دانلود نمایید. این فایل حاوی ۲۵۰۰۰ نظر و شناسه است. وظیفه ی ما پیش بینی برچسب احساسات این نظرات است.
توجه کنید زمانی که ما برای مجموعه ی آزمایشی از صندوقچه ی کلمات استفاده می کنیم، برخلاف داده های آموزشی که از fit_transform استفاده کردیم؛ در اینجا تنها transform را فراخوانی می کنیم. یادتان باشد که در یادگیری ماشین، از مجموعه ی آزمایشی برای ساخت مدل هیچگاه استفاده نکنید و تنها به داده های آموزشی بسنده کنید. در غیر اینصورت، شما برنامه را در معرض خطر بیش برازش (overfitting) قرار داده اید.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Read the test data
test = pd.read_csv("testData.tsv", header=, delimiter="\t", \
                   quoting=3 )

# Verify that there are 25,000 rows and 2 columns
print test.shape

# Create an empty list and append the clean reviews one by one
num_reviews = len(test["review"])
clean_test_reviews = []

print "Cleaning and parsing the test set movie reviews...\n"
for i in xrange(,num_reviews):
    if( (i+1) % 1000 == ):
        print "Review %d of %d\n" % (i+1, num_reviews)
    clean_review = review_to_words( test["review"][i] )
    clean_test_reviews.append( clean_review )

# Get a bag of words for the test set, and convert to a numpy array
test_data_features = vectorizer.transform(clean_test_reviews)
test_data_features = test_data_features.toarray()

# Use the random forest to make sentiment label predictions
result = forest.predict(test_data_features)

# Copy the results to a pandas dataframe with an "id" column and
# a "sentiment" column
output = pd.DataFrame( data={"id":test["id"], "sentiment":result} )

# Use pandas to write the comma-separated output file
output.to_csv( "Bag_of_Words_model.csv", index=False, quoting=3 )

حال شما برای ساخت اولین submission یا ارسال پاسخ خود در مسابقه پردازش متن کگل آماده اید. شما می توانید هر یک از تنظیمات و تعیین پارامترهایی را که در این مثال انجام دادیم، به دلخواه تغییر دهید مثلاً به روش دیگری نظرات را پاکسازی کنید، عدد متفاوتی را برای فرهنگ لغت مربوط به صندوقچه ی کلمات انتخاب کنید، ریشه یابی پورتر را اعمال کنید، الگوریتم دسته بندی ای غیر از جنگل تصادفی یا هر عملیات دیگری را امتحان کنید.

اکنون شما یک کار پردازش متن و یادگیری ماشین خلاصه و جمع و جوری را به کمک کتابخانه های آماده پایتون به راحتی انجام داده اید . با ما همراه باشید …..

پی نوشت :

برای سنجش احساس در حوزه متون فارسی می توانید از این مقالات هم استفاده کنید.

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

جای خالی در معادله زیر را با کی برد انگلیسی وارد کنید : * Time limit is exhausted. Please reload CAPTCHA.