朴素贝叶斯(naive bayes)

标签: Python 机器学习

主要參考资料:《机器学习实战》《统计学习方法》


1.朴素贝叶斯分类原理

朴素贝叶斯法是基于贝叶斯定理特征条件独立假设(称为朴素的原因)的分类方法。先看看维基百科中贝叶斯定理的描写叙述:

贝叶斯定理(维基百科)
通常,事件A在事件B(发生)的条件下的概率。与事件B在事件A的条件下的概率是不一样的。然而,这两者是有确定的关系,贝叶斯定理就是这样的关系的陈述。

公式描写叙述例如以下:

P(A|B)=P(B|A)P(A)P(B)

当中P(A|B)是在B发生的情况下A发生的可能性。

在机器学习中,经常常使用事件A表示属于某个类别,事件B表示特征条件的集合。下面图作为样例解说:

图中共同拥有两类点。记为c1和c2。p(ci|x,y)表示点(x,y)为类ci的概率。那么依据贝叶斯公式,能够进行例如以下分类:

  • 假设P(c1|x,y)>P(c2|x,y)。则断定该点属于c1
  • 假设P(c1|x,y)<P(c2|x,y)。则断定该点属于c2

假设用P(x,y|ci)表示类ci中点(x,y)的概率(分布)。则:

P(ci|x,y)=P(x,y|ci)P(ci)P(x,y)

又由于假设了特征条件独立。即x和y之间没有不论什么的关系。则:

P(ci|x,y)=P(x|ci)P(y|ci)P(ci)P(x,y)

分母同样,仅仅须要比較分子就可以。朴素贝叶斯算法训练的目的就是得到训练集中P(x|ci)P(y|ci)P(ci),即不同独立特征的条件概率

2.朴素贝叶斯实现

2.1准备数据

由于是简单的演示样例,直接创建训练集和类标签向量:

# 训练集:留言板的中的留言
def create_data_set(): 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

当前数据集中的数据是单词,我们要依据单词出现的频率预计出条件概率。就必须知道每一个单词出现的频数。而统计单词频数,首先得创建单词表,即全部单词仅仅出现一次的列表(集合):

#创建单词表
def create_vocablist(dataSet): vocabSet = set([])  #create empty setfor document in dataSet:vocabSet = vocabSet | set(document) #取并集return list(vocabSet)

有了单词表就能够将语句转化为频率矢量,首先将单词表全部单词的频率初始化为0。然后遍历每一条语句。将出现的单词频率置为1(0表示未出现该单词,1表示出现该单词):

#将输入语句转化为单词频率向量,表示单词表中的哪些单词出现过
def setOfWords2Vec(vocabList, inputSet):returnVec = [0]*len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] = 1else: print "the word: %s is not in my Vocabulary!" % wordreturn returnVec

利用上面生成的数据集生成一个单词表,结果例如以下:

将语句”I buying cute dog”转化为向量例如以下:

2.2训练算法

先看看训练的目标參数:P(w1|ci),P(w2|ci),...,P(wm|ci)P(ci),当中wi表示某一个单词,由于一条语句是由若干单词组成。且我们假设每一个单词出现的事件是独立的。故类ci有语句w的概率P(w⃗ |ci)=P(w1|ci),P(w2|ci),...,P(wm|ci)。

训练函数传入的參数有两个。各自是语句集合转化的单词表向量集合和类标签向量。首先依据类标签列表能够计算出侮辱性语句和非侮辱性语句的频率。然后再计算各个特征的条件概率。

计算特征的条件概率时使用了numpy中的矢量运算。极大的简化了程序的编写。先定义2个空的单词表矢量,用来统计侮辱性单词和非侮辱性单词的频数,再定义2个浮点型变量。用来统计侮辱性单词和非侮辱性单词的总数。遍历单词表向量集合。依据每一个向量的类别,统计侮辱性和非侮辱性单词的频数与总数。最后,将频数除以总数,就能够得到侮辱性或非侮辱性条件下某单词的出现的概率。

#朴素贝叶斯训练函数,输入为全部文档的单词频率向量集合。类标签向量
def trainNB(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix) #文档数量numWords = len(trainMatrix[0]) #单词表长度pAbusive = sum(trainCategory)/float(numTrainDocs) #侮辱性词语的频率p0Num = zeros(numWords); p1Num = zeros(numWords) #分子初始化为0p0Denom = 0.0; p1Denom = 0.0                   #分母初始化为0for i in range(numTrainDocs):if trainCategory[i] == 1: #假设是侮辱性语句p1Num += trainMatrix[i] #矢量相加,将侮辱性语句中出现的词语频率全部加1p1Denom += sum(trainMatrix[i]) #屈辱性词语的总量也添加else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = p1Num/p1Denom #对每一个元素做除法p0Vect = p0Num/p0Denomreturn p0Vect,p1Vect,pAbusive #返回全部词语非侮辱性词语中的频率。全部词语在侮辱性词语中的频率。侮辱性语句的频率

可是这段程序有两个问题,问题一为可能发生下溢出,问题二为某语句的某个单词在侮辱性或非侮辱性集合中的频率为0,这会导致连乘的积为0.

首先解决这个问题一:
频率都是非常小的小数,这些小数连乘的结果终于也是非常小非常小的小数,在计算机中会发生下溢出或者为0,总之都不是正确的结果。

较为常见的解决方法是使用对数。将连乘变为连加。对应的程序改动例如以下:

p1Vect = log(p1Num/p1Denom) #变为对数,防止下溢出;对每一个元素做除法
p0Vect = log(p0Num/p0Denom)

然后解决这个问题二:
能够通过分子全部初始化为1,分母初始化为2解决该问题,这样的方法在统计学中叫做贝叶斯预计
条件概率P(wj|ci)的极大似然预计为:

P(wj|ci)=∑I(wj,ci)I(ci)

我们原先就是依照上面的公式计算P(wj|ci),可是该公式可能出现所要预计的概率值为0的情况,所以给分子分母添加一项,称为条件概率的贝叶斯预计,详细例如以下:

P(wj|ci)=∑I(wj,ci)+λI(ci)+Sjλ

当中λ>0,Sj表示wj能够取得不同值的个数。当λ=1时,称为拉普拉斯平滑

在我们所讨论的问题中。wj表示某个单词是否出现,仅仅有0和1两个值。故Sj=2。所以初始化时分子为1。分母为2,再依据遍历结果添加分子和分母的值。对应的程序改动例如以下:

p0Num = ones(numWords); p1Num = ones(numWords) #分子初始化为1
p0Denom = 2.0; p1Denom = 2.0                   #分母初始化为2

2.3測试算法

依据下面准则编写分类函数:

  • 假设P(c0|x,y)>P(c1|x,y),则断定为非侮辱性语句
  • 假设P(c0|x,y)<P(c1|x,y),则断定为侮辱性语句
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1) #矢量相乘求出概率。log相加p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else: return 0

然后编写測试函数,进行測试,须要注意的是python中的列表不提供矢量运算,要想进行矢量运算,就要将列表转化为numpy中的array或者mat

def testingNB():listOPosts,listClasses = create_data_set()myVocabList = create_vocablist(listOPosts)trainMat=[]for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0V,p1V,pAb = trainNB(array(trainMat),array(listClasses))testEntry = ['love', 'my', 'dalmation']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)testEntry = ['stupid', 'garbage']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)

执行结果例如以下:

3.总结

  • 源代码在我的GitHub中,MachineLearningAction仓库里面有常见的机器学习算法处理常见数据集的各种实例,欢迎訪问
  • 朴素贝叶斯算法核心就两个:
    • 贝叶斯定理
    • 朴素:假设各个特征之间是独立的
  • 仅仅要牢记朴素贝叶斯的核心以及公式,那么编敲代码就比較easy
  • 朴素贝叶斯经常常使用于文本分类。然而该方法对于英文等语言非常好用。对中文就不是非常好,由于中文是字组成词。对于长句子要进行“分词”操作,比方“黄金”和“金黄”的字全然一样,可是意思截然不同
  • 朴素贝叶斯有非常多的改进方法,比方说用词袋模型取代词集模型,移除停用词

朴素贝叶斯(naive bayes)相关推荐

  1. 机器学习一:朴素贝叶斯(Naive Bayes)

    朴素贝叶斯 Naive Bayes 1. Introduction 1.1 离散属性 1.2 连续属性 1.2.1 Gaussian Naive Bayes 1.2.2 Multinomial Nai ...

  2. 【手写算法实现】 之 朴素贝叶斯 Naive Bayes 篇

    [手写算法实现] 之 朴素贝叶斯 Naive Bayes 篇 朴素贝叶斯模型(naive bayes)属于分类模型,也是最为简单的概率图模型,对于之后理解HMM.CRF等模型,大有裨益.这里手写算法介 ...

  3. 机器学习:基于朴素贝叶斯(Naive Bayes)的分类预测

    目录 一.简介和环境准备 简介: 环境: 二.实战演练 2.1使用葡萄(Wine)数据集,进行贝叶斯分类 1.数据导入 2.模型训练 3.模型预测 2.2模拟离散数据集–贝叶斯分类 1.数据导入.分析 ...

  4. 机器学习笔记——朴素贝叶斯(Naive Bayes)

    1贝叶斯算法简介 贝叶斯分类算法是统计学的一种分类方法,它是一类利用概率统计知识进行分类的算法.在许多场合,朴素贝叶斯(Naïve Bayes,NB)分类算法可以与决策树和神经网络分类算法相媲美,该算 ...

  5. 朴素贝叶斯(Naive Bayes),“Naive”在何处?

    加上条件独立假设的贝叶斯方法就是朴素贝叶斯方法(Naive Bayes). Naive的发音是"乃一污",意思是"朴素的"."幼稚的".&q ...

  6. 西瓜书+实战+吴恩达机器学习(八)监督学习之朴素贝叶斯 Naive Bayes

    文章目录 0. 前言 1. 朴素贝叶斯算法 2. 半朴素贝叶斯算法 2.1. ODE 2.2. SPODE 2.3. TAN 2.4. AODE 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔 ...

  7. 机器学习算法: 朴素贝叶斯(Naive Bayes)

    朴素贝叶斯的介绍 朴素贝叶斯算法(Naive Bayes, NB) 是应用最为广泛的分类算法之一.它是基于贝叶斯定义和特征条件独立假设的分类器方法.由于朴素贝叶斯法基于贝叶斯公式计算得到,有着坚实的数 ...

  8. 机器学习(十)分类算法之朴素贝叶斯(Naive Bayes)算法

    贝叶斯定理 首先我们来了解一下贝叶斯定理: 贝叶斯定理是用来做什么的?简单说,概率预测:某个条件下,一件事发生的概率是多大? 了解一下公式 事件B发生的条件下,事件A发生的概率为: 这里写图片描述 同 ...

  9. spark mllib 朴素贝叶斯 naive bayes

    为什么80%的码农都做不了架构师?>>>    数据源说明 第一列每行的标签,其他列为特征 运行代码如下 package spark.logisticRegressionimport ...

最新文章

  1. video 微信 标签层级过高_基于大数据的用户标签体系建设思路和应用
  2. IntelliJ IDEA 不能识别 Java 项目
  3. 【学员分享】深度学习计算机视觉,两个星期从入门到上线
  4. Linux服务器和客户端之间的数据同步(备份)
  5. Python每日一练(1):计算文件夹内各个文章中出现次数最多的单词
  6. 关于 adb shell error: no devices/emulators found 的解决方案
  7. 转载:bug的处理流程
  8. java 文件中查找指定的单词,查找指定文本文件中的单词数的Java程序
  9. Redis(一)面试总结精讲
  10. 接 嵌入式设备上的Linux系统开发
  11. error:cv_bridge---opencv和ros连接起来的桥
  12. 食谱数据库数据找不到的问题
  13. Android 杂记 - 存货盘点用的客户端
  14. 2021-07-05C#/CAD二次开发创建圆弧(4)
  15. 姓舒男孩名字简单大气,帮你解决起名的烦恼!
  16. word输入(a)一敲空格就变自动编号
  17. C++如何获取虚函数表(vtbl)的内容及虚成员函数指针存放原理
  18. 【转】加油站压力/真空阀(PV阀)的工作原理及安全注意事项
  19. 一副重现赤壁之战的神秘地图
  20. C# 3GQQ批量登录工具(QQ答复机器人)

热门文章

  1. 影响线型缩聚物分子量的因素_运城专业超高分子量聚乙烯油井内衬管生产基地...
  2. python股票涨势_stock
  3. linux配置临时IP和永久IP
  4. idea服务器怎么配置文件,Idea部署远程Docker并配置文件
  5. oracle点勾算提交吗,oracle表结构和数据导出时的一些勾选项说明
  6. 神经网络的输出层有哪些_神经网络算法—总结篇
  7. jquery ajax node,jquery ajax post json and node express
  8. Leetcode69场双周赛-第四题5931. 用邮票贴满网格图
  9. MAC显示隐藏文件和文件夹
  10. RabbitMQ简介以及应用