300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 机器学习:伯努利朴素贝叶斯分类器(原理+python实现)

机器学习:伯努利朴素贝叶斯分类器(原理+python实现)

时间:2020-10-13 19:51:23

相关推荐

机器学习:伯努利朴素贝叶斯分类器(原理+python实现)

伯努利朴素贝叶斯分类器主要用于文本分类,下面我们以一个具体的例子,来讲述下伯努利朴素贝叶斯的原理和实现逻辑。

具体例子:

已知我们有八个句子以及每个句子对应的类别,即中性或侮辱性。那么再给出一个句子,我们来判断该句子是中性还是侮辱性,即计算该句子是中性的概率大还是侮辱性的概率大,概率大的类别即为我们判断的类别。

首先要把句子进行处理,即把句子分解成拥有多个单词的单词组,句子对应的单词组以及类别如下所示:

def loadDataSet():postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]classVec = [0, 1, 0, 1, 0, 1] # 类别0为中性,1为带有侮辱性质return postingList, classVec

那么在给出一个单词组的情况下,根据贝叶斯决策理论,计算出该单词组属于类别0和类别1的概率,其计算公式如下:

p(类别 i│单词组)=(p(单词组│类别 i )×p(类别i))/(p(单词组))

其中, i=0或1

p(类别i)该如何计算?

对于训练集内的八个单词组,当类别为i时所对应的单词组数占这八个单词组的比例即为p(类别i)

p(单词组│类别 i )该如何计算?

p(单词组│类别 i )=p(单词1│类别 i )×p(单词2│类别 i )×…p(单词n│类别 i )

可以看出,对于一个单词组而言,其p(单词组│类别 i )是由在该类别下的各个单词的条件概率相乘而来,这意味着在计算p(单词组│类别 i )时,认为单词组内所有单词都是彼此独立的特征,该假设叫做条件独立性假设,这也是朴素贝叶斯的决策原理。

那么对于p(单词j│类别 i ),它该如何计算呢?具体如下:

p(单词j│类别 i )=(符合类别 i的训练集内单词j的数目)/(符合类别 i的训练集内所有单词的数目)

根据例子的描述可以知道,训练集指的是这八个单词组,符合类别i的训练集指的是,在这八个单词组中,只有对应类别是i的单词组,才算是符合类别i的训练集。那么单词的数目是什么呢?首先我们来了解下单词表的概念。对于训练集的单词组,我们可以以此来构建一个单词表,那么对于单词j而言,只要在一个单词组出现过,那么在单词j的数目上就增加一次,而训练集内有八个单词组,所以单词j出现的次数最多为8次。从这里可以看出,单词j即使是在同一个单词组内出现多次,也依然会记作1次,这就是伯努利模型。

在伯努利模型中,假设所有单词的权重是一样的,所以即使两个单词在同一词组出现的次数不同,伯努利模型会认为这两个单词的重要程度是一样的。

那么什么是训练集内所有单词的数目呢?这就是说,在计算出各个词组内都有多少个单词出现在了单词表中,其数目的累加和。

根据上面的描述,我们可以先构建一个单词表,其单词表涵盖了这八个单词组内所出现的所有单词。

# 根据句子构建单词表def createVocabList(dataSet):vocabSet = set([]) # 因为document也是[]结构for document in dataSet:vocabSet = vocabSet | set(document) # 集合的并集return list(vocabSet) # 将集合格式变为list格式

接下来,根据单词表,将所有的单词组都转换成一个词向量,这样的转换方式使得每个长度不一的单词组都转换成了长度一样的数字向量,与此同时,词向量可以可以很清晰地显示出每个词组都出现哪些单词,需要注意的是,这里是应用了伯努利模型,所以单词在同一词组内无论出现多少次都记作1,没出现记作0。

# 将单词组转换成数字组def setOfWords2Vec(vocabList, inputSet):returnVec = [0] * len(vocabList) # 构建指定长度的列表for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] = 1else:print"the word: %s is not in my Vocabulary!" % wordreturn returnVec

那么现在按照p(单词j│类别 i )的计算方式,可以计算出训练集内的八个单词组各个单词在不同类别下的条件概率,以及p(类别i),其实现方式如下:

# 输入词向量矩阵和类别标签def trainNB0(trainMatrix, trainCategory):numTrainDocs = len(trainMatrix) # 训练集单词组数numWords = len(trainMatrix[0]) # pAbusive = sum(trainCategory) / float(numTrainDocs) # p(类别1)p0Num = ones(numWords); #初始化为1p1Num = ones(numWords) #初始化为1p0Denom = 2.0; # 初始化为2p1Denom = 2.0 # 初始化为2for i in range(numTrainDocs): # 对于每一个词向量而言if trainCategory[i] == 1:p1Num += trainMatrix[i] # 记录类别为1时每个词的出现次数p1Denom += sum(trainMatrix[i]) # 记录类别为1时单词出现总数else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = log(p1Num / p1Denom) # 进行log处理p0Vect = log(p0Num / p0Denom) # 进行log处理return p0Vect, p1Vect, pAbusive

那么在这里,我们要考虑一个现实问题,那就是

p(单词1│类别 i )×p(单词2│类别 i )×…p(单词n│类别 i )

如果说有一个因子为0,那么p(单词组│类别 i )就为0,所以我们可以将词向量作下修改,即不出现单词的记作1,出现单词的记作2,这样就避免了 p(单词j│类别 i )可能为0的情况。但与此同时,若p(单词j│类别 i )都很小时,乘积出来依然为0,为了避免这个问题,我们将p(单词j│类别 i )修改为ln(p(单词j│类别 i )),通过取对数,来化解概率较小的问题。根据上面这两个修改,我们计算两个类别下的概率。

# 输入要预测的词向量和p0Vect, p1Vect, pAbusivedef classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1) # element-wise multp0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else:return 0

根据构建好的贝叶斯决策,进行预测[‘love’, ‘my’, ‘dalmation’] 和[‘stupid’, ‘garbage’]这两个词组的类别

def testingNB():listOPosts, listClasses = loadDataSet()myVocabList = createVocabList(listOPosts)trainMat = []for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0V, p1V, pAb = trainNB0(np.array(trainMat), np.array(listClasses))testEntry = ['love', 'my', 'dalmation']thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))testEntry = ['stupid', 'garbage']thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))testingNB()

其预测的类别为

总结:本文在讲述伯努利朴素贝叶斯分类器原理的同时,也引入了文本处理的方法,主要是将长短不一的单词词组经过指定的单词表转换成了词向量,由此可以通过贝叶斯准则计算出各个类别的概率,决策出类别。但在整个过程中,伯努利朴素贝叶斯假设单词组内各个单词的特征是相互独立的,且每个单词的作用程度地位是一样的,因此也存在一定的局限性。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。