Python实现朴素贝叶斯分类器的方法详解


Posted in Python onJuly 04, 2018

本文实例讲述了Python实现朴素贝叶斯分类器的方法。分享给大家供大家参考,具体如下:

贝叶斯定理

贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,在概率论中具有重要地位。

先验概率分布(边缘概率)是指基于主观判断而非样本分布的概率分布,后验概率(条件概率)是根据样本分布和未知参数的先验概率分布求得的条件概率分布。

贝叶斯公式:

P(A∩B) = P(A)*P(B|A) = P(B)*P(A|B)

变形得:

P(A|B)=P(B|A)*P(A)/P(B)

其中

  • P(A)是A的先验概率或边缘概率,称作"先验"是因为它不考虑B因素。
  • P(A|B)是已知B发生后A的条件概率,也称作A的后验概率。
  • P(B|A)是已知A发生后B的条件概率,也称作B的后验概率,这里称作似然度。
  • P(B)是B的先验概率或边缘概率,这里称作标准化常量。
  • P(B|A)/P(B)称作标准似然度。

朴素贝叶斯分类(Naive Bayes)

朴素贝叶斯分类器在估计类条件概率时假设属性之间条件独立。

首先定义

  • x = {a1,a2,...}为一个样本向量,a为一个特征属性
  • div = {d1 = [l1,u1],...} 特征属性的一个划分
  • class = {y1,y2,...}样本所属的类别

算法流程:

(1) 通过样本集中类别的分布,对每个类别计算先验概率p(y[i])

(2) 计算每个类别下每个特征属性划分的频率p(a[j] in d[k] | y[i])

(3) 计算每个样本的p(x|y[i])

p(x|y[i]) = p(a[1] in d | y[i]) * p(a[2] in d | y[i]) * ...

样本的所有特征属性已知,所以特征属性所属的区间d已知。

可以通过(2)确定p(a[k] in d | y[i])的值,从而求得p(x|y[i])

(4) 由贝叶斯定理得:

p(y[i]|x) = ( p(x|y[i]) * p(y[i]) ) / p(x)

因为分母相同,只需计算分子。

p(y[i]|x)是观测样本属于分类y[i]的概率,找出最大概率对应的分类作为分类结果。

示例:

导入数据集

{a1 = 0, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
{a1 = 0, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
{a1 = 0, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
{a1 = 1, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
{a1 = 1, a2 = 0, C = 0} {a1 = 0, a2 = 0, C = 1}
{a1 = 1, a2 = 0, C = 0} {a1 = 1, a2 = 0, C = 1}
{a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 0, C = 1}
{a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 1, C = 1}
{a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 1, C = 1}
{a1 = 1, a2 = 1, C = 0} {a1 = 1, a2 = 1, C = 1}

计算类别的先验概率

P(C = 0) = 0.5
P(C = 1) = 0.5

计算每个特征属性条件概率:

P(a1 = 0 | C = 0) = 0.3
P(a1 = 1 | C = 0) = 0.7
P(a2 = 0 | C = 0) = 0.4
P(a2 = 1 | C = 0) = 0.6
P(a1 = 0 | C = 1) = 0.5
P(a1 = 1 | C = 1) = 0.5
P(a2 = 0 | C = 1) = 0.7
P(a2 = 1 | C = 1) = 0.3

测试样本:

x = { a1 = 1, a2 = 2}
p(x | C = 0) = p(a1 = 1 | C = 0) * p( 2 = 2 | C = 0) = 0.3 * 0.6 = 0.18
p(x | C = 1) = p(a1 = 1 | C = 1) * p (a2 = 2 | C = 1) = 0.5 * 0.3 = 0.15

计算P(C | x) * p(x):

P(C = 0) * p(x | C = 1) = 0.5 * 0.18 = 0.09
P(C = 1) * p(x | C = 2) = 0.5 * 0.15 = 0.075

所以认为测试样本属于类型C1

Python实现

朴素贝叶斯分类器的训练过程为计算(1),(2)中的概率表,应用过程为计算(3),(4)并寻找最大值。

还是使用原来的接口进行类封装:

from numpy import *
class NaiveBayesClassifier(object):
  def __init__(self):
    self.dataMat = list()
    self.labelMat = list()
    self.pLabel1 = 0
    self.p0Vec = list()
    self.p1Vec = list()
  def loadDataSet(self,filename):
    fr = open(filename)
    for line in fr.readlines():
      lineArr = line.strip().split()
      dataLine = list()
      for i in lineArr:
        dataLine.append(float(i))
      label = dataLine.pop() # pop the last column referring to label
      self.dataMat.append(dataLine)
      self.labelMat.append(int(label))
  def train(self):
    dataNum = len(self.dataMat)
    featureNum = len(self.dataMat[0])
    self.pLabel1 = sum(self.labelMat)/float(dataNum)
    p0Num = zeros(featureNum)
    p1Num = zeros(featureNum)
    p0Denom = 1.0
    p1Denom = 1.0
    for i in range(dataNum):
      if self.labelMat[i] == 1:
        p1Num += self.dataMat[i]
        p1Denom += sum(self.dataMat[i])
      else:
        p0Num += self.dataMat[i]
        p0Denom += sum(self.dataMat[i])
    self.p0Vec = p0Num/p0Denom
    self.p1Vec = p1Num/p1Denom
  def classify(self, data):
    p1 = reduce(lambda x, y: x * y, data * self.p1Vec) * self.pLabel1
    p0 = reduce(lambda x, y: x * y, data * self.p0Vec) * (1.0 - self.pLabel1)
    if p1 > p0:
      return 1
    else:
      return 0
  def test(self):
    self.loadDataSet('testNB.txt')
    self.train()
    print(self.classify([1, 2]))
if __name__ == '__main__':
  NB = NaiveBayesClassifier()
  NB.test()

Matlab

Matlab的标准工具箱提供了对朴素贝叶斯分类器的支持:

trainData = [0 1; -1 0; 2 2; 3 3; -2 -1;-4.5 -4; 2 -1; -1 -3];
group = [1 1 -1 -1 1 1 -1 -1]';
model = fitcnb(trainData, group)
testData = [5 2;3 1;-4 -3];
predict(model, testData)

fitcnb用来训练模型,predict用来预测。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python之模拟鼠标键盘动作具体实现
Dec 30 Python
在Docker上开始部署Python应用的教程
Apr 17 Python
浅谈利用numpy对矩阵进行归一化处理的方法
Jul 11 Python
python 图片去噪的方法示例
Jul 09 Python
python子线程退出及线程退出控制的代码
Oct 16 Python
使用PyTorch实现MNIST手写体识别代码
Jan 18 Python
Python tkinter模版代码实例
Feb 05 Python
Python异常继承关系和自定义异常实现代码实例
Feb 20 Python
Python3爬虫中Selenium的用法详解
Jul 10 Python
Python虚拟环境virtualenv创建及使用过程图解
Dec 08 Python
pip 20.3 新版本发布!即将抛弃 Python 2.x(推荐)
Dec 16 Python
Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)
Jan 29 Python
如何优雅地改进Django中的模板碎片缓存详解
Jul 04 #Python
Django框架多表查询实例分析
Jul 04 #Python
python 借助numpy保存数据为csv格式的实现方法
Jul 04 #Python
Python将一个CSV文件里的数据追加到另一个CSV文件的方法
Jul 04 #Python
python中csv文件的若干读写方法小结
Jul 04 #Python
Python画柱状统计图操作示例【基于matplotlib库】
Jul 04 #Python
pandas将numpy数组写入到csv的实例
Jul 04 #Python
You might like
菜鸟学PHP之Smarty入门
2007/01/04 PHP
php下过滤HTML代码的函数
2007/12/10 PHP
PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
2015/12/24 PHP
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
ThinkPHP5框架实现简单的批量查询功能示例
2018/06/07 PHP
php探针不显示内存解决方法
2019/09/17 PHP
javascript 页面只自动刷新一次
2009/07/10 Javascript
javascript 函数调用规则
2009/08/26 Javascript
鼠标事件延时切换插件
2011/03/12 Javascript
jQuery代码优化 选择符篇
2011/11/01 Javascript
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
BootStrap栅格系统、表单样式与按钮样式源码解析
2017/01/20 Javascript
微信小程序侧边栏滑动特效(左右滑动)
2017/01/23 Javascript
webpack打包并将文件加载到指定的位置方法
2018/02/22 Javascript
vue-cli项目根据线上环境分别打出测试包和生产包
2018/05/23 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
2018/09/07 Javascript
解决layui的radio属性或别的属性没显示出来的问题
2019/09/26 Javascript
vue实现在线学生录入系统
2020/05/30 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
python 参数列表中的self 显式不等于冗余
2008/12/01 Python
Python实现建立SSH连接的方法
2015/06/03 Python
Python关于__name__属性的含义和作用详解
2020/02/19 Python
Python xlrd模块导入过程及常用操作
2020/06/10 Python
Ray-Ban雷朋美国官网:全球领先的太阳眼镜品牌
2016/07/20 全球购物
WebSphere面试题:在WebSphere里面如何部署一个应用
2015/08/02 面试题
大学生自荐信
2013/12/11 职场文书
自我评价格式
2014/01/06 职场文书
加工操作管理制度
2014/01/19 职场文书
工程师岗位职责规定
2014/02/26 职场文书
民主生活会意见
2015/06/05 职场文书
2016高考感言
2015/08/01 职场文书
小程序教您怎样你零成本推广获取数万用户的方法
2019/07/30 职场文书
如何在pycharm中快捷安装pip命令(如pygame)
2021/05/31 Python
漫画《催眠麦克风-Dawn Of Divisions》第二卷PV公开
2022/04/05 日漫