朴素贝叶斯算法以及案例

大家好,我是W

这次给大家带来朴素贝叶斯算法,贝叶斯分类是一类分类算法的总称,其基础都是贝叶斯定理。要理解该算法就需要先理解其背后的概率知识,我会尽量详细地给大家讲解清楚。所以今天的顺序是:贝叶斯理论和条件概率、朴素贝叶斯原理、案例 - insultingComments分类

Bayes贝叶斯理论

假设在坐标轴中存在两类点,分别对应着两个类别。接下来我们要对新加入的点进行分类,我们要怎么做?可能会联想到之前的KNN算法,这也是一个思路。但是在这里可以考虑使用贝叶斯决策:即我们可以认为新加入的点既可以属于A类,也可以属于B类但是分别对应着不同的概率。那么当别人问起这个点到底属于A还是属于B时,我们会倾向回答概率大的类别这就是贝叶斯决策理论的思想:选择具有最高概率的决策。

条件概率

p(A)

P(A) - 事件A发生的概率,比如P(抛硬币出正面) = 1/2

P(A|B)

P(A|B) - 事件B发生的情况下A发生的概率。这个就有讲头了,下图两个方格表示两个黑盒子,里面放有白色和黄色乒乓球若干,求在右桶中抽出白球的概率。那么我们就有两种算法:

  • 法1

首先,要求得右桶白球占总球数的比例,P(右桶白球数/总球数) = 1/7。然后求出右桶球数占总球数的比例,P(右桶球数/总球数) = 2/7。于是右桶中抽出白球的概率,P(抽出白球|从右桶中抽) = P(右桶白球数/总球数) / P(右桶球数/总球数) = 1/2。

  • 法2

使用贝叶斯准则求条件概率,贝叶斯准则可以帮助我们交换条件概率的条件和结果,即若一直P©、P(x)、P(x|c)那么就可以求P(c|x) = P(x|c)P© / P(x)。在本题中若已知P(从右桶中抽|已知抽中白球)、P(选中右桶概率)、P(抽中白球概率),就可以算出P(抽出白球|从右桶中抽)。

有人可能疑问,我若是能求出P(x|c)我还用怕求不出来P(c|x)?其实我们真的可以求出P(x|c)而求不出P(c|x),所以需要依靠贝叶斯转换条件和结果的特性,我会在后面的实战案例环节讲解。

朴素贝叶斯

在条件概率部分已经知道贝叶斯准则的公式,即P(c|x) = P(x|c)P© / P(x),但是在实际场景下,例如文本分类,每一个样本会存在多个特征。假设这些特征相互独立,即在统计意义上独立,则这个假设就是朴素贝叶斯分类器中的朴素的含义,朴素贝叶斯分类器还有一个假设是所有特征重要程度相同

接上一段,因为每个样本会存在许多特征,所以公式可以改写成:

P(c|(w_1,w_2,w_3,…,w_n)) = P((w_1,…,w_n)|c)P© / P(w_1,w_2,…,w_n)
,w_n表示样本的多维特征。

因为朴素贝叶斯中每个样本的每个特征相互独立,所以有:

P((w_1,…,w_n)|c) = P(w_1|c) * … * P(w_n|c)

请大家先记住以上结论,后面会用到,也会随时返回来。

案例 - insultingComments分类

项目描述: 论坛需要对用户的评论做质量监控,以确保提供给用户一个干净的论坛环境。所以需要对用户评论做分类,若用户评论内容包含负面或侮辱性内容,则为内容不当。因此建立一个二分类问题:侮辱性言乱和非侮辱性言论。

开发流程:

流程 解释
准备数据 实际场景应该是公司数据库提供,本案例假设已经得到一些评论数据,并且带有标签,以字符串存储
分析数据 对bayes算法的计算做准备工作,例如将数据集转为可计算类型
训练算法 这一步会产生一系列bayes算法参数,用于实际使用
测试数据 自己定义若干条评论测试是否符合预期

准备数据

OK,按照上面的流程,这一步准备数据我们假设已经从后台拿到处理好的数据,并且带有相应的标签,格式是字符串,写一个函数把数据返回。

def loadDataSets():"""加载数据集:return: dataMatrix,labelList"""dataMatrix = [["stop", "fuck", "you", "bitch", "garbage"],["useless", "dog", "stupid", "worthless"],["suck", "my", "dick", "bitch", "pig", "asshole"],["son", "bitch", "hoocker", "happy"],['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],]labelList = [1, 1, 1, 1, 0, 0, 0]return dataMatrix, labelList

这里直接把字符串拆成列表了,如果大家想还原更真实的场景可以考虑使用结巴分词来做。

分析数据

在这一阶段我们需要把字符串转为可以运算的类型,那么我们需要按照以下步骤做:

  • 得到trainingSet的所有字符的去重列表
  • dataMatrix转为one-hot矩阵
1’ 得到去重列表

显然该函数只需要dataMatrix矩阵就可以,无论用什么方法只需要做到去重,转换成列表就可以了。下面这个方法时我找到写法十分简洁的方法:

def buildWordsSet(dataMatrix):"""创建单词集合:param dataMatrix: 单词矩阵:return:"""# 定义一个空set,因为set本身有去重的功能wordsSet = set([])# 遍历矩阵的每一行for comment in dataMatrix:# |表示取交集wordsSet = wordsSet | set(comment)return list(wordsSet)
2’ 把dataMatrix转为one-hot

因为转为one-hot所以需要1’中的去重列表,所以传入dataMatrix和wordsSet。这样的操作是可以的,但是考虑到后期在测试阶段会存在单个列表而非矩阵转one-hot,所以我们考虑在调用函数时遍历dataMatrix,对每一行做处理。

def getOneZeroVector(wordSet, comment):"""以wordSet这个训练集词频向量为依据构建comment的词频(0,1)向量:param wordSet: 全集:param comment: 单个评论的list:return: 每个comment对应的(0,1)向量"""one_zero_vec = [0] * len(wordSet)for word in comment:if word in wordSet:one_zero_vec[wordSet.index(word)] = 1else:print(" %s 没有收录" % word)return one_zero_vec

训练算法

在这一阶段就需要通过使用bayes公式得到一些参数,为接下来的使用做准备。并且在这一阶段就是整个算法的核心步骤,我也尽量给大家讲清楚。

目前,我们有的变量是:

dataMatrix
[['stop', 'fuck', 'you', 'bitch', 'garbage'], # 1['useless', 'dog', 'stupid', 'worthless'],  # 1['suck', 'my', 'dick', 'bitch', 'pig', 'asshole'], # 1['son', 'bitch', 'hoocker', 'happy'],  # 1['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], # 0['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],# 0['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him']]# 0
labelList
[1, 1, 1, 1, 0, 0, 0]
wordSet
['son', 'mr', 'licks', 'him', 'dick',
'garbage', 'hoocker', 'useless', 'dalmation','steak', 'problems', 'to', 'help', 'my', 'cute', 'how', 'I', 'bitch', 'worthless','stupid', 'is', 'you', 'love', 'so', 'suck', 'stop', 'ate', 'pig', 'asshole', 'has',
'fuck', 'please', 'dog', 'flea', 'happy']
np.array(one_zero_matrix)

one_zero_matrix是dataMatrix转为one-hot后的矩阵。

[[0 1 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0][0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0][0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0][0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0][0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0][1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1][0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0]]

重温bayes公式

不了解的同学推荐用草稿写下来,看得清楚点,电脑的格式不好看。

P(c|x) = P(x|c)P(c) / P(x)

在朴素贝叶斯标题下我们了解了一个样本可能会有多个特征,所以我们往往用w来代替x,故

P(c|x) = P(x|c)P(c) / P(x)** = **P(c|w) = P(w|c)P(c) / P(w)

又因w包含多个特征,所以

P(c|x) = P(x|c)P(c) / P(x) =
P(c|w) = P(w|c)P(c) / P(w) =
P(c|(w_1,w_2,w_3,...,w_n)) = P((w_1,...,w_n)|c)P(c) / P(w_1,w_2,...,w_n)

又因为朴素贝叶斯中特征间相互独立,所以

P((w_1,...,w_n)|c) = P(w_1|c)P(w_2|c)....P(w_n|c)

**P(w_1|c)**表示已知该评论为侮辱性评论的情况下出现w_1词的概率是多少。

计算bayes参数代码

那么拿到one_zero_matrix又怎么用呢?

首先,我们可以去计算P(w|c)。遍历矩阵中每一个向量,若该样本向量标记为侮辱性1,则把向量每一维加到空向量中,并且计数该向量词语个数。遍历完整个矩阵后,就会得到一条好向量(标签为0的向量在各个维度上的和)和一条坏向量,还有整个trainingSet的好词数(整个训练集标签为0的评论词语个数)和坏词数。在这个基础上相除就是P(w|c)

def getBayesParams(one_zero_matrix, labelList):"""计算贝叶斯公式参数:param one_zero_matrix: (0,1)词频矩阵:param labelList: 每个评论的标签:return: log(词频/好类总词数) , log(词频/坏类总次数) , 侮辱性评论占训练集总评论概率"""# 侮辱性评论概率p_c1 = sum(labelList) / float(len(labelList))# 训练集总词数total_words_count = len(one_zero_matrix[0])# 两种单词出现频率列表p0List = np.ones(len(one_zero_matrix[0]))p1List = np.ones(len(one_zero_matrix[0]))# 计算两类词频p0num = 1.0p1num = 1.0# 遍历所有测试集评论for i in range(len(labelList)):# 若该评论是侮辱性if labelList[i] == 1:p1List += one_zero_matrix[i]p1num += sum(one_zero_matrix[i])else:p0List += one_zero_matrix[i]p0num += sum(one_zero_matrix[i])# 每个词词频列表/该类别词频 再取对数p1vec = np.log(p1List / p1num)  # 已知是侮辱性评论情况下,每个词出现的概率p0vec = np.log(p0List / p0num)  # 已知不是侮辱性评论情况下,每个词出现的概率return p1vec, p0vec, p_c1

返回的三个对象分别是P(w|坏评论)、P(w|好评论)、P(坏评论出现概率)

为什么使用np.log()

在重温贝叶斯公式这个部分我们看到,在相互独立的环境下,

P((w_1,...,w_n)|c) = P(w_1|c)P(w_2|c)....P(w_n|c)

但是,每个概率都是远小于1的浮点数,在计算机中如此多的浮点数连乘很可能会出现机器0,即小到一定地步了就没办法保留尾数。所以为了解决这种情况可以转为log函数,log运算可以把连乘转换为加法,防止了机器0的出现。

实现比较代码

按照bayes思想,选择概率大的类别。

def classifyByBayes(p1vec, p0vec, p_c1, one_zero_vector):"""使用贝叶斯参数比较得出结果:param p1vec::param p0vec::param p_c1::param one_zero_vector::return:"""# sum(one_zero_vector * p1vec) 对应元素相乘相加# p_1 = sum(one_zero_vector * p1vec) + np.log(p_c1)p_1 = sum(one_zero_vector * p1vec)# p_0 = sum(one_zero_vector * p0vec) + np.log(1.0 - p_c1)p_0 = sum(one_zero_vector * p0vec)if p_1 > p_0:return 1else:return 0

项目地址

点击进入github

朴素贝叶斯算法以及案例相关推荐

  1. 机器学习之朴素贝叶斯算法原理+Python实现

    朴素贝叶斯 1.简介 ​ 贝叶斯分类算法是统计学中的一种概率分类方法,朴素贝叶斯分类是贝叶斯分类中最简单的一种.其分类原理就是利用贝叶斯公式根据某特征的先验概率计算出其后验概率,然后选择具有最大后验概 ...

  2. [Python图像处理] 二十六.图像分类原理及基于KNN、朴素贝叶斯算法的图像分类案例

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  3. python人工智能——机器学习——分类算法-朴素贝叶斯算法对新闻进行分类案例

    朴素贝叶斯案例流程 1.加载20类新闻数据,并进行分割 2.生成文章特征词 3.朴素贝叶斯estimator流程进行预估 代码 from sklearn.datasets import fetch_2 ...

  4. 【机器学习-分类】一句话+一张图说清楚朴素贝叶斯算法(附案例+代码)

    说在前面 同一个算法本身存在各种不同的变体,即各种改进版本.一句话+一张图并不能涵盖所有情况,只是尽量用通俗的语言介绍其中经典的算法版本.希望对某算法本身不了解的人看完能迅速get到该算法在干什么:二 ...

  5. 【机器学习入门】(3) 朴素贝叶斯算法:多项式、高斯、伯努利,实例应用(心脏病预测)附python完整代码及数据集

    各位同学好,今天我和大家分享一下朴素贝叶斯算法中的三大模型.在上一篇文章中,我介绍了朴素贝叶斯算法的原理,并利用多项式模型进行了文本分类预测. 朴素贝叶斯算法 -- 原理,多项式模型文档分类预测,附p ...

  6. 【机器学习入门】(2) 朴素贝叶斯算法:原理、实例应用(文档分类预测)附python完整代码及数据集

    各位同学好,今天我向大家介绍python机器学习中的朴素贝叶斯算法.内容有:算法的基本原理:案例实战--新闻文档的分类预测. 案例简介:新闻数据有20个主题,有10万多篇文章,每篇文章对应不同的主题, ...

  7. 机器学习算法基础——朴素贝叶斯算法

    26.朴素贝叶斯算法原理 联合概率和条件概率 联合概率:包含多个条件,且所有条件同时成立的概率 记作:P(A,B) P(A,B)=P(A)P(B) 条件概率:就是事件A在另外一个事件B已经发生条件下的 ...

  8. 朴素贝叶斯算法-分类算法

    朴素贝叶斯算法-分类算法 1 概率基础 概率定义为一件事情发生的可能性 联合概率:包含多个条件,且所有条件同时成立的概率,记作P(A,B) 条件概率:事件A在另一个事件B已经发生条件下的发送概率,记作 ...

  9. 分类算法之朴素贝叶斯算法

    1. 什么是朴素贝叶斯分类方法 2. 概率基础 2.1 概率(Probability)定义 概率定义为一件事情发生的可能性 扔出一个硬币,结果头像朝上 某天是晴天 P(X) : 取值在[0, 1] 2 ...

最新文章

  1. Java学习总结:53(单对象保存父接口:Collection)
  2. CVPR 2020 Oral | 旷视提出Circle Loss,革新深度特征学习范式
  3. catia 无许可证服务器名称,win10升级2004后CATIA无法连接许可证服务器解决方案(2页)-原创力文档...
  4. python3.7.2下载-Python编程神器 v3.7.2 最新免费版
  5. 如何限制SELECT-OPTIONS的选择屏幕的OPTION
  6. Linux中exit与_exit的区别
  7. 如果再这么玩下去,中国的科研就没戏了
  8. 用php实现随机点名,使用javascript做的一个随机点名程序
  9. VPP命令行:启动配置,HTTP服务,DPDK配置
  10. react 树形菜单_react使用antd组件递归实现左侧菜单导航树
  11. 【报告分享】2019年中国首席营销官(CMO)调查白皮书.pdf(附下载链接)
  12. 整站数据下载工具:SiteSucker for mac
  13. 某生鲜平台面试题:如何保证库存在高并发的场景下是安全的?
  14. 在设计四人抢答器中灯全亮_四人智力竞赛抢答器最终版(资料4)
  15. Python 处理表格进行成绩排序的操作代码
  16. 缺氧游戏 游戏泉修改_自己用的
  17. 一级网站域名与二级域名的区别,如何注册网站一级域名
  18. RealView MDK的指定位置
  19. Facebook 登录、分享
  20. win10 下的输入法切换成繁体的问题解决方案

热门文章

  1. UMX消息和待办事宜类型之间的转换方式
  2. 局部对比度结合区域显著性红外弱小目标检测
  3. 身份证号处理 c 字符串
  4. (数据结构)树的Child表示法
  5. VNH7100BASTR资料BTS5090-2EKA驱动器特点R5F562T6DDFF规格参数
  6. 零基础PPT学习记录
  7. oracle中call用法,Oracle数据库中 call 和 exec的区别
  8. (Android/安卓)客户配置教程
  9. gis里创建要素面板怎么打开_规划用地CAD转gis文件并制作用地平衡表
  10. 书签bookmarks