您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > Python贝叶斯文本分类模型从原理到实现
Python贝叶斯文本分类模型从原理到实现朴素贝叶斯分类器是一种有监督学习,常见有两种模型,多项式模型(multinomialmodel)即为词频型和伯努利模型(Bernoullimodel)即文档型。二者的计算粒度不一样,多项式模型以单词为粒度,伯努利模型以文件为粒度,因此二者的先验概率和类条件概率的计算方法都不同。计算后验概率时,对于一个文档d,多项式模型中,只有在d中出现过的单词,才会参与后验概率计算,伯努利模型中,没有在d中出现,但是在全局单词表中出现的单词,也会参与计算,不过是作为“反方”参与的(避免消除测试文档时类条件概率中有为0现象而做的取对数等问题)。一、数据集数据集是有8个分类的文本数据集,使用了结巴分词对每个文本分词,每个单词当作特征,再利用二元词串构造更多特征,然后去掉停用词,去掉出现次数太多和太少的特征,得到了19630个特征。取1998个样本用于训练,509个用于测试。基于词袋模型的思路将每个文本转换为向量,训练集和测试集分别转换为矩阵,并用pythonnumpy模块将其保存为npy格式。数据集共使用了19630个单词作为特征,特征值是词在文本中出现的次数。8个分类,分别是1、2、...、8。训练集共1998个样本,测试集共509个样本。二、朴素贝叶斯分类器划分邮件算法朴素贝叶斯分类器,基于贝叶斯定理,是一个表现良好的分类方法。1、公式原理推导主要根据事件间的相互影响进行公式推断。1.1、条件概率:P(A|B)=P(A,B)/P(B)A和B是随机事件,P(A|B)也就是在事件B发生的前提下事件A发生的概率。P(A,B)表示A、B都发生的概率。这样一来,我们可以通过统计结果计算条件概率。例如假设有1000封邮件,垃圾邮件有300封,出现单词购买的邮件为50封,而即是垃圾邮件又同时出现了购买这个单词的邮件共有20封。如果把垃圾邮件看成事件A,邮件里出现单词购买看成事件B,那么P(A)是指垃圾邮件出现的概率,因为没考虑其他的因素对A的影响,也可以将P(A)看做A的先验概率,这里:P(A)=300/1000=0.3同理,P(B)=50/1000=0.05P(A,B)是指A和B同时发生的概率,P(A,B)=20/1000=0.02根据条件概率的公式,能够得到P(A|B)=0.02/0.05=0.4因为有B的影响,P(A|B)也叫做A的后验概率。1.2、相互独立事件如果事件A和B是相互独立的,代表着A发生的可能性对B发生的可能性没有影响,B也对A没有影响,在这种情况下:P(A,B)=P(A)*P(B)。既然A和B之间没有相互影响,那么:P(A|B)=P(A,B)/P(B)=P(A)P(B|A)=P(A,B)/P(A)=P(B)1.3、贝叶斯定理由P(A|B)=P(A,B)/P(B)很容易推出:P(A|B)=P(B|A)*P(A)/P(B)这也就是贝叶斯公式了。1.4、朴素贝叶斯分类器(naiveBayesclassifier)首先有以下定理:如果B、C相互独立,那么P(B|C,A)=P(B|A)。设有事件A、B1、B2,那么在B1、B2同时发生的前提下,A发生的概率是:P(A|B1,B2)=P(B1,B2|A)*P(A)/P(B1,B2)如果B1和B2相互独立,那么有P(B1,B2|A)=P(B1|B2,A)*P(B2|A)=P(B1|A)*P(B2|A)于是,P(A|B1,B2)=P(B1,B2|A)*P(A)/P(B1,B2)=P(B1|A)*P(B2|A)*P(A)/P(B1,B2)根据实际需求,假设某个体有n项特征(可以看着邮件中出现的词语),分别为F1、F2、…、Fn。现有m个类别(可以看着邮件的分类),分别为C1、C2、…、Cm。贝叶斯分类器就是计算出概率最大的那个分类,也就是求下面这个算式的最大值(即算出每个分类的概率,以最大概率为最终分类):P(C|F1,F2,...,Fn)=P(F1,F2,...,Fn|C)*P(C)/P(F1,F2,...,Fn)由于P(F1,F2,...,Fn)对于所有的类别都是相同的,可以省略,问题就变成了求P(F1,F2,...,Fn|C)*P(C)的最大值。朴素贝叶斯分类器则是更进一步,假设所有特征都彼此独立,因此P(F1,F2,...,Fn|C)*P(C)=P(F1|C)*P(F2|C)*...*P(Fn|C)*P(C)朴素贝叶斯分类器假设所有特征都彼此独立存在一定的不合理性,不过该分类器一般能取得很好的分类效果。2、判断邮件是否为垃圾邮件假定我们现在有1000封被标识的邮件作为训练集,训练集一般是人工标识,分为“垃圾邮件”、“正常邮件”。注意,训练集不宜人为地从大量邮件中有意挑拣,而应随机挑拣。然后我们从邮件中选取特征,例如我们把单词“购买”是否出现在邮件中看作是该邮件的一个特征,训练时候应该记录含有单词“购买”的垃圾邮件有多少封,含有单词“购买”的正常邮件有多少封,按照这个思路,我们得到以下表格:特征词统计正常邮件垃圾邮件汇总“购买”105060“淘宝”85664“开心”60363“编程”201535汇总98124222好了,现在有一封邮件需要分类,假设它有购买、淘宝、开心、编程四个特征,那么其属于正常邮件的可能性是:10/98*8/98*60/98*20/98*98/222=0.000459属于垃圾邮件的可能性是:50/124*56/124*3/124*15/124*124/222=0.00029768结果是该邮件更有可能是正常邮件。如果邮件只有有开心和编程两个特征,那么其属于正常邮件的可能性是:60/98*20/98*98/222=0.0551571属于垃圾邮件的可能性是:3/124*15/124*124/222=0.0016346992153443768结果是该邮件更有可能是正常邮件。3、让分类器更合理如果我们的统计结果是这样的:特征词统计正常邮件垃圾邮件汇总(求和)“购买”105060“淘宝”85664“开心”63063“编程”201535汇总(求和)101121222具有特征开心的垃圾邮件有0封。如果某封邮件具有购买、淘宝、开心这三个特征,按照上面的思路,该邮件属于正常邮件的可能性是:10/101*8/101*63/101*101/222=0.00222553属于垃圾邮件的可能性是:50/121*56/121*0/121*121/222=0这意味着,只要邮件里有“开心”,那么它就不是垃圾邮件(属于垃圾邮件的可能性为0),这显然是不合理的。对此,我们可以对P(F1|C)(以及P(F2|C)、P(F3|C)等)做如下处理(加权平均):P2(F1|C)=(1*0.5+sum(F1)*P(F1|C))/(1+sum(F1))=(0.5+sum(F1)*P(F1|C))/(1+sum(F1))其中,若F1是开心,那么sum(F1)=63+0=63。于是,属于正常邮件的可能性是:((0.5+10/101*60)/61)*((0.5+8/101*64)/65)*((0.5+63/101*63)/64)*101/222=0.0025593104680632236属于垃圾邮件的可能性是:((0.5+50/121*60)/61)*((0.5+56/121*64)/65)*((0.5+0/121*63)/64)*121/222=0.0008181611103439531这封邮件还是倾向于正常邮件,不过计算方式更合理了。另外我们也可以通过取对数的方式进行优化。这样更合理,因为对数的相乘可以变成相加。4、如何由计算结果判断类别如果计算出一封邮件属于正常邮件的概率是0.05,属于垃圾邮件的概率是0.006,基本可以肯定这是一封正常邮件。不过,如果一封邮件属于正常邮件的概率是0.05,属于垃圾邮件的概率是0.049,那么这封邮件是否该划分为垃圾邮件?也许在这个时候就要在训练之后再填上一个分类了——不确定分类。首先,设定一个阈值T(大于1),待标注数据D,两个分类C0和C1,如果:P(C0|D)/P(C1|D)T那么,D属于类别C0。如果:P(C1|D)/P(C0|D)T那么,D属于类别C1。5、如果有多个类别对于朴素贝叶斯分类器而言,多个分类和二分类没什么差别,就是训练的时候多加个分类而已。三、贝叶斯模型实现朴素贝叶斯的三个常用模型:高斯、多项式、伯努利朴素贝叶斯的基本若一个样本有n个特征,分别用x1,x2,…,xn表示,将其划分到类yk的可能性P(yk|x1,x2,…,xn)为:P(yk|x1,x2,…,xn)=P(x1|yk)*P(x2|yk)…*P(xn|yk)*P(yk)上式中等号右侧的各个值可以通过训练得到。根据上面的公式可以求的某个数据属于各个分类的可能性(这些可能性之和不一定是1),该数据应该属于具有最大可能性的分类中。一般来说,如果一个样本没有特征xi,那么P(xi|yk)将不参与计算。不过下面的伯努利模型除外。高斯模型有些特征可能是连续型变量,比如说人的身高,物体的长度,这些特征可以转换成离散型的值,比如如果身高在160cm以下,特征值为1;在160cm和170cm之间,特征值为2;在170cm之上,特征值为3。也可以这样转换,将身高转换为3个特征,分别是f1、f2、f3,如果身高是160cm以下,这三个特征的值分别是1、0、0,若身高在170cm之上,这三个特征的值分别是0、0、1。不过这些方式都不够细腻,高斯模型可以解决这个问题。高斯模型假设这些一个特征的所有属于某个类别的观测值符合高斯分布(正态分布),也就是:下面看一个sklearn中的示例:(需要安装sklearn包)fromsklearnimportdatasetsiris=datasets.load_iris()iris.feature_names#四个特征的名字['sepallength(cm)','sepalwidth(cm)','petallength(cm)','petalwidth(cm)']iris.dataarray([[5.1,3.5,1.4,0.2],[4.9,3.,1.4,0.2],[4.7,3.2,1.3,0.2],[4.6,3.1,1.5,0.2],[5.,3.6,1.4,0.2],[5.4,3.9,1.7,0.4],[4.6,3.4,1.4,0.3],[5.,3.4,1.5,0.2],......[6.5,3.,5.2,2.],[6.2,3.4,5.4,2.3],[5.9,3.,5.1,1.8]])#类型是numpy.arrayiris.data.size600#共600/4=150个样本iris.target_namesarray(['setosa','versicolor','virginica'],dtype='|S10')iris.targetarray([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,.....,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,......,2,2,2,2,2,2,2,2,2,2,2,2])iris.target.size150fromsklearn.naive_bayesimportGaussianNBclf=GaussianNB()clf.fit(iris.data,iris.target)clf.predict(iris.data[0])array([0])#预测正确clf.predict(iris.data[149])array([2])#预测正确data=numpy.array([6,4,6,2])clf.predict(data)array([2])#预测结果很合理伯努利模型伯努利模型中,对于一个样本来说,其特征用的是全局的特征。1)基本原理P(c)=类c下文件总数/整个训练样本的文件总数P(tk|c)=(类c下包含单词tk的文件数+1)/(类c下单词总数+2)2)举例使用前
本文标题:Python贝叶斯文本分类模型从原理到实现
链接地址:https://www.777doc.com/doc-1993660 .html