徒手实现一个贝叶斯分类器

  • 引子
  • 代码
  • 小结

引子

朴素贝叶斯分类器顾名思义是以贝叶斯公式为基础的分类器,其将后验概率转换为先验概率和不同类的条件概率的乘积,再通过比较不同的类别下该乘积的大小实现分类。不同于其他的分类器,朴素贝叶斯分类器严格意义上没有训练过程,只需计算相关概率即可。贝叶斯分类器比较适合对自然语言分类的模型,下面以对英文评文本类为例,详细描述如何实现一个贝叶斯分类器。

代码

首先引入语料库,其内容为英文网站评论,如果需要处理中文,还需要对中文进行分词,获得单词列表。

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”表示负面评价。在实际运用中,睡着语料库的丰富,还可以进一步细化分类标准,例如正面评价分为5级,负面评价也分为5级。
由于计算机无法直接对文本进行处理,首先需要对文本进行编码,这里我们采用简单的词袋模型,即建立一个单词表,将所有在语料库中出现的单词包含其中。具体实现方法可以采用python中的集合数据类型,集合中不能包含重复元素,具有自动去重功能。

dataSet = postingList
vocabSet = set([])   #初始化一个空集合
for document in dataSet:   # | 表示集合的并操作,集合中不能包含重复元素,并集操作时会自动去除两个集合中相同的元素vocabSet = vocabSet | set(document)
vocabSet = list(vocabSet)    #list的操作比集合set更方便 

为了便于计算机进行处理,需要对训练样本进行编码。在已获得单词列表的基础上,将每一条训练样本转换成固定长度的特征向量,其长度等于单词列表的长度。

def bagOfWords2VecMN(vocabList, inputSet):    #特征向量的长度等于词汇表的长度    returnVec = [0]*len(vocabList)    for word in inputSet:        if word in vocabList:            #出现一次相对应位置计数加一            returnVec[vocabList.index(word)] += 1return returnVec#将数据集转换为词袋模型下的特征向量,编码
trainMat = []
for postinDoc in postingList:   res = bagOfWords2VecMN(vocabSet,postinDoc)    trainMat.append(res)
#将list转换为数组,便于训练
trainMatrix = np.array(trainMat)
trainCategory = np.array(classVec)
print(trainMatrix)

通过以上操作,将训练样本转换为如下形式,其中特征向量长度为词汇表长度,每个数字对应词汇表中每个单词的出现次数。

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

完成上述步骤后,即可计算各个概率值。首先求解先验概率。对于离散变量,可以将先验概率的求解简化为频率值的统计。

numTrainDocs = len(trainMatrix)     #样本数量
numWords = len(trainMatrix[0])     #样本特征数量
pC1 = sum(trainCategory) / float(numTrainDocs)    #P(1)的比例,即先验概率

接下来需要做的是求解每个类别下的条件概率。针对C1这个类别,需要求出p(F1|C1)p(F2|C1)…p(F32|C1)这32个值,特征对应条件概率则等于该单词出现次数/给类别下出现单词的总数。如果某些类别中,某些单词的出现次数为0,会导致连乘结果直接为0。此外,由于p(F1|C1)p(F2|C1)…p(F32|C1)中每一个概率值都可能较小,连乘之后可能导致计算机下溢。解决办法是将单词列表和每个类别单词总数分别初始化为1和2以及对概率连乘值取ln,避免出现0值,并将概率值控制在一定范围,同时还将连乘运算转换为连加,避免出现过小值。

#获取不同类别的单词总数
numWordC0 = 2    #单词总数初始化为2,避免极小值
numWordC1 = 2
for i in range(numTrainDocs):if trainCategory[i] == 0:for num in trainMatrix[i]:            numWordC0 += numelse:for num in trainMatrix[i]:numWordC1 += num#获取不同类别条件下,每次单词出现的次数
numWordFsC0 = np.ones(numWords)    #单词出现次数初始化为1,避免出现0值
numWordFsC1 = np.ones(numWords)
for j in range(numTrainDocs):    for k in range(numWords):        if trainCategory[j] == 0:numWordFsC0[k] += trainMatrix[j][k]else:            numWordFsC1[k] += trainMatrix[j][k]#计算每个单词不同类的条件概率值
psOfFsC0 = numWordFsC0/numWordC0
psOfFsC1 = numWordFsC1/numWordC1

获得了先验概率和条件概率之后,我们就可以对测试目标进行分类,分类思路也很简单,将测试目标中所包含单词的不同类的条件概率的自然对数值进行累加,再与不同类的先验概率的对数值相加,较大的一类即分类结果。

testWords = ['stupid','garbage']
testValueC0 = 0
testValueC1 = 0
# 寻找测试目标中每个单词所对应的条件概率值,取对数并累加
for  word in testWords:testValueC0 += math.log(psOfFsC0[vocabSet.index(word)])testValueC1 += math.log(psOfFsC1[vocabSet.index(word)])
# 与类对应的先验概率值累加
testValueC0 += math.log(1-pC1)
testValueC1 += math.log(pC1)print('C0: ',testValueC0)
print('C1: ',testValueC1)
# 对值进行比较,较大者则是所属的类
if(testValueC0 > testValueC1):print("belone to C0")
else:print("belone to C1")

打印结果如下:

C0:  -7.20934025660291
C1:  -4.702750514326955
belone to C1

其中C1值明显大于C0值,故判断该测试目标属于C1类。同时我们可以通过常识判断’stupid’,'garbage’明显属于负面评价,与测试结果相同。
若将测试目标改为明显的正面评价:[‘love’,‘my’,‘dalmation’],运行结果如下。

C0:  -7.694848072384611
C1:  -9.826714493730215
belone to C0

打印结果显示C0值明显大于C1值,属于C0类,与我们的常识判断相同。

小结

朴素贝叶斯分类器原理清晰,结果简单,效果明显,能够有效的实现自然语言处理分类。后续将探索在更大的语料库基础上、采用不同的词袋模型的朴素贝叶斯分类的有效性、准确性。

朴素贝叶斯分类器的python实现相关推荐

  1. 朴素贝叶斯分类器python_朴素贝叶斯分类器及Python实现

    贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,在概率论中具有重要地位. 先验概率分布(边缘概率)是指基于主观判断而非样本分布的概率分布,后验概率(条件概率)是根据 ...

  2. 贝叶斯公式/朴素贝叶斯分类器及python自实现

    本文从贝叶斯与频率概率的对比入手理解贝叶斯决策的思维方式.通过两个实例理解贝叶斯的思想与流程,然后梳理了朴素贝叶斯分类器的算法流程,最后从零开始实现了朴素分类器的算法. 文章目录 1.起源.提出与贝叶 ...

  3. 机器学习(十一)-Naïve Bayes Classifier朴素贝叶斯分类器及Python实现

    原创不易,转载前请注明博主的链接地址:Blessy_Zhu https://blog.csdn.net/weixin_42555080 本次代码的环境: 运行平台: Windows Python版本: ...

  4. 贝叶斯篇:贝叶斯的概率推到,朴素贝叶斯分类器及Python实现

    在了解贝叶算法前:要有一定的概率与数理统计基础以及注意事项 ####条件概率 首先,理解这两个公式的前提是理解条件概率,因此先复习条件概率. P(A∣B)=P(AB)P(B)P(A|B) ={ P(A ...

  5. 朴素贝叶斯python实现预测_Python实现朴素贝叶斯分类器的方法详解

    本文实例讲述了Python实现朴素贝叶斯分类器的方法.分享给大家供大家参考,具体如下: 贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,在概率论中具有重要地位. 先 ...

  6. (数据科学学习手札30)朴素贝叶斯分类器的原理详解Python与R实现

    一.简介 要介绍朴素贝叶斯(naive bayes)分类器,就不得不先介绍贝叶斯决策论的相关理论: 贝叶斯决策论(bayesian decision theory)是概率框架下实施决策的基本方法.对分 ...

  7. python数据挖掘课程】二十一.朴素贝叶斯分类器详解及中文文本舆情分析

    #2018-04-06 13:52:30 April Friday the 14 week, the 096 day SZ SSMR python数据挖掘课程]二十一.朴素贝叶斯分类器详解及中文文本舆 ...

  8. [转载] 朴素贝叶斯python实现预测_Python实现朴素贝叶斯分类器的方法详解

    参考链接: Python朴素贝叶斯分类器 本文实例讲述了Python实现朴素贝叶斯分类器的方法.分享给大家供大家参考,具体如下: 贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进 ...

  9. 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_第十章:利用Python实现朴素贝叶斯模型

    免责声明:本文是通过网络收集并结合自身学习等途径合法获取,仅作为学习交流使用,其版权归出版社或者原创作者所有,并不对涉及的版权问题负责.若原创作者或者出版社认为侵权,请联系及时联系,我将立即删除文章, ...

最新文章

  1. python中复合条件_如何用Python选取复合条件的坐标组成新的列表?
  2. span 标记 width 设置
  3. Delphi中DLL或Package窗体载入与显示
  4. xgboost相比传统gbdt有何不同?xgboost为什么快?xgboost如何支持并行?
  5. sql2005数据导入出错问题
  6. Win10 安装 MongoDB 3.6.5 失败的问题及解决方法
  7. android+模拟器+ram,Android模拟器RAM修改方法 - 尤其是3.0
  8. 批量导数据之利器-load data[2016-07-11]
  9. php if require,php – 验证规则required_if与其他条件(Laravel 5.4)
  10. 【精品】Deepsort文章深度解析
  11. 《我的互联网方法论》读书笔记
  12. 服务器温度检测软件_科技产品—整机柜服务器—产品简介
  13. es6 模板字变量和字符串占位符
  14. typeof的用法 typeof的返回值是一个字符串 返回的字符串类别
  15. 天弘基金:中国的BlackRock?
  16. 搭建最简单的Drool框架
  17. win7无法打开计算机共享文件夹,win7无法共享文件夹 共享文件设置不了共享怎么办?...
  18. java:编写一个程序完成:完成在银行的存款和取款操作。在定义银行类时,若取款数大于余额则作为异常处理。
  19. 计算机网络课程设计组建大型网吧局域网,计算机网络课程设计报告—组建大型网吧局域网.doc...
  20. 制作轮播图经验分享——element ui走马灯的使用(附源码,效果截图)

热门文章

  1. python网络编程项目_python网络编程(1):客户端与网络编程简介
  2. InceptionNet V3整理总结
  3. python代码规范准则_Python编码规范
  4. 服务器安装三节点RabbitMQ集群(2)
  5. [Unity] AnimationEvent 的 receiver 需要继承 Mono
  6. 简约自适应APP下载页简单源码
  7. api有哪些 javasocket_基于java的socket编程及API解析
  8. c字符串分割成数组_excel这个复杂数组公式怎么读?
  9. python安装方法及运行_Python下载及其安装步骤
  10. 总裁导航V2.5.0-秒收录网站