機器學習-將多項式樸素貝葉斯應用於NLP問題

  • 2019 年 10 月 7 日
  • 筆記

樸素貝葉斯分類器演算法是一系列概率演算法,基於貝葉斯定理和每對特徵之間條件獨立的「樸素」假設而應用。 貝葉斯定理計算概率P(c | x),其中c是可能結果的類別,x是必須分類的給定實例,表示某些特定特徵。

P(c|x) = P(x|c) * P(c) / P(x)

樸素貝葉斯主要用於自然語言處理(NLP)問題。 樸素貝葉斯預測文本的標籤。 他們計算給定文本的每個標籤的概率,然後輸出最高標籤的標籤。

樸素貝葉斯演算法如何工作?

讓我們考慮一個示例,對評論進行正面或負面的分類。

TEXT

REVIEWS

「I liked the movie」

positive

「It』s a good movie. Nice story」

positive

「Nice songs. But sadly boring ending. 」

negative

「Hero』s acting is bad but heroine looks good. Overall nice movie」

positive

「Sad, boring movie」

negative

我們對「總體喜歡這部電影」的文字進行正面評價還是負面評價。 我們必須計算 P(正面|總體上喜歡這部電影) —假定句子「總體上喜歡這部電影」,則該句子的標籤為正的概率。 P(負|總體上喜歡這部電影) —假定句子「總體上喜歡這部電影」,則句子的標籤為負的概率。

在此之前,首先,我們在文本中應用「刪除停用詞並阻止」。

刪除停用詞:這些是常用詞,實際上並沒有真正添加任何內容,例如,有能力的,甚至其他的,等等。

詞根提取:詞根提取。

現在,在應用了這兩種技術之後,我們的文本變為

TEXT

REVIEWS

「ilikedthemovi」

positive

「itsagoodmovienicestori」

positive

「nicesongsbutsadlyboringend」

negative

「herosactingisbadbutheroinelooksgoodoverallnicemovi」

positive

「sadboringmovi」

negative

特徵工程: 重要的部分是從數據中找到特徵,以使機器學習演算法起作用。 在這種情況下,我們有文字。 我們需要將此文本轉換為可以進行計算的數字。 我們使用詞頻。 那就是將每個文檔視為包含的一組單詞。 我們的功能將是每個單詞的計數。

在本例中,通過使用以下定理,我們得到 P(positive | overall liked the movie)

P(positive | overall liked the movie) = P(overall liked the movie | positive) * P(positive) / P(overall liked the movie)

由於對於我們的分類器,我們必須找出哪個標籤具有更大的概率,因此我們可以捨棄兩個標籤相同的除數,

P(overall liked the movie | positive)* P(positive) with P(overall liked the movie | negative) * P(negative)

但是存在一個問題:「總體上喜歡這部電影」沒有出現在我們的訓練數據集中,因此概率為零。 在這裡,我們假設「樸素」的條件是句子中的每個單詞都獨立於其他單詞。 這意味著現在我們來看單個單詞。

我們可以這樣寫:

P(overall liked the movie) = P(overall) * P(liked) * P(the) * P(movie)

下一步就是應用貝葉斯定理:

P(overall liked the movie| positive) = P(overall | positive) * P(liked | positive) * P(the | positive) * P(movie | positive)

現在,這些單詞實際上在我們的訓練數據中出現了幾次,我們可以計算出來!

計算概率:

首先,我們計算每個標籤的先驗概率:對於我們訓練數據中的給定句子,其為正P(positive)的概率為3/5。 那麼,P(negative)是2/5。

然後,計算P(overall | positive)意味著計算單詞「 overall」在肯定文本(1)中出現的次數除以肯定(11)中的單詞總數。 因此,P(overall | positive) = 1/17, P(liked/positive) = 1/17,P(the/positive)= 2/17,P(movie/positive)= 3/17。

如果概率為零,則使用拉普拉斯平滑法:我們向每個計數加1,因此它永遠不會為零。 為了平衡這一點,我們將可能單詞的數量添加到除數中,因此除法永遠不會大於1。在我們的情況下,可能單詞的總數為21。

應用平滑,結果為:

WORD

P(WORD | POSITIVE)

P(WORD | NEGATIVE)

overall

1 + 1/17 + 21

0 + 1/7 + 21

liked

1 + 1/17 + 21

0 + 1/7 + 21

the

2 + 1/17 + 21

0 + 1/7 + 21

movie

3 + 1/17 + 21

1 + 1/7 + 21

現在我們將所有概率相乘,看看誰更大:

P(overall | positive) * P(liked | positive) * P(the | positive) * P(movie | positive) * P(postive ) = 1.38 * 10^{-5} = 0.0000138

P(overall | negative) * P(liked | negative) * P(the | negative) * P(movie | negative) * P(negative) = 0.13 * 10^{-5} = 0.0000013

我們的分類器為「總體喜歡這部電影」賦予了肯定的標籤。

下面是實現:

#導入包 這裡用到了NLTK

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)

# 創建單詞模型庫

cv = CountVectorizer(max_features = 1500)

X = cv.fit_transform(corpus).toarray()

y = dataset.iloc[:, 1].values

# 分隔數據設置訓練數據和測試數據

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)

# 使用樸素貝葉斯高斯分布訓練數據

from sklearn.naive_bayes import GaussianNB

from sklearn.metrics import confusion_matrix

classifier = GaussianNB();

classifier.fit(X_train, y_train)

# 預測測試結果

y_pred = classifier.predict(X_test)

# 製作混亂矩陣

cm = confusion_matrix(y_test, y_pred)

cm