机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器

原文连接: Jack-Cui,cuijiahua.com/blog/2017/1…html

1、前言

朴素贝叶斯算法是有监督的学习算法,解决的是分类问题,如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优势在于简单易懂、学习效率高、在某些领域的分类问题中可以与决策树、神经网络相媲美。但因为该算法以自变量之间的独立(条件特征独立)性和连续变量的正态性假设为前提,就会致使算法精度在某种程度上受影响。python

本篇文章将从朴素贝叶斯推断原理开始讲起,经过实例进行辅助讲解。最后,使用Python3编程实现一个简单的言论过滤器。git

2、朴素贝叶斯理论

朴素贝叶斯是贝叶斯决策理论的一部分,因此在讲述朴素贝叶斯以前有必要快速了解一下贝叶斯决策理论。github

一、贝叶斯决策理论

假设如今咱们有一个数据集,它由两类数据组成,数据分布以下图所示:算法

咱们如今用p1(x,y)表示数据点(x,y)属于类别1(图中红色圆点表示的类别)的几率,用p2(x,y)表示数据点(x,y)属于类别2(图中蓝色三角形表示的类别)的几率,那么对于一个新数据点(x,y),能够用下面的规则来判断它的类别:编程

  • 若是p1(x,y)>p2(x,y),那么类别为1
  • 若是p1(x,y)<p2(x,y),那么类别为2

也就是说,咱们会选择高几率对应的类别。这就是贝叶斯决策理论的核心思想,即选择具备最高几率的决策。已经了解了贝叶斯决策理论的核心思想,那么接下来,就是学习如何计算p1和p2几率。数组

二、条件几率

在学习计算p1 和p2几率以前,咱们须要了解什么是条件几率(Condittional probability),就是指在事件B发生的状况下,事件A发生的几率,用P(A|B)来表示。bash

根据文氏图,能够很清楚地看到在事件B发生的状况下,事件A发生的几率就是P(A∩B)除以P(B)。网络

所以,app

同理可得,

因此,

这就是条件几率的计算公式。

三、全几率公式

除了条件几率之外,在计算p1和p2的时候,还要用到全几率公式,所以,这里继续推导全几率公式。

假定样本空间S,是两个事件A与A'的和。

上图中,红色部分是事件A,绿色部分是事件A',它们共同构成了样本空间S。

在这种状况下,事件B能够划分红两个部分。

在上一节的推导当中,咱们已知

因此,

这就是全几率公式。它的含义是,若是A和A'构成样本空间的一个划分,那么事件B的几率,就等于A和A'的几率分别乘以B对这两个事件的条件几率之和。

将这个公式代入上一节的条件几率公式,就获得了条件几率的另外一种写法:

四、贝叶斯推断

对条件几率公式进行变形,能够获得以下形式:

咱们把P(A)称为"先验几率"(Prior probability),即在B事件发生以前,咱们对A事件几率的一个判断。

P(A|B)称为"后验几率"(Posterior probability),即在B事件发生以后,咱们对A事件几率的从新评估。

P(B|A)/P(B)称为"可能性函数"(Likelyhood),这是一个调整因子,使得预估几率更接近真实几率。

因此,条件几率能够理解成下面的式子:

后验几率&emsp;=&emsp;先验几率 x 调整因子
复制代码

这就是贝叶斯推断的含义。咱们先预估一个"先验几率",而后加入实验结果,看这个实验究竟是加强仍是削弱了"先验几率",由此获得更接近事实的"后验几率"

在这里,若是"可能性函数"P(B|A)/P(B)>1,意味着"先验几率"被加强,事件A的发生的可能性变大;若是"可能性函数"=1,意味着B事件无助于判断事件A的可能性;若是"可能性函数"<1,意味着"先验几率"被削弱,事件A的可能性变小。

为了加深对贝叶斯推断的理解,咱们举一个例子。

两个如出一辙的碗,一号碗有30颗水果糖和10颗巧克力糖,二号碗有水果糖和巧克力糖各20颗。如今随机选择一个碗,从中摸出一颗糖,发现是水果糖。请问这颗水果糖来自一号碗的几率有多大?

咱们假定,H1表示一号碗,H2表示二号碗。因为这两个碗是同样的,因此P(H1)=P(H2),也就是说,在取出水果糖以前,这两个碗被选中的几率相同。所以,P(H1)=0.5,咱们把这个几率就叫作"先验几率",即没有作实验以前,来自一号碗的几率是0.5。

再假定,E表示水果糖,因此问题就变成了在已知E的状况下,来自一号碗的几率有多大,即求P(H1|E)。咱们把这个几率叫作"后验几率",即在E事件发生以后,对P(H1)的修正。

根据条件几率公式,获得

已知,P(H1)等于0.5,P(E|H1)为一号碗中取出水果糖的几率,等于30÷(30+10)=0.75,那么求出P(E)就能够获得答案。根据全几率公式,

因此,

将数字代入原方程,获得

这代表,来自一号碗的几率是0.6。也就是说,取出水果糖以后,H1事件的可能性获得了加强。

同时再思考一个问题,在使用该算法的时候,若是不须要知道具体的类别几率,即上面P(H1|E)=0.6,只须要知道所属类别,即来自一号碗,咱们有必要计算P(E)这个全几率吗?要知道咱们只须要比较 P(H1|E)和P(H2|E)的大小,找到那个最大的几率就能够。既然如此,二者的分母都是相同的,那咱们只须要比较分子便可。即比较P(E|H1)P(H1)和P(E|H2)P(H2)的大小,因此为了减小计算量,全几率公式在实际编程中能够不使用

五、朴素贝叶斯推断

理解了贝叶斯推断,那么让咱们继续看看朴素贝叶斯。贝叶斯和朴素贝叶斯的概念是不一样的,区别就在于“朴素”二字,朴素贝叶斯对条件个几率分布作了条件独立性的假设。 好比下面的公式,假设有n个特征:

因为每一个特征都是独立的,咱们能够进一步拆分公式 :

)

这样咱们就能够进行计算了。若是有些迷糊,让咱们从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难。

某个医院早上来了六个门诊的病人,他们的状况以下表所示:

如今又来了第七个病人,是一个打喷嚏的建筑工人。请问他患上感冒的几率有多大?

根据贝叶斯定理:

可得:

根据朴素贝叶斯条件独立性的假设可知,"打喷嚏"和"建筑工人"这两个特征是独立的,所以,上面的等式就变成了

这里能够计算:

所以,这个打喷嚏的建筑工人,有66%的几率是得了感冒。同理,能够计算这个病人患上过敏或脑震荡的几率。比较这几个几率,就能够知道他最可能得什么病。

这就是贝叶斯分类器的基本方法:在统计资料的基础上,依据某些特征,计算各个类别的几率,从而实现分类。

一样,在编程的时候,若是不须要求出所属类别的具体几率,P(打喷嚏) = 0.5和P(建筑工人) = 0.33的几率是能够不用求的。

3、动手实战

说了这么多,没点实践编程怎么行?

以在线社区留言为例。为了避免影响社区的发展,咱们要屏蔽侮辱性的言论,因此要构建一个快速过滤器,若是某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。过滤这类内容是一个很常见的需求。对此问题创建两个类型:侮辱类和非侮辱类,使用1和0分别表示。

咱们把文本当作单词向量或者词条向量,也就是说将句子转换为向量。考虑出现全部文档中的单词,再决定将哪些单词归入词汇表或者说所要的词聚集合,而后必需要将每一篇文档转换为词汇表上的向量。简单起见,咱们先假设已经将本文切分完毕,存放到列表中,并对词汇向量进行分类标注。编写代码以下:

# -*- coding: UTF-8 -*-
 
""" 函数说明:建立实验样本 Parameters: 无 Returns: postingList - 实验样本切分的词条 classVec - 类别标签向量 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
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]                                                                   #类别标签向量,1表明侮辱性词汇,0表明不是
    return postingList,classVec
 
if __name__ == '__main__':
    postingLIst, classVec = loadDataSet()
    for each in postingLIst:
        print(each)
    print(classVec)
复制代码

从运行结果能够看出,咱们已经将postingList是存放词条列表中,classVec是存放每一个词条的所属类别,1表明侮辱类 ,0表明非侮辱类。

继续编写代码,前面咱们已经说过咱们要先建立一个词汇表,并将切分好的词条转换为词条向量。

# -*- coding: UTF-8 -*-
 
""" 函数说明:建立实验样本 Parameters: 无 Returns: postingList - 实验样本切分的词条 classVec - 类别标签向量 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
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]                                                                   #类别标签向量,1表明侮辱性词汇,0表明不是
    return postingList,classVec
 
""" 函数说明:根据vocabList词汇表,将inputSet向量化,向量的每一个元素为1或0 Parameters: vocabList - createVocabList返回的列表 inputSet - 切分的词条列表 Returns: returnVec - 文档向量,词集模型 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)                                    #建立一个其中所含元素都为0的向量
    for word in inputSet:                                                #遍历每一个词条
        if word in vocabList:                                            #若是词条存在于词汇表中,则置1
            returnVec[vocabList.index(word)] = 1
        else: print("the word: %s is not in my Vocabulary!" % word)
    return returnVec                                                    #返回文档向量
 
""" 函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表 Parameters: dataSet - 整理的样本数据集 Returns: vocabSet - 返回不重复的词条列表,也就是词汇表 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
def createVocabList(dataSet):
    vocabSet = set([])                      #建立一个空的不重复列表
    for document in dataSet:               
        vocabSet = vocabSet | set(document) #取并集
    return list(vocabSet)
 
if __name__ == '__main__':
    postingList, classVec = loadDataSet()
    print('postingList:\n',postingList)
    myVocabList = createVocabList(postingList)
    print('myVocabList:\n',myVocabList)
    trainMat = []
    for postinDoc in postingList:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    print('trainMat:\n', trainMat)
复制代码

从运行结果能够看出,postingList是原始的词条列表,myVocabList是词汇表。myVocabList是全部单词出现的集合,没有重复的元素。词汇表是用来干什么的?没错,它是用来将词条向量化的,一个单词在词汇表中出现过一次,那么就在相应位置记做1,若是没有出现就在相应位置记做0。trainMat是全部的词条向量组成的列表。它里面存放的是根据myVocabList向量化的词条向量。

咱们已经获得了词条向量。接下来,咱们就能够经过词条向量训练朴素贝叶斯分类器。

# -*- coding: UTF-8 -*-
import numpy as np
 
""" 函数说明:建立实验样本 Parameters: 无 Returns: postingList - 实验样本切分的词条 classVec - 类别标签向量 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
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]                                                                   #类别标签向量,1表明侮辱性词汇,0表明不是
    return postingList,classVec
 
""" 函数说明:根据vocabList词汇表,将inputSet向量化,向量的每一个元素为1或0 Parameters: vocabList - createVocabList返回的列表 inputSet - 切分的词条列表 Returns: returnVec - 文档向量,词集模型 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)                                    #建立一个其中所含元素都为0的向量
    for word in inputSet:                                                #遍历每一个词条
        if word in vocabList:                                            #若是词条存在于词汇表中,则置1
            returnVec[vocabList.index(word)] = 1
        else: print("the word: %s is not in my Vocabulary!" % word)
    return returnVec                                                    #返回文档向量
 
""" 函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表 Parameters: dataSet - 整理的样本数据集 Returns: vocabSet - 返回不重复的词条列表,也就是词汇表 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
def createVocabList(dataSet):
    vocabSet = set([])                      #建立一个空的不重复列表
    for document in dataSet:
        vocabSet = vocabSet | set(document) #取并集
    return list(vocabSet)
 
""" 函数说明:朴素贝叶斯分类器训练函数 Parameters: trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵 trainCategory - 训练类别标签向量,即loadDataSet返回的classVec Returns: p0Vect - 非侮辱类的条件几率数组 p1Vect - 侮辱类的条件几率数组 pAbusive - 文档属于侮辱类的几率 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """
def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)                            #计算训练的文档数目
    numWords = len(trainMatrix[0])                            #计算每篇文档的词条数
    pAbusive = sum(trainCategory)/float(numTrainDocs)        #文档属于侮辱类的几率
    p0Num = np.zeros(numWords); p1Num = np.zeros(numWords)    #建立numpy.zeros数组,词条出现数初始化为0
    p0Denom = 0.0; p1Denom = 0.0                            #分母初始化为0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:                            #统计属于侮辱类的条件几率所需的数据,即P(w0|1),P(w1|1),P(w2|1)···
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:                                                #统计属于非侮辱类的条件几率所需的数据,即P(w0|0),P(w1|0),P(w2|0)···
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = p1Num/p1Denom                                      
    p0Vect = p0Num/p0Denom         
    return p0Vect,p1Vect,pAbusive                            #返回属于侮辱类的条件几率数组,属于非侮辱类的条件几率数组,文档属于侮辱类的几率
 
if __name__ == '__main__':
    postingList, classVec = loadDataSet()
    myVocabList = createVocabList(postingList)
    print('myVocabList:\n', myVocabList)
    trainMat = []
    for postinDoc in postingList:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    p0V, p1V, pAb = trainNB0(trainMat, classVec)
    print('p0V:\n', p0V)
    print('p1V:\n', p1V)
    print('classVec:\n', classVec)
    print('pAb:\n', pAb)
复制代码

运行结果以下,p0V存放的是每一个单词属于类别0,也就是非侮辱类词汇的几率。好比p0V的倒数第6个几率,就是stupid这个单词属于非侮辱类的几率为0。同理,p1V的倒数第6个几率,就是stupid这个单词属于侮辱类的几率为0.15789474,也就是约等于15.79%的几率。咱们知道stupid的中文意思是蠢货,难听点的叫法就是傻逼。显而易见,这个单词属于侮辱类。pAb是全部侮辱类的样本占全部样本的几率,从classVec中能够看出,一用有3个侮辱类,3个非侮辱类。因此侮辱类的几率是0.5。所以p0V存放的就是P(非侮辱类 | him) = 0.0833,P(非侮辱类 | is) = 0.0417,一直到P(非侮辱类 | dog) = 0.0417,这些单词的条件几率。同理,p1V存放的就是各个单词属于侮辱类的条件几率。pAb就是先验几率。

已经训练好分类器,接下来,使用分类器进行分类。

# -*- coding: UTF-8 -*-
import numpy as np
from functools import reduce
 
""" 函数说明:建立实验样本 Parameters: 无 Returns: postingList - 实验样本切分的词条 classVec - 类别标签向量 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
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]                                                                   #类别标签向量,1表明侮辱性词汇,0表明不是
    return postingList,classVec                                                                #返回实验样本切分的词条和类别标签向量
 
""" 函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表 Parameters: dataSet - 整理的样本数据集 Returns: vocabSet - 返回不重复的词条列表,也就是词汇表 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
def createVocabList(dataSet):
    vocabSet = set([])                      #建立一个空的不重复列表
    for document in dataSet:                
        vocabSet = vocabSet | set(document) #取并集
    return list(vocabSet)
 
""" 函数说明:根据vocabList词汇表,将inputSet向量化,向量的每一个元素为1或0 Parameters: vocabList - createVocabList返回的列表 inputSet - 切分的词条列表 Returns: returnVec - 文档向量,词集模型 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-11 """
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)                                    #建立一个其中所含元素都为0的向量
    for word in inputSet:                                                #遍历每一个词条
        if word in vocabList:                                            #若是词条存在于词汇表中,则置1
            returnVec[vocabList.index(word)] = 1
        else: print("the word: %s is not in my Vocabulary!" % word)
    return returnVec                                                    #返回文档向量
 
 
""" 函数说明:朴素贝叶斯分类器训练函数 Parameters: trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵 trainCategory - 训练类别标签向量,即loadDataSet返回的classVec Returns: p0Vect - 非侮辱类的条件几率数组 p1Vect - 侮辱类的条件几率数组 pAbusive - 文档属于侮辱类的几率 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """
def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)                            #计算训练的文档数目
    numWords = len(trainMatrix[0])                            #计算每篇文档的词条数
    pAbusive = sum(trainCategory)/float(numTrainDocs)        #文档属于侮辱类的几率
    p0Num = np.zeros(numWords); p1Num = np.zeros(numWords)    #建立numpy.zeros数组,
    p0Denom = 0.0; p1Denom = 0.0                            #分母初始化为0.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:                            #统计属于侮辱类的条件几率所需的数据,即P(w0|1),P(w1|1),P(w2|1)···
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:                                                #统计属于非侮辱类的条件几率所需的数据,即P(w0|0),P(w1|0),P(w2|0)···
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = p1Num/p1Denom                                    #相除 
    p0Vect = p0Num/p0Denom          
    return p0Vect,p1Vect,pAbusive                            #返回属于侮辱类的条件几率数组,属于非侮辱类的条件几率数组,文档属于侮辱类的几率
 
""" 函数说明:朴素贝叶斯分类器分类函数 Parameters: vec2Classify - 待分类的词条数组 p0Vec - 侮辱类的条件几率数组 p1Vec -非侮辱类的条件几率数组 pClass1 - 文档属于侮辱类的几率 Returns: 0 - 属于非侮辱类 1 - 属于侮辱类 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = reduce(lambda x,y:x*y, vec2Classify * p1Vec) * pClass1                #对应元素相乘
    p0 = reduce(lambda x,y:x*y, vec2Classify * p0Vec) * (1.0 - pClass1)
    print('p0:',p0)
    print('p1:',p1)
    if p1 > p0:
        return 1
    else: 
        return 0
 
""" 函数说明:测试朴素贝叶斯分类器 Parameters: 无 Returns: 无 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """
def testingNB():
    listOPosts,listClasses = loadDataSet()                                    #建立实验样本
    myVocabList = createVocabList(listOPosts)                                #建立词汇表
    trainMat=[]
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))                #将实验样本向量化
    p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses))        #训练朴素贝叶斯分类器
    testEntry = ['love', 'my', 'dalmation']                                    #测试样本1
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))                #测试样本向量化
    if classifyNB(thisDoc,p0V,p1V,pAb):
        print(testEntry,'属于侮辱类')                                        #执行分类并打印分类结果
    else:
        print(testEntry,'属于非侮辱类')                                        #执行分类并打印分类结果
    testEntry = ['stupid', 'garbage']                                        #测试样本2
 
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))                #测试样本向量化
    if classifyNB(thisDoc,p0V,p1V,pAb):
        print(testEntry,'属于侮辱类')                                        #执行分类并打印分类结果
    else:
        print(testEntry,'属于非侮辱类')                                        #执行分类并打印分类结果
 
if __name__ == '__main__':
    testingNB()
复制代码

咱们测试了两个词条,在使用分类器前,也须要对词条向量化,而后使用classifyNB()函数,用朴素贝叶斯公式,计算词条向量属于侮辱类和非侮辱类的几率。运行结果以下:

你会发现,这样写的算法没法进行分类,p0和p1的计算结果都是0,显然结果错误。这是为何呢?下一篇文章继续讲解~

4、总结

朴素贝叶斯推断的一些优势

  • 生成式模型,经过计算几率来进行分类,能够用来处理多分类问题。
  • 对小规模的数据表现很好,适合多分类任务,适合增量式训练,算法也比较简单。

朴素贝叶斯推断的一些缺点

  • 对输入数据的表达形式很敏感。
  • 因为朴素贝叶斯的“朴素”特色,因此会带来一些准确率上的损失。
  • 须要计算先验几率,分类决策存在错误率。

其它

  • 本文中的编程实例,存在必定的问题,须要进行改进,下篇文章会讲解改进方法;
  • 同时,本文中的编程实例,没有进行前期的文本切分,下一篇文章会讲解英文单词和中文单词的切分方法;
  • 下篇文章将使用sklearn进行中文实例练习;
  • 朴素贝叶斯的准确率,实际上是比较依赖于训练语料的,机器学习算法就和纯洁的小孩同样,取决于其成长(训练)条件,"吃的是草挤的是奶",但"不是全部的牛奶,都叫特仑苏"。
  • 参考文献:www.ruanyifeng.com/blog/2013/1…
  • 若有问题,请留言。若有错误,还望指正,谢谢!

PS: 若是以为本篇本章对您有所帮助,欢迎关注、评论、赞!

本文出现的全部代码和数据集,都可在个人github上下载,欢迎Follow、Star:github.com/Jack-Cheris…


相关文章和视频推荐

圆方圆学院聚集 Python + AI 名师,打造精品的 Python + AI 技术课程。 在各大平台都长期有优质免费公开课,欢迎报名收看。 公开课地址: ke.qq.com/course/3627…

加入python学习讨论群 78486745 ,获取资料,和广大群友一块儿学习。

圆方圆python技术讨论群
圆方圆python技术讨论群
相关文章
相关标签/搜索