1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 朴素贝叶斯网络matlab实现_基于朴素贝叶斯的文本分类方法实战

朴素贝叶斯网络matlab实现_基于朴素贝叶斯的文本分类方法实战

时间:2020-01-25 16:21:24

相关推荐

朴素贝叶斯网络matlab实现_基于朴素贝叶斯的文本分类方法实战

基于朴素贝叶斯的文本分类方法

一、朴素贝叶斯原理的介绍

二、朴素贝叶斯分类器的代码实现

分类器有时会产生错误结果,这时可以要求分类器给出一个最优的类别猜测结果,同时会给出这个猜测的概率估计值。朴素贝叶斯分类是使用概率论进行分类的方法。所谓“朴素”,是因为整个形式化过程只做最原始、最简单的假设。

一、朴素贝叶斯原理的介绍

优点:在数据较少的情况下仍然有效,可以处理多类别问题。

缺点:对于输入数据的准备方式较为敏感。

适用数据类型:标称型数据。

1.贝叶斯决策理论

在学习朴素贝叶斯分类之前,我们先回顾一下贝叶斯决策理论和条件概率。贝叶斯决策理论的核心思想是选择最高概率对应的类别,也就是选择具有最高概率的决策。贝叶斯准则是计算条件概率的有效方法,可以告诉我们如何交换条件概率中的条件与结果,即如果已知P(x|C),要求P(C|x),那么就可以使用下面的计算方法:

2.使用条件概率分类

假设我们有一个二维数据集,由两类数据组成,现在我们结合贝叶斯决策理论使用条件概率来给这些数据点分类。即给定数据点(x,y),判断是属于类别1还是类别2的方法是,分别计算该数据点来自类别1和来自类别2的概率。所以真正需要比较的是P(C1|x,y)和P(C2|x,y)。若已知从给定类别中取出该数据的概率,即P(x,y|Ci) ,应用贝叶斯准则可以得到:

,那么属于类别1,

,则属于类别2。

以上是贝叶斯准则的简要理论,我们在对文档进行分的类常用算法朴素贝叶斯分类器中“朴素”一词基于两个假设:

a.特征之间相互独立,在上述二维数据中的体现就是x与y相互独立。

b.每个特征同等重要。即x与y有同样的重要性。

在应用于文档分类时,尽管很多情况下特征难以完全符合上述假设,但朴素贝叶斯的实际效果却很好。

下面我们将其付诸实践,使用Python构建基于这些理论的分类器。

二、朴素贝叶斯分类器的实现

在文档分类中,整个文档(如一封电子邮件)是实例,文档中的某些元素构成特征。我们把每个词的出现或不出现作为一个特征。整个文本分类的过程分为三步:

a.拆分文本,获取特征。在英文文档分类中,特征来自文本的词条(token),一个词条可以是单词,也可以是URL、IP地址等任意其他字符串。

b.将文本数字化,构建词向量。每一个文本片段表示为一个词条向量,其中值为1表示词条出现在文档中,0表示词条未出现。

c.计算条件概率并分类。应用朴素贝叶斯分类原理,通过词向量计算条件概率。这里w是一个向量,由多个数值组成,它代表着由多个单词组成的一段文本或者一组单词。

计算上面的概率值,然后比较大小。

下面是在线社区留言板的案例,我们要留言分为侮辱类和非侮辱类。如果留言中使用了负面或者侮辱性词语,那么该留言就识别为侮辱类留言,记为1,否则0。

1.准备数据,从文本中构建词向量

先将所有文档中出现过的词构建词汇表,然后把每篇文档中的词转换成词汇表上的向量。由于这里我们用的是将一个词出现与否作为特征的词集模型(对应的还有词袋模型),不计数每个词出现的次数,所以词向量中只需将出现在词汇表的词记为1即可。具体实现如下:

#准备数据:从文本中构建词向量

测试下:

postingList

得到词表:

print

得到第一个文档的词向量:

2.从词向量计算概率

上面我们已经探讨了,要得到类别概率值,首先要计算P(w|Ci)和P(Ci)。P(Ci)容易获得,用侮辱类文档数除以总文档数即可。接下来计算P(w|Ci)。朴素贝叶斯中假设特征相互独立,这里体现为每个词条相互独立。将P(w|Ci)展开成P(w0,w1,w2,...,wn|Ci),根据假设P(w0,w1,w2,...,wn|Ci)=P(w0|Ci)P(w1|Ci)P(w2|Ci)...P(wn|Ci)成立,我们可以以此计算上述概率。

伪代码如下:

计算每个类别文档数目

对每篇训练文档:

对每个类别:

如果词条出现在文档中,则增加该词的计数值

增加该类文档所有词的计数值

对每个类别:

将该词的计数值除以该类文档总词数得到条件概率

返回每个类别的条件概率

实战代码如下:

#trainMatrix已转换为向量的文档矩阵,trainCategory每篇文档类别标签所构成的向量

准备好概率向量和侮辱类文档概率后,按照贝叶斯准则公式将上述概率进行计算,得到朴素贝叶斯分类函数:

#朴素贝叶斯分类函数

在上述代码中,我们用Numpy数组来计算两个向量即vec2Classify和p1Vect、vec2Classify和p0Vect的相乘的结果,也就是包含待分类文档所有词条的条件概率向量p0VectClassify和p1VectClassify,这里的相乘是指对应元素的相乘,具体就是先将两个向量的第一个元素相乘,再将第二个元素相乘,以此类推。接下来要通过将条件概率向量中的各元素相乘P(w0|Ci)P(w1|Ci)P(w2|Ci)...P(wn|Ci)得到概率值P(w|Ci),如果其中一个概率值为0,那么最后的乘积也会是0。为避免这种影响,我们将p0VectClassify和p1VectClassify中的0元素去掉,得到新的列表p0Cond和p1Cond。若p0VectClassify或p1VectClassify全为0,对应的新列表为空,在应用reduce()函数时,会得到结果为1,显然不正确,所以这里我们用了if语句,将空列表的条件概率值pCi置为0。最后比较p0和p1的大小,也就是P(C0|w)和P(C1|w)的大小,得到分类结果。

——分割线——————————————————————————

感谢评论区提醒,用平滑处理方式比直接将条件概率计算时的0元素去掉更有效。这里我采用的方式是将所有词的出现数初始化为1,相当于所有词频加1,并将分母初始化为2。相应地在trainNB()函数中要修改

p0Num=zeros(numWords) #初始化概率p1Num=zeros(numWords) p0Denom=0p1Denom=0

为:

p0Num=ones(numWords) #初始化概率p1Num=ones(numWords) p0Denom=2p1Denom=2

另外为避免很多非常小的因子相乘会造成下溢出,即用Python计算很多非常小的数时会四舍五入得到0的问题,采用对上述乘积取自然对数的方法。相应地在trainNB()函数中要修改

#对p1Num的每个元素做除法,即侮辱性文档中出现每个词语的概率p1Vect=p1Num/p1Denom #对p0Num的每个元素做除法,即正常文档中出现每个词语的概率p0Vect=p0Num/p0Denom

为:

#对p1Num的每个元素做除法,即侮辱性文档中出现每个词语的概率p1Vect=log(p1Num/p1Denom) #change to log()#对p0Num的每个元素做除法,即正常文档中出现每个词语的概率p0Vect=log(p0Num/p0Denom) #change to log()

此处,分类函数中不需要再进行去掉0元素等操作,取了自然对数后计算条件概率也更加容易,重新改写分类函数为:

def classifyNB(vec2Classify,trainMatrix,trainCategory):p0Vect,p1Vect,pAb=trainNB(trainMatrix,trainCategory)p1=sum(vec2Classify*p1Vect)+log(pAb)p0=sum(vec2Classify*p0Vect)+log(1-pAb)if p1>p0:return 1else:return 0

3.测试运行结果

代入上面的数据

#加载数据

看看结果:

测试结果没有问题,和预期一致。上述代码简单实践了基于朴素贝叶斯理论的文档分类,下面我们对代码做些简单改进,使分类效果更好。

4.简单应用词袋模型

在上面的模型中,我们是将一个词出现与否作为特征,采用的是词集模型。如果一个词在文档中出现不止一次,可能包含比一个词出现与否更多的信息,这种方法称为词袋模型。词袋模型计数每个词出现的次数,而词集模型中词向量中只需将出现在词汇表的词记为1即可。因此,采用词袋模型,我们只需将setofWords2Vec()函数稍作改动即可。下面是基于词袋模型的朴素贝叶斯分类代码:

def

我们再次运行前面的测试用例,会得到与词集模型相同的结果:

这里,我们只是通过简单应用来介绍词袋模型。在更复杂的文档分类工作中,词袋模型会更好地表现出模型优越性。

本文通过实现简单的基于朴素贝叶斯的文档分类器,初步了解了贝叶斯决策理论和文档分类工作。在实际项目中,我们还会遇到很多实际问题。比如在实现朴素贝叶斯时会存在下溢出的问题,通常对概率取对数来解决。在文档分类中还有移除停用词等问题,在这里就不逐一解释实现了。

文章主要参考书目:机器学习实战。

若文中有错误疏漏之处,望请读者指正,谢谢!

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