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的print用法示例
Feb 11 Python
Python文件读取的3种方法及路径转义
Jun 21 Python
python生成随机图形验证码详解
Nov 08 Python
Python基于回溯法解决01背包问题实例
Dec 06 Python
python 反向输出字符串的方法
Jul 16 Python
python使用tcp实现局域网内文件传输
Mar 20 Python
Python Pandas 箱线图的实现
Jul 23 Python
给大家整理了19个pythonic的编程习惯(小结)
Sep 25 Python
Django 实现Admin自动填充当前用户的示例代码
Nov 18 Python
pycharm 激活码及使用方式的详细教程
May 12 Python
如何通过python计算圆周率PI
Nov 11 Python
详解分布式系统中如何用python实现Paxos
May 18 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脚本数据库功能详解(下)
2006/10/09 PHP
php URL跳转代码 减少外链
2011/06/25 PHP
ThinkPHP之foreach标签使用概述
2014/06/30 PHP
php计算两个坐标(经度,纬度)之间距离的方法
2015/04/17 PHP
在laravel中实现ORM模型使用第二个数据库设置
2019/10/24 PHP
javascript获得CheckBoxList选中的数量
2009/10/27 Javascript
JS代码放在head和body中的区别分析
2011/12/01 Javascript
使用javascript控制cookie显示和隐藏背景图
2014/02/12 Javascript
js对文章内容进行分页示例代码
2014/03/05 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
jQuery.lazyload+masonry改良图片瀑布流代码
2014/06/20 Javascript
jQuery实现流动虚线框的方法
2015/01/29 Javascript
javascript中sort() 方法使用详解
2015/08/30 Javascript
基于jquery实现左右按钮点击的图片切换效果
2021/01/27 Javascript
JQuery fileupload插件实现文件上传功能
2016/03/18 Javascript
jQuery简单实现上下,左右滑动的方法
2016/06/01 Javascript
前端微信支付js代码
2016/07/25 Javascript
Bootstrap风格的WPF样式
2016/12/07 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
vue+ts下对axios的封装实现
2020/02/18 Javascript
基于JavaScript实现留言板功能
2020/03/16 Javascript
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
Python 功能和特点(新手必学)
2015/12/30 Python
使用python进行拆分大文件的方法
2018/12/10 Python
利用Python进行图像的加法,图像混合(附代码)
2019/07/14 Python
python二维键值数组生成转json的例子
2019/12/06 Python
Prometheus开发中间件Exporter过程详解
2020/11/30 Python
Pytorch如何切换 cpu和gpu的使用详解
2021/03/01 Python
CSS3的column-fill属性对齐列内容高度的用法详解
2016/07/01 HTML / CSS
大学生毕业自我鉴定
2013/11/06 职场文书
员工晚婚的请假条
2014/02/08 职场文书
暑期社会实践个人总结
2015/03/06 职场文书
本科毕业论文致谢怎么写
2015/05/14 职场文书
2019年公司快递收发管理制度模板
2019/11/20 职场文书
Apache Hudi集成Spark SQL操作hide表
2022/03/31 Servers
忘记Grafana不要紧2种Grafana重置admin密码方法详细步骤
2022/04/07 Servers