بیز ساده چند جمله ای (MNB) یک الگوریتم محبوب یادگیری ماشین برای حل مسائل طبقهبندی متن در پردازش زبان طبیعی (NLP) است. این الگوریتم برای مسائلی که شامل دادههای متنی با ویژگیهای گسسته مانند تعداد دفعات کلمات هستند، بسیار مفید است. MNB بر اساس اصل قضیه بیز کار میکند و فرض میکند که ویژگیها در صورت داشتن متغیر کلاس، به صورت شرطی مستقل از یکدیگر هستند.
مراحل کاربرد بیز ساده چند جمله ای در مسائل پردازش زبان طبیعی
پیشپردازش دادههای متنی
دادههای متنی باید قبل از اعمال الگوریتم پیشپردازش شوند. این شامل گامهایی چون توکنسازی، حذف کلمات توقف، استمینگ و لماتیزاسیون میباشد.
استخراج ویژگی
دادههای متنی باید به یک فرمت بردار ویژگی تبدیل شوند که بتواند به عنوان ورودی برای الگوریتم MNB مورد استفاده قرار گیرد. رایجترین روش استخراج ویژگی، استفاده از مدل کولهی کلمات (bag-of-words) است، جایی که هر سند توسط یک بردار از تعداد دفعات کلمات نمایندگی میکند.
تقسیم دادهها
دادهها باید به دو بخش آموزشی و آزمایشی تقسیم شوند. مجموعه دادههای آموزشی برای آموزش مدل MNB و مجموعه دادههای آزمایشی برای ارزیابی عملکرد آن استفاده میشود.
آموزش مدل MNB
مدل MNB با تخمین احتمالات هر ویژگی داده شده برای هر کلاس روی مجموعه دادههای آموزشی آموزش داده میشود. این امر شامل محاسبه احتمالات قبلی هر کلاس و احتمال ویژگیها داده شده برای هر کلاس است.
ارزیابی عملکرد مدل
عملکرد مدل با استفاده از معیارهایی مانند دقت (accuracy)، صحت (precision)، بازخوانی و امتیاز F1 روی مجموعه دادههای آزمایشی ارزیابی میشود.
استفاده از مدل برای انجام پیشبینیها
پس از آموزش مدل، میتوان از آن برای انجام پیشبینیها روی دادههای متنی جدید استفاده کرد. دادههای متنی پیشپردازش و به فرمت بردار ویژگی تبدیل میشوند، که سپس به مدل آموزشدیده وارد شده و برچسب کلاس پیشبینیشده به دست میآید.
بیز ساده چند جمله ای (MNB) یک الگوریتم ساده و کارآمد است که برای بسیاری از مسائل پردازش زبان طبیعی مانند تحلیل احساسات، تشخیص اسپم و طبقهبندی موضوعات به خوبی کار میکند. با این حال، محدودیتهایی دارد، مانند فرض استقلال بین ویژگیها، که ممکن است در برخی موارد صادق نباشد. بنابراین، ارزیابی دقیق عملکرد مدل قبل از استفاده در یک برنامه کاربردی واقعی مهم است.
الگوریتم طبقهبندی بیز ساده یک خانواده از الگوریتمهای احتمالاتی است که بر اساس به کارگیری قضیه بیز با فرض “ساده”ی استقلال شرطی بین هر جفت ویژگی استفاده میشود.
قضیه بیز احتمال P(c|x) را محاسبه میکند که در آن c کلاس نتایج احتمالی و x نمونهای داده شده است که باید طبقهبندی شود و برخی ویژگیهای خاص را نشان میدهد.
P(c|x) = P(x|c) * P(c) / P(x)
بیز ساده بیشتر در مسائل پردازش زبان طبیعی (NLP) استفاده میشود. بیز ساده برچسب یک متن را پیشبینی میکنند. آنها احتمال هر برچسب را برای یک متن داده شده محاسبه میکنند و سپس برچسب با بالاترین احتمال را خروجی میدهند.
الگوریتم بیز ساده چگونه کار می کند؟
بیایید با در نظر گرفتن یک مثال، بررسی کنیم که آیا نقد و بررسی مثبت است یا منفی.
مجموعه دادههای آموزشی:
Reviews |
Text |
منفی |
در کل از فیلم خوشم آمد |
مثبت |
فیلم خوبی است. داستان خوبی دارد |
منفی |
آهنگهای خوبی دارد. اما متاسفانه پایان خستهکنندهای دارد. |
مثبت |
بازی قهرمان فیلم بد است اما قهرمانه ظاهر خوبی دارد. در کل فیلم خوبی است |
منفی |
فیلم غمانگیز و خستهکننده |
ما طبقهبندی میکنیم که آیا متن “در کل از فیلم خوشم آمد” نقد و بررسی مثبتی دارد یا منفی. ما باید محاسبه کنیم،
P(مثبت | در کل از فیلم خوشم آمد) — احتمال اینکه برچسب یک جمله مثبت باشد با توجه به اینکه جمله “در کل از فیلم خوشم آمد” است.
P(منفی | در کل از فیلم خوشم آمد) — احتمال اینکه برچسب یک جمله منفی باشد با توجه به اینکه جمله “در کل از فیلم خوشم آمد” است.
قبل از آن، ابتدا باید حذف کلمات بیمعنی و استخراج ریشه کلمات (Removing Stopwords and Stemming) را روی متن اعمال کنیم.
حذف کلمات بیمعنی: کلمات رایجی هستند که واقعاً چیزی به طبقهبندی اضافه نمیکنند، مانند able (توانا), either (یکی از دو), else (دیگر), ever (همیشه) و غیره.
استخراج ریشه: استخراج ریشه به معنای گرفتن ریشه کلمه است.
بعد از اجرای این دو تکنیک، متن بهصورت زیر درمیآید:
Reviews |
Text |
منفی |
درکلازفیلمخوشمآمد |
مثبت |
فیلمخوبیاستداستانخوبیدارد |
منفی |
آهنگهایخوبیداردامامتاسفانهپایانخستهکنندهایدارد |
مثبت |
بازیقهرمانفیلمبداستاماقهرمانهظاهرخوبیدارددرکلفیلمخوبیاست |
منفی |
فیلمغمانگیزوخستهکننده |
مهندسی ویژگیها
بخش مهم، یافتن ویژگیهایی از دادهها است تا الگوریتم های یادگیری ماشین کار کنند. در این مورد، ما با متن سر و کار داریم. نیاز داریم این متن را به اعدادی تبدیل کنیم که بتوانیم محاسبات انجام دهیم. ما از فراوانی کلمات استفاده میکنیم. یعنی هر سند را به عنوان مجموعهای از کلماتی که دربردارد، در نظر میگیریم. ویژگیهای ما تعداد شمارش هر یک از این کلمات خواهد بود.
در مورد پیشرو، ما P(مثبت | در کل از فیلم خوشم آمد) داریم، با استفاده از این قضیه:
P(مثبت | در کل از فیلم خوشم آمد) = P(در کل از فیلم خوشم آمد | مثبت) * P(مثبت) / P(در کل از فیلم خوشم آمد)
از آنجایی که برای طبقهبندی، باید پیدا کنیم که کدام برچسب احتمال بیشتری دارد، میتوانیم مقسومعلیه را که برای هر دو برچسب یکسان است نادیده بگیریم،
P(در کل از فیلم خوشم آمد | مثبت) * P(مثبت) با P(در کل از فیلم خوشم آمد | منفی) * P(منفی)
با این حال یک مشکل وجود دارد: “در کل از فیلم خوشم آمد” در مجموعه دادههای آموزشی ما ظاهر نمیشود، بنابراین احتمال آن صفر است. در اینجا، ما شرط ‘سادهگرایانه’ را فرض میکنیم که هر کلمه در یک جمله مستقل از سایر کلمات است. این بدان معنی است که اکنون ما به کلمات فردی نگاه میکنیم.
میتوانیم این را به صورت زیر بنویسیم:
P(در کل از فیلم خوشم آمد) = P(در کل) * P(خوشم آمد) * P(فیلم)
مرحله بعدی فقط اعمال قضیه بیز است:
P(در کل از فیلم خوشم آمد | مثبت) = P(در کل | مثبت) * P(خوشم آمد | مثبت) * P(فیلم | مثبت)
و حالا، این کلمات فردی واقعاً چندین بار در دادههای آموزشی ما ظاهر میشوند و ما میتوانیم آنها را محاسبه کنیم!
محاسبه احتمالات
اول، ما احتمال قبلی هر برچسب را محاسبه میکنیم: برای یک جمله داده شده در دادههای آموزشی، احتمال اینکه مثبت باشد P(مثبت) برابر با 3/5 است. سپس، P(منفی) برابر با 2/5 است.
سپس، محاسبه P(در کل | مثبت) به معنای شمارش تعداد دفعاتی است که کلمه “در کل” در متنهای مثبت ظاهر میشود (1) تقسیم بر تعداد کل کلمات در مثبت (17). بنابراین:
P(در کل | مثبت) = 1/17،
P(خوشم آمد/مثبت) = 1/17،
P(فیلم/مثبت) = 3/17.
اگر احتمال به صفر برسد پس با استفاده از فیلتر لاپلاس ما 1 را به هر شمارش اضافه میکنیم تا هرگز صفر نشود. برای تعادل، تعداد کلمات ممکن را به مقسوم علیه اضافه میکنیم، بنابراین تقسیم هرگز بیشتر از 1 نخواهد بود. در مورد ما، تعداد کل کلمات ممکن 21 است.
پس از اعمال فیلتر نتایج بهصورت زیر است:
کلمه |
P(کلمه | مثبت) |
P(کلمه | منفی) |
درکل |
1 + 1/17 + 21 |
0 + 1/7 + 21 |
خوشمآمد |
1 + 1/17 + 21 |
0 + 1/7 + 21 |
the |
2 + 1/17 + 21 |
0 + 1/7 + 21 |
فیلم |
3 + 1/17 + 21 |
1 + 1/7 + 21 |
اکنون ما تمام احتمالات را در هم ضرب میکنیم و میبینیم کدام یک بزرگتر است:
P(در کل | مثبت) * P(خوشم آمد | مثبت) * P(فیلم | مثبت) * P(مثبت) = 1.38 * 10^{-5} = 0.0000138
P(در کل | منفی) * P(خوشم آمد | منفی) * P(فیلم | منفی) * P(منفی) = 0.13 * 10^{-5} = 0.0000013
طبقهبندیکننده ما به “در کل از فیلم خوشم آمد” برچسب مثبت میدهد.
در زیر پیادهسازی آن آمده است.
# cleaning texts import pandas as pd import re import nltk from nltk.corpus import stopwords from nltk.stem.porter import PorterStemmer from sklearn.feature_extraction.text import CountVectorizer dataset = [["I liked the movie", "positive"], ["It’s a good movie. Nice story", "positive"], ["Hero’s acting is bad but heroine looks good.\ Overall nice movie", "positive"], ["Nice songs. But sadly boring ending.", "negative"], ["sad movie, boring movie", "negative"]] dataset = pd.DataFrame(dataset) dataset.columns = ["Text", "Reviews"] nltk.download('stopwords') corpus = [] for i in range(0, 5): text = re.sub('[^a-zA-Z]', '', dataset['Text'][i]) text = text.lower() text = text.split() ps = PorterStemmer() text = ''.join(text) corpus.append(text) # creating bag of words model cv = CountVectorizer(max_features = 1500) X = cv.fit_transform(corpus).toarray() y = dataset.iloc[:, 1].values
# splitting the data set into training set and test set from sklearn.cross_validation import train_test_split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = 0.25, random_state = 0)
# fitting naive bayes to the training set from sklearn.naive_bayes import GaussianNB from sklearn.metrics import confusion_matrix classifier = GaussianNB(); classifier.fit(X_train, y_train) # predicting test set results y_pred = classifier.predict(X_test) # making the confusion matrix cm = confusion_matrix(y_test, y_pred) cm