深入理解朴素贝叶斯(Naive Bayes)

https://blog.csdn.net/li8zi8fa/article/details/76176597

朴素贝叶斯是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法。朴素贝叶斯原理简单,也很容易实现,多用于文本分类,比如垃圾邮件过滤。该算法虽然简单,但是由于笔者不常用,总是看过即忘,这是写这篇博文的初衷。当然,更大的动力来在于跟大家交流,有论述不妥的地方欢迎指正。

1.算法思想——基于概率的预测

逻辑回归通过拟合曲线(或者学习超平面)实现分类,决策树通过寻找最佳划分特征进而学习样本路径实现分类,支持向量机通过寻找分类超平面进而最大化类别间隔实现分类。相比之下,朴素贝叶斯独辟蹊径,通过考虑特征概率来预测分类。举个可能不太恰当的例子:眼前有100个人,好人和坏人个数差不多,现在要用他们来训练一个“坏蛋识别器”。怎么办呢?咱们不管他们干过啥事,只看他们长啥样(这确实不是个恰当的例子)。也就是说,我们在区分好坏人时,只考虑他们的样貌特征。比如说“笑”这个特征,它的取值可能是“甜美的笑”、“儒雅的笑”、“憨厚的笑”、“没心没肺的笑”、“微微一笑”,等等——这都是“好人的笑”;也可以是“阴险的笑”、“不屑的笑”、“色眯眯的笑”、“任我行似的笑”、“冷笑”、“皮笑肉不笑”,等等——这很可能是“坏人的笑”。单就“笑”这个特征来说,一个好人发出“好人的笑”的概率更大,而且频率更高;而坏人则发出“坏人的笑”的概率更大,频率更高(电视上总能看见作奸犯科的人在暗地里发出挨千刀的笑)。当然,好人也有发出坏笑的时候(那种偶像剧里面男猪脚“坏坏的笑”),坏人也有发出好人的笑的时候(想想《不要和陌生人说话》里面的冯远征),这些就都是噪声了。

除了笑之外,这里可用的特征还有纹身,性别等可以考虑。朴素贝叶斯把类似“笑”这样的特征概率化,构成一个“人的样貌向量”以及对应的“好人/坏人标签”,训练出一个标准的“好人模型”和“坏人模型”,这些模型都是各个样貌特征概率构成的。这样,当一个品行未知的人来以后,我们迅速获取ta的样貌特征向量,分布输入“好人模型”和“坏人模型”,得到两个概率值。如果“坏人模型”输出的概率值大一些,那这个人很有可能就是个大坏蛋了。

决策树是怎么办的呢?决策树可能先看性别,因为它发现给定的带标签人群里面男的坏蛋特别多,这个特征眼下最能区分坏蛋和好人,然后按性别把一拨人分成两拨;接着看“笑”这个特征,因为它是接下来最有区分度的特征,然后把两拨人分成四拨;接下来看纹身,,,,最后发现好人要么在田里种地,要么在山上砍柴,要么在学堂读书。而坏人呢,要么在大街上溜达,要么在地下买卖白粉,要么在海里当海盗。这些个有次序的特征就像路上的一个个垫脚石(树的节点)一样,构成通往不同地方的路径(树的枝丫),这些不同路径的目的地(叶子)就是一个类别容器,包含了一类人。一个品行未知的人来了,按照其样貌特征顺序及其对应的特征值,不断走啊走,最后走到了农田或山上,那就是好人;走到了地下或大海,那就是大坏蛋。(这是个看脸的例子,但重点不是“脸”,是“例子”,这真的只是个没有任何偏见的例子)。可以看出来,两种分类模型的原理是很不相同。

2.理论基础——条件概率,词集模型、词袋模型

条件概率:朴素贝叶斯最核心的部分是贝叶斯法则,而贝叶斯法则的基石是条件概率。贝叶斯法则如下:

这里的C表示类别,输入待判断数据,式子给出要求解的某一类的概率。我们的最终目的是比较各类别的概率值大小,
而上面式子的分母是不变的,因此只要计算分子即可。仍以“坏蛋识别器”为例。我们用C0表示好人,C1表示坏人,
现在100个人中有60个好人,则P(C0)=0.6,那么P(x,y|C0)怎么求呢?注意,这里的(x,y)是多维的,因为有
60个好人,每个人又有“性别”、“笑”、“纹身”等多个特征,这些构成X,y是标签向量,有60个0和40个1构成。
这里我们假设X的特征之间是独立的,互相不影响,这就是朴素贝叶斯中“朴素”的由来。在假设特征间独立的假设下
,很容易得到P(x,y|C0)=P(x0,y0|C0)P(x1,y1|C0)...P(xn,yn|C0)。然而,P(xn,yn|C0),n=0,1,
...,n如何求呢?有两种情况,涉及到词集模型和词袋模型。接下来我们举个更合适的例子,那就是文本分类。我们
的训练集由正常的文档和侮辱性的文档组成,能反映侮辱性文档的是侮辱性词汇的出现与否以及出现频率。

词集模型:对于给定文档,只统计某个侮辱性词汇(准确说是词条)是否在本文档出现
    词袋模型:对于给定文档,统计某个侮辱性词汇在本文当中出现的频率,除此之外,往往还需要剔除重要性极低的高频词和停用词。因此,词袋模型更精炼,也更有效。

需要解释的是,为了高效计算,求解P(x,y|C0)时是向量化操作的,因此不会一个个的求解P(xn,yn|C0)。

3.数据预处理——向量化

向量化、矩阵化操作是机器学习的追求。从数学表达式上看,向量化、矩阵化表示更加简洁;在实际操作中,矩阵化(向量是特殊的矩阵)更高效。仍然以侮辱性文档识别为例:

首先,我们需要一张词典,该词典囊括了训练文档集中的所有必要词汇(无用高频词和停用词除外),还需要把每个文档剔除高频词和停用词;

其次,根据词典向量化每个处理后的文档。具体的,每个文档都定义为词典大小,分别遍历某类(侮辱性和非侮辱性)文档中的每个词汇并统计出现次数;最后,得到一个个跟词典一样大小的向量,这些向量有一个个整数组成,每个整数代表了词典上一个对应位置的词在当下文档中的出现频率。

最后,统计每一类处理过的文档中词汇总个数,某一个文档的词频向量除以相应类别的词汇总个数,即得到相应的条件概率,如P(x,y|C0)。有了P(x,y|C0)和P(C0),P(C0|x,y)就得到了,用完全一样的方法可以获得

P(C1|x,y)。比较它们的大小,即可知道某人是不是大坏蛋,某篇文档是不是侮辱性文档了。

4.Python代码解读

def loadDataSet():
        postingList=[[‘my‘,‘dog‘,‘has‘,‘flea‘,‘problem‘,‘help‘,‘please‘],
                     [‘maybe‘,‘not‘,‘take‘,‘him‘,‘to‘,‘dog‘,‘park‘,‘stupid‘],
                     [‘my‘,‘dalmation‘,‘is‘,‘so‘,‘cute‘,‘I‘,‘love‘,‘him‘],
                     [‘stop‘,‘posting‘,‘ate‘,‘my‘,‘steak‘,‘how‘,‘to‘,‘stop‘,‘him‘],
                     [‘mr‘,‘licks‘,‘ate‘,‘my‘,‘steak‘,‘how‘,‘to‘,‘stop‘,‘him‘],
                     [‘quit‘,‘buying‘,‘worthless‘,‘dog‘,‘food‘,‘stupid‘]]
        classVec=[0,1,0,1,0,1]
        return postingList,classVec
    #定义一个简单的文本数据集,由6个简单的文本以及对应的标签构成。1表示侮辱性文档,0表示正常文档。
    def createVocabList(dataSet):
        vocabSet=set([])
        for document in dataSet:
            vocabSet=vocabSet|set(document)
        return list(vocabSet)
    def setOfWords2Vec(vocabList,inputSet):
        returnVec=[0]*len(vocabList)               #每个文档的大小与词典保持一致,此时returnVec是空表
        for word in inputSet:
            if word in vocabList:
                returnVec[vocabList.index(word)]=1 #当前文档中有某个词条,则根据词典获取其位置并赋值1
            else:print "the word :%s is not in my vocabulary" %word
        return returnVec        
    def bagOfWords2Vec(vocabList,inputSet):
        returnVec=[0]*len(vocabList)
        for word in inputSet:
            if word in vocabList:
                returnVec[vocabList.index(word)]+=1 # 与词集模型的唯一区别就表现在这里
            else:print "the word :%s is not in my vocabulary" %word
        return returnVec
    #### 文档向量化,这里是词袋模型,不知关心某个词条出现与否,还考虑该词条在本文档中的出现频率
     
    def trainNB(trainMatrix,trainCategory):                                        
        numTrainDocs=len(trainMatrix)     
        numWords=len(trainMatrix[0])        
        pAbusive=sum(trainCategory)/float(numTrainDocs) #统计侮辱性文档的总个数,然后除以总文档个数  
        #p0Num=zeros(numWords);p1Num=zeros(numWords)    # 把属于同一类的文本向量加起来
        #p0Denom=0.0;p1Denom=0.0
        p0Num=ones(numWords);p1Num=ones(numWords)
        p0Denom=2.0;p1Denom=2.0
        for i in range(numTrainDocs):
            if trainCategory[i]==1:
                p1Num+=trainMatrix[i]#把属于同一类的文本向量相加,实质是统计某个词条在该类文本中出现频率
                p1Denom+=sum(trainMatrix[i]) #把侮辱性文档向量的所有元素加起来
            else:
                p0Num+=trainMatrix[i]
                p0Denom+=sum(trainMatrix[i])
        #p1Vec=p1Num/float(p1Denom)
        #p0Vec=p0Num/float(p0Denom)
        p1Vec=log(p1Num/p1Denom) #统计词典中所有词条在侮辱性文档中出现的概率
        p0Vec=log(p0Num/p0Denom) #统计词典中所有词条在正常文档中出现的概率
        return pAbusive,p1Vec,p0Vec
    #### 训练生成朴素贝叶斯模型,实质上相当于是计算P(x,y|Ci)P(Ci)的权重。
    ### 注意:被注释掉的代码代表不太好的初始化方式,在那种情况下某些词条的概率值可能会非常非常小,甚至约
    ###等于0,那么在不同词条的概率在相乘时结果就近似于0
    def classifyNB(vec2classify,p0Vec,p1Vec,pClass1):  # 参数1是测试文档向量,参数2和参数3是词条在各个
                                                        #类别中出现的概率,参数4是P(C1)
        p1=sum(vec2classify*p1Vec)+log(pClass1)   # 这里没有直接计算P(x,y|C1)P(C1),而是取其对数
                                                     #这样做也是防止概率之积太小,以至于为0
        p0=sum(vec2classify*p0Vec)+log(1.0-pClass1) #取对数后虽然P(C1|x,y)和P(C0|x,y)的值变了,但是
                                                     #不影响它们的大小关系。
        if p1>p0:
            return 1
        else:
            return 0

5.总结

不同于其它分类器,朴素贝叶斯是一种基于概率理论的分类算法;
    特征之间的条件独立性假设,显然这种假设显得“粗鲁”而不符合实际,这也是名称中“朴素”的由来。然而事实证明,朴素贝叶斯在有些领域很有用,比如垃圾邮件过滤;
    在具体的算法实施中,要考虑很多实际问题。比如因为“下溢”问题,需要对概率乘积取对数;再比如词集模型和词袋模型,还有停用词和无意义的高频词的剔除,以及大量的数据预处理问题,等等;
    总体上来说,朴素贝叶斯原理和实现都比较简单,学习和预测的效率都很高,是一种经典而常用的分类算法。
---------------------  
作者:千君一发  
来源:CSDN  
原文:https://blog.csdn.net/li8zi8fa/article/details/76176597  
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/fengff/p/10083531.html

时间: 2024-11-12 04:29:43

深入理解朴素贝叶斯(Naive Bayes)的相关文章

朴素贝叶斯(naive bayes)

朴素贝叶斯(naive bayes) 主要参考资料:<机器学习实战><统计学习方法> 1.朴素贝叶斯分类原理 朴素贝叶斯法是基于贝叶斯定理和特征条件独立假设(称为朴素的原因)的分类方法.先看看维基百科中贝叶斯定理的描述: 贝叶斯定理(维基百科) 通常,事件A在事件B(发生)的条件下的概率,与事件B在事件A的条件下的概率是不一样的:然而,这两者是有确定的关系,贝叶斯定理就是这种关系的陈述. 公式描述如下: P(A|B)=P(A|B)P(A)P(B) 其中P(A|B)是在B发生的情况下

趣味案例理解朴素贝叶斯

机器学习(10)之趣味案例理解朴素贝叶斯 转载:https://mp.weixin.qq.com/s/s0v_afLVqtJhZyn3qHlseQ 01 病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难.某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒 打喷嚏 农夫 过敏 头疼 建筑工人 脑震荡 头疼 建筑工人 感冒 打喷嚏 教师 感冒 头疼 教师 脑震荡 现在又来了第七个病人,是一个打喷嚏的建筑工人.请问他患上感冒的概率有多大? 根据贝

NLP系列(2)_用朴素贝叶斯进行文本分类(上)

作者:寒小阳 && 龙心尘 时间:2016年1月. 出处:http://blog.csdn.net/longxinchen_ml/article/details/50597149 http://blog.csdn.net/han_xiaoyang/article/details/50616559 声明:版权全部,转载请联系作者并注明出处 1. 引言 贝叶斯方法是一个历史悠久.有着坚实的理论基础的方法,同一时候处理非常多问题时直接而又高效.非常多高级自然语言处理模型也能够从它演化而来.因此,

Step by Step 改进朴素贝叶斯算法

引言 如果你对naive bayes认识还处于初级阶段,只了解基本的原理和假设,还没有实现过产品级的代码,那么这篇文章能够帮助你一步步对原始的朴素贝叶斯算法进行改进.在这个过程中你将会看到朴素贝叶斯假设的一些不合理处以及局限性,从而了解为什么这些假设在简化你的算法的同时,使最终分类结果变得糟糕,并针对这些问题提出了改进的方法. 朴素贝叶斯(Naive Bayes) 出处: <机器学习>(Machine Learning by Tom M.Mitchell) 符号和术语 假设待分类的实例 X 可

统计学习方法 李航---第4章 朴素贝叶斯法

第4章 朴素贝叶斯法 朴素贝叶斯 (naive Bayes) 法是基于贝叶斯定理与特征条件独立假设的分类方法.对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布:然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出Y. 4.1 朴素贝叶斯法的学习与分类 基本方法 朴素贝叶斯法通过训练数据集学习X和Y的联合概率分布 P(X,Y). 具体地,学习以 下先验概率分布及条件概率分布. 先验概率分布 条件概率分布 条件概率分布有指数级数量的参数,其估计实际是不可行的

斯坦福机器学习实现与分析之六(朴素贝叶斯)

朴素贝叶斯(Naive Bayes)适用于离散特征的分类问题,对于连续问题则需将特征离散化后使用.朴素贝叶斯有多元伯努利事件模型和多项式事件模型,在伯努利事件模型中,特征每一维的值只能是0或1,而多项式模型中特征每一维的值可取0到N之间的整数,因此伯努利模型是多项式模型的一种特例,下面的推导就直接使用伯努利模型. 朴素贝叶斯原理推导 与GDA类似,朴素贝叶斯对一个测试样本分类时,通过比较p(y=0|x)和p(y=1|x)来进行决策.根据贝叶斯公式: \( \begin{aligned} p(y=

斯坦福CS229机器学习课程笔记四:GDA、朴素贝叶斯、多项事件模型

生成学习与判别学习 像逻辑回归,用hθ(x) = g(θTx) 直接地来建模 p(y|x; θ) :或者像感知机,直接从输入空间映射到输出空间(0或1),它们都被称作判别学习(discriminative learning).与之相对的是生成学习(generative learning),先对 p(x|y) 与 p(y) 建模,然后通过贝叶斯法则导出后验条件概率分布分母的计算规则为全概率公式:p(x) = p(x|y = 1)p(y = 1) + p(x|y =0)p(y = 0).这一节介绍的

统计学习四:1.朴素贝叶斯

全文引用自<统计学习方法>(李航) 朴素贝叶斯(naive Bayes)法 是以贝叶斯定理为基础的一中分类方法,它的前提条件是假设特征条件相互独立.对于给定的训练集,它首先基于特征条件假设的前提条件,去学习输入与输出的条件概率分布,然后根据此分布模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y. 1.朴素贝叶斯的学习与分类 1.1 基本方法 假设输入空间\(X \subseteq R^n\)为n维向量的集合,输入空间为类标记集合\(Y=\{c_1,c_2,\cdots,c_K\}\

朴素贝叶斯算法小结

朴素贝叶斯naive bayes是直接生成方法,也就是直接找出特征输出Y和特征X的联合分布P(X,Y)P(X,Y),然后用P(Y|X)=P(X,Y)/P(X)P(Y|X)=P(X,Y)/P(X)得出. 数学基础: 1. 最大似然估计 原文地址:https://www.cnblogs.com/guodavid/p/10169867.html