基于概率论的分类方法:朴素贝叶斯

原创 2018年04月16日 17:22:55

        其实朴素贝叶斯分类用一个区分是否是侮辱性句子的应用来说就是:

                我们先通过训练集来算出 当句子是侮辱性句子时,单词(要计算很多个单词)出现的概率W,然后通过概率W来预测测试句子是否是侮辱性句子。


使用朴素贝叶斯进行文档分类:以社区的留言板为例,运用朴素贝叶斯算法,对文本自动分类是否是侮辱性句子

    一,准备数据

            1.生成测试集包括一个文本矩阵,和一个人工标注的是否是侮辱性句子的一维矩阵。

            这里省去了如何将文本转化为下列格式的步骤,为了方便后面的测试,这里直接用函数生成了一个已经数据清洗好的测试集。

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

            2.生成词汇表

def createVocablist(dataSet):   #生成一个包含所有不重复单词的列表,
    vocabSet=set([])    #创建一个空集
    for document in dataSet:
        vocabSet=vocabSet | set(document) #求两个集合的并集 
    return list(vocabSet)

         3.构建词向量,这里采用的是词集模型,即只需记录每个词是否出现,而不考虑其出现的次数。需要记录词出现的次数的叫词袋模型。

            设存在一个词汇表list['a','b','c','d'] 和一个文本words['a','c']

            该函数的作用就是将 ['a','c'] 转换为[1,0,1,0] ---对应于list['a','b','c','d']            

def setOfWords2Vec(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
       将所有的句子都转化为词向量
tarinMat=[]
for postinDoc in listOposts:
    tarinMat.append(setOfWords2Vec(myVocabList,postinDoc))


二.训练算法:从词向量计算概率

原理:

                             贝叶斯定理如下式:      

    其中,x,y表示特征变量, 表示分类,即表示在特征为x,y的情况下分入类别的概率,因此,结合条件概率和贝叶斯定理,有:

●     如果,那么分类应当属于类;

●     如果,那么分类应当属于类;

       将x,y变为W,这里W是一个向量表示很多特征值,表示的是词汇表的单词在(侮辱性句子|正常语句)出现的概率。

                                                        

         

用训练集中,属于类别的样本数量除以总的样本数量即可;


可以根据前面的独立性假设,先分别计算等项,再将其结果相乘即可,而的计算公式为:

                                                                                                 

当仅仅是为了比较大小的时候,由于分母相同,因此只需要比较分子即可。

    朴素贝叶斯是基于特征条件独立这个假设的。也就是说,我们假设词汇表中各个单词独立出现,不会相互影响,因此可以将展开成独立事件概率相乘的形式,即:


    这个假设极大地降低了计算的复杂度,这也是朴素贝叶斯中“朴素”一词的由来。


在实现算法时,需要考虑两个问题

       a.当使用连乘计算时,若某一个词的概率为0,那么最终的结果也会为0,这是不正确的。为防止这种情况,需要将所有词项出现的次数都初始化为1,每一类所有词项数量初始化为2;

       b.在连乘时,为防止单项概率过小导致连乘结果下溢,需要对结果求自然对数将其转化为加法,因为


  1.求出ci,w/ci的概率,因为c1=1-c0.所以求一个就好了。

def trainNB0(trainMatrix,trainCategroy):
    numTrainDocs=len(trainMatrix) #留言总数 
    numWords=len(trainMatrix[0]) #单词个数。 
    pAbusive=sum(trainCategroy)/float(numTrainDocs) #侮辱性句子的概率 
    p0num=np.ones(numWords) #单词出现个数初始化为1 
    p1num=np.ones(numWords) 
    p0demon=2.0 #各类别单词出现总数初始化为2 
    p1demon=2.0 
    for i in range(numTrainDocs):
         if trainCategroy[i]==1:
             p1num+=trainMatrix[i] 
             p1demon+=np.sum(trainMatrix[i])
         else: p0num+=trainMatrix[i]
             p0demon+=np.sum(trainMatrix[i]) 
   p1Vect=np.log(p1num/p1demon) #转化为Log 函数 
   p0Vect=np.log(p0num/p0demon) 
   return p0Vect,p1Vect,pAbusive


2.利用上面求出的概率,定义预测函数。
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    p1=np.sum(vec2Classify*p1Vec)+np.log(pClass1)
    p0=np.sum(vec2Classify*p0Vec)+np.log(1-pClass1)
    if p1>p0:
        return 1
    else:
        return 0

其中vec2Classify 表示的是要预测的句子的词向量。

p0Vec,p1Vec,pClass1均为上一步函数的返回值,分别代表公式中的

3.编写测试函数。

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

结果:

                            


参考:Peter Harrington 《机器学习实战》

机器学习之朴素贝叶斯(NB)分类算法与Python实现

朴素贝叶斯(Naive Bayesian)是最为广泛使用的分类方法,它以概率论为基础,是基于贝叶斯定理和特征条件独立假设的分类方法。文章总结在学习《机器学习实战》过程中的心得体会,对朴素贝叶斯的原理和...
  • moxigandashu
  • moxigandashu
  • 2017年05月09日 23:22
  • 6896

基于概率论的分类方法:朴素贝叶斯

例子来自机器学习实战一书,语言是python 朴素贝叶斯 优点:在数据较少的情况下仍然有效,可以处理多类别的问题。 缺点:对于输入数据的准备方式较为敏感。 适用数据类型:标称型数据 ...
  • xia744510124
  • xia744510124
  • 2015年05月05日 19:48
  • 542

机器学习实战--基于概率论的分类方法:朴素贝叶斯

朴素贝叶斯概述 朴素贝叶斯算法就是利用我们在概率论中学习的条件概率公式来处理一些分类问题。 朴素贝叶斯 优点:在数据较少的情况下仍然有效,可以处理多类别问题 缺点:对于输入数据的准备...
  • czliuming
  • czliuming
  • 2016年04月29日 15:18
  • 7881

机器学习——朴素贝叶斯(基于概率论的分类方法)

前言 分类器有时会产生错误结果,这是要求分类器给出一个最优的类别猜测结果,同时给出这个猜测的概率估计值。 1.使用概率论分布进行分类 2.学习朴素贝叶斯分类器 3.解析RSS源数据 4.使用朴素贝叶...
  • u010343650
  • u010343650
  • 2016年12月19日 14:54
  • 1293

基于概率论的分类方法:朴素贝叶斯及CSDN_RSS源分析

本文所有代码都是基于python3.6的,数据及源码下载:传送门引言最简单的解决方法通常是最强大的,朴素贝叶斯呢就是一个很好的证明。尽管在过去的几年里机器学习取得了巨大的进步,各种优秀算法层出不穷,但...
  • u010665216
  • u010665216
  • 2017年10月14日 09:12
  • 320

机器学习实战 - 基于概率论的分类方法:朴素贝叶斯

基于概率论,如果A事件发生的概率大于B时间发生的概率那么我们的“决策机构”就选择A事件,反则选B。...
  • a389850155
  • a389850155
  • 2017年04月24日 21:11
  • 967

基于朴素贝叶斯的兴趣分类

寒假期间使用了朴素贝叶斯算法对用户画像中的用户兴趣进行了分类,然而最终预测的准确率以及召回率却不尽如人意,这里就谈谈朴素贝叶斯算法的使用以及我对此次失败的一个小小反思吧~关于分类分类是将一个未知样本分...
  • Totoro1745
  • Totoro1745
  • 2017年04月03日 11:59
  • 660

第四章 基于概率论的分类方法:朴素贝叶斯

朴素贝叶斯在数据较少的情况下仍然有效,可以处理多类别问题,但是对输入数据的准备方式较为敏感。贝叶斯决策理论的核心思想是选择具有最该概率的决策。应用贝叶斯准则得到: ...
  • u012465655
  • u012465655
  • 2018年02月28日 11:08
  • 14

机器学习——基于概率论的分类方法:朴素贝叶斯

一.贝叶斯概述: 贝叶斯决策论是概率框架下实施决策的基本方法。对分类任务来说,在所有相关概率都已知的理想情形下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。朴素贝叶斯采用了“属性条...
  • u013289254
  • u013289254
  • 2017年03月18日 16:53
  • 307

基于概率论的分类方法--朴素贝叶斯

朴素贝叶斯法是基于贝叶斯定理和特征条件独立假设(用于分类的特征在类确定的情况下是条件独立的)的分类方法 对于给定的训练数据集,首先基于特征条件独立假设 学习输入、输出的联合概率分布;然后基于此模型,对...
  • fangafangxiaoniu
  • fangafangxiaoniu
  • 2017年12月19日 11:15
  • 25
收藏助手
不良信息举报
您举报文章:基于概率论的分类方法:朴素贝叶斯
举报原因:
原因补充:

(最多只允许输入30个字)