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  
版权声明:本文为博主原创文章,转载请附上博文链接!

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

  1. 朴素贝叶斯 Naive Bayes

    2017-12-15 19:08:50 朴素贝叶斯分类器是一种典型的监督学习的算法,其英文是Naive Bayes.所谓Naive,就是天真的意思,当然这里翻译为朴素显得更学术化. 其核心思想就是利用 ...

  2. 机器学习算法实践:朴素贝叶斯 (Naive Bayes)(转载)

    前言 上一篇<机器学习算法实践:决策树 (Decision Tree)>总结了决策树的实现,本文中我将一步步实现一个朴素贝叶斯分类器,并采用SMS垃圾短信语料库中的数据进行模型训练,对垃圾 ...

  3. 朴素贝叶斯(Naive Bayesian)

    简介 Naive Bayesian算法 也叫朴素贝叶斯算法(或者称为傻瓜式贝叶斯分类) 朴素(傻瓜):特征条件独立假设 贝叶斯:基于贝叶斯定理 这个算法确实十分朴素(傻瓜),属于监督学习,它是一个常用 ...

  4. 【机器学习速成宝典】模型篇05朴素贝叶斯【Naive Bayes】(Python版)

    目录 先验概率与后验概率 条件概率公式.全概率公式.贝叶斯公式 什么是朴素贝叶斯(Naive Bayes) 拉普拉斯平滑(Laplace Smoothing) 应用:遇到连续变量怎么办?(多项式分布, ...

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

    作者:龙心尘 && 寒小阳 时间:2016年1月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50597149 h ...

  6. 【Udacity】朴素贝叶斯

    机器学习就像酿制葡萄酒--好的葡萄(数据)+好的酿酒方法(机器学习算法) 监督分类 supervised classification Features -->Labels 保留10%的数据作为 ...

  7. 【机器学习与R语言】3-概率学习朴素贝叶斯(NB)

    目录 1.理解朴素贝叶斯 1)基本概念 2)朴素贝叶斯算法 2.朴素贝斯分类应用 1)收集数据 2)探索和准备数据 3)训练模型 4)评估模型性能 5)提升模型性能 1.理解朴素贝叶斯 1)基本概念 ...

  8. 朴素贝叶斯算法--python实现

    朴素贝叶斯算法要理解一下基础:    [朴素:特征条件独立   贝叶斯:基于贝叶斯定理] 1朴素贝叶斯的概念[联合概率分布.先验概率.条件概率**.全概率公式][条件独立性假设.]   极大似然估计 ...

  9. 【十大算法实现之naive bayes】朴素贝叶斯算法之文本分类算法的理解与实现

    关于bayes的基础知识,请参考: 基于朴素贝叶斯分类器的文本聚类算法 (上) http://www.cnblogs.com/phinecos/archive/2008/10/21/1315948.h ...

随机推荐

  1. python virtualenv安装说明

    环境说明: virtualenv安装: 第一步,创建目录code: 第二步,创建一个独立的Python运行环境,命名为venv: 新建的Python环境被放到当前目录下的venv目录. 第三步,有了v ...

  2. 基础知识《十二》一篇文章理解Cookie和Session

    理解Cookie和Session机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定 ...

  3. .net环境下的缓存技术-转载!

    摘要: 介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1         概念 1.1   缓存能解决的问题 · 性 ...

  4. Android设计和开发系列第二篇:Action Bar(Design)

    Action Bar The action bar is a dedicated piece of real estate at the top of each screen that is gene ...

  5. Material Design系列第四篇——Defining Shadows and Clipping Views

    Defining Shadows and Clipping Views This lesson teaches you to Assign Elevation to Your Views Custom ...

  6. Cross-compilation using Clang

    Introduction This document will guide you in choosing the right Clang options for cross-compiling yo ...

  7. sencha touch 在线实战培训 第一期 第七节

    2014.1.13晚上8点过一点开的课 本期培训一共八节,前三堂免费,后面的课程需要付费才可以观看. 本节内容:             非结构化数据传输 通过js调取phonegap实现图片采集.上 ...

  8. 应急响应--记录一次漏洞紧急处理中意外发现的挖矿木马(Shiro反序列化漏洞和ddg挖矿木马)

    背景 某公司线上服务器意外发现一个Apache Shiro 反序列化漏洞,可以直接GetShell.出于做安全的谨慎,马上出现场应急,确认漏洞.该漏洞存在在cookie字段中的rememberMe字段 ...

  9. 2015.7.8js-05(简单日历)

    今天做一个简单的小日历,12个月份,鼠标移动其中一个月份时添加高亮并显示本月的活动.其实同理与选项卡致.不过是内容存在js里 window.onload = function(){ var oMain ...

  10. 关于数据库DB负载均衡的初步研究(二)

    负载均衡: 是什么:有一组服务器由路由器联系在一起,各个节点相互协作,共同负载,均衡压力. 实现原理:应用程序与DB之间有个中央控制台服务器,根据负载均衡策略决定访问哪一台DB服务器. DB服务器:读 ...