📜  将多项式朴素贝叶斯应用于NLP问题

📅  最后修改于: 2021-04-17 03:41:10             🧑  作者: Mango

朴素贝叶斯分类器算法是一系列概率算法,基于贝叶斯定理和每对特征之间条件独立的“朴素”假设而应用。
贝叶斯定理计算概率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(正|总体上喜欢这部电影):

由于对于我们的分类器,我们必须找出哪个标签具有更大的概率,因此我们可以舍弃两个标签相同的除数,

P(总体喜欢电影|正面)* P(正面)与P(总体喜欢电影|负面)* P(负面)

但是有一个问题:“总体上喜欢这部电影”没有出现在我们的训练数据集中,因此概率为零。在这里,我们假设“天真”的条件是句子中的每个单词都独立于其他单词。这意味着现在我们来看单个单词。

我们可以这样写:

下一步只是应用贝叶斯定理:-

现在,这些单词实际上在我们的训练数据中出现了几次,我们可以计算出来!

计算概率:

首先,我们计算每个标签的先验概率:对于我们训练数据中的给定句子,其为正P(正)的概率为3/5。那么,P(负)是2/5。

然后,计算P(overall | positive)意味着计算单词“ overall”在正文本(1)中出现的次数除以正数(11)中的单词总数。因此,P(总体|正)= 1/17,P(喜欢/正)= 1/17,P(正/正)= 2/17,P(电影/正)= 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

现在我们将所有概率相乘,看看谁更大:

我们的分类器为“总体喜欢这部电影”赋予了肯定的标签。

下面是实现:

# 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