统计学习方法与Python实现(三)——朴素贝叶斯法

1、定义

朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。

对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布。然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y,从而进行决策分类。

朴素贝叶斯法学习到的是生成数据的机制,属于生成模型。

设Ω为试验E的样本空间,A为E的事件,B1~Bn为Ω的一个划分,则有全概率公式:

2、学习与分类

对于训练数据集:

我们的目的是从训练集中学习到联合概率分布P(X, Y),为此先学习后验概率分布和条件概率分布。

后验概率分布,即类标签Y的概率分布,条件概率分布即在类标签Y确定的情况下输入特征向量x的分布。

从中学习后验概率分布:

从中学习条件概率分布:

条件概率分布的参数是指数级数量的,对其进行参数估计是不可能的。因此,对条件概率分布做独立性假设,认为输入特征向量x的各个分量是独立的,这也是“朴素”的含义。这样做简化了模型,但是也牺牲了分类的准确率。

条件独立性假设:

朴素贝叶斯法进行分类时,对于输入特征向量x,通过学习到的模型计算后验概率

。主要是之前学习的后验概率

和条件概率

,带入全概率公式,可得输入x的条件下,输出y取各个值的概率,并且将概率最大的y作为分类结果。

朴素贝叶斯法分类的基本公式为:

朴素贝叶斯分类器为:

分母为定值,则进一步简化可得:

3、分类方法的含义

一般的分类方法都有损失函数的概念,优化的目标也是最小化损失函数。朴素贝叶斯法直接要求将实例分到后验概率最大的类中有何含义?实际上,这也等价于期望风险即损失函数最小化。

如果对模型f(X)取0-1损失函数L(Y,f(X)),即分类正确损失L取0,分类错误L取1。则期望风险函数为:

因为每个输入特征向量x是独立的,因此只需对每个X=x的实例进行极小化。

即推导得到了后验概率最大化准则。

4、参数学习

参数学习即确定每个先验概率和条件概率,一般用极大似然估计法。

先验概率P(Y = ck)的极大似然估计是:

  条件概率

(即Y取ck时X的第j个特征取第l个值的概率)的极大似然估计是:

其中,函数I(.)表示当括号内的条件满足取1,不满足取0。

朴素贝叶斯算法为:

a、对于给定的训练数据集,计算先验概率和条件概率。

b、对于给定的实例x,计算

c、确定实例x的类

5、贝叶斯估计

极大似然估计可能会使所要估计的概率为0的情况,这时会导致计算条件概率时分母为0,使分类出现偏差。可以用贝叶斯估计来解决此问题,即在随机变量各个取值的聘书上加一个正数λ。λ取0时为极大似然估计,λ取1时为拉普拉斯平滑。贝叶斯估计下的条件概率为:

贝叶斯估计下的先验概率为:

6、Python实现

数据集选择mnist手写数字集,数据集中为0~255的整数,先读入数据并对其进行0-1二值化。并初始化数组记录条件概率和先验概率。

from tensorflow.keras.datasets importmnistimportnumpy as np

(train_data, train_label), (test_data, test_label)=\

mnist.load_data(r'E:\code\statistical_learning_method\Data_set\mnist.npz')#训练集和测试集大小

train_length = 60000test_length= 10000size= 28 * 28 #输入特征向量长度

data_kind = 10 #分为几类

choice = 2 #每个向量有几种取值

lam = 1 #贝叶斯估计中的lamda

#预处理数据

train_data =train_data[:train_length].reshape(train_length, size)#数据二值化

np.place(train_data, train_data > 0, 1)

train_label= np.array(train_label, dtype='int8')

train_label=train_label[:train_length].reshape(train_length, )

test_data=test_data[:test_length].reshape(test_length, size)

np.place(test_data, test_data> 0, 1) #数据二值化

test_label = np.array(test_label, dtype='int8')

test_label=test_label[:test_length].reshape(test_length, )#初始化数组记录条件概率和先验概率

P_con =np.zeros([data_kind, size, choice])

P_pre= np.zeros(data_kind)

然后在训练集上进行学习,计算先验概率和条件概率。

#计算先验概率

def compute_P_pre(label, P_init, lamda=1):

pre=P_initfor la inlabel:

pre[int(la)]+= 1pre+=lamdareturn pre / (label.shape[0] + pre.shape[0] *lamda)#计算条件概率

def compute_P_con(data, label, P_init, lamda=1):

con=P_init

summ=np.zeros(P_init.shape[0])for index, value inenumerate(data):for jndex, dalue inenumerate(value):

con[int(label[index]), jndex, int(dalue)]+= 1summ[int(label[index])]+= 1con+=lamda

summ+= lamda * 2

for index, value inenumerate(con):

con[index]/=summ[index]return con

最后,在测试集上进行测试。

#进行测试

defBayes_divide(pre, con, test, label):

acc=0

ans= np.full(test.shape[0], -1)

P_div=np.ones([test.shape[0], pre.shape[0]])for index, value inenumerate(test):for times inrange(pre.shape[0]):for jndex, dalue inenumerate(value):

P_div[index, times]*=con[times, jndex, int(dalue)]

P_div[index, times]*=pre[times]for index, temp inenumerate(P_div):

ans[index]=temp.argmax()if ans[index] ==label[index]:

acc+= 1

return acc /label.shape[0], ans

P_pre= compute_P_pre(train_label, P_pre, lamda=lam)

P_con= compute_P_con(train_data, train_label, P_con, lamda=lam)

acc, ans=Bayes_divide(P_pre, P_con, test_data, test_label)print('acc', acc)

lam=1时的测试结果为acc=0.8413。

更改lam的值,lam=0时,acc=0.8410;lam=2时,acc=0.8411;lam=5时,acc=0.8407;lam=10时,acc=0.8399。总的而言影响不大。

7、生成模型

因为朴素贝叶斯方法是生成模型,所以可以通过训练好的模型生成出模型学习到的特征,也就是生成模型认为最像某个数字的图像。最简单的思想就是,因为我们假设输入特征向量x的各个维度的值是独立的,所以可以输入一个初始向量,然后比较每个维度上取0或1时,模型输出的概率大小,然后将各个维度的值置为更大的概率所对应的值。代码实现如下:

from skimage importioimportmatplotlib.pyplot as plt#测试输入数据被识别为goal的概率

deftest(data0, goal, pre, con):

P_gene= 1

for index, value inenumerate(data0):

P_gene*=con[goal, index, int(value)]

P_gene*=pre[goal]returnP_gene#初始化输入为全0向量

gene =np.zeros([data_kind, size])for goals, sim inenumerate(gene):

temp=sim#遍历向量

for index inrange(sim.shape[0]):

ans1=test(temp, goals, P_pre, P_con)

temp[index]= 1ans2=test(temp, goals, P_pre, P_con)if ans1 >ans2:

temp[index]=0#画出生成的图像

for i in range(gene[:10].shape[0]):

draw=gene[i][:, np.newaxis]

draw= draw.reshape([28, 28])

plt.subplot(1, 10, i+1)

plt.axis('off')

io.imshow(draw)

plt.tight_layout()

最后的输出结果为:

参考:李航 《统计学习方法(第二版)》

python朴素贝叶斯分布对数据的要求_统计学习方法与Python实现(三)——朴素贝叶斯法...相关推荐

  1. python第七章文件和数据格式化选择题_《计算机二级Python语言程序设计考试》第7章:文件和数据格式化...

    注明:本系列课程专为全国计算机等级考试二级 Python 语言程序设计考试服务 目录 考纲考点 文件的使用: 文件打开.关闭和读写 数据组织的维度:一维数据和二维数据 一维数据的处理:表示.存储和处理 ...

  2. 缺失数据em算法python_重磅!李航《统计学习方法》Python 代码更新,适应第二版!...

    重磅!李航<统计学习方法>Python 代码更新,适应第二版! 点击上方"AI有道",选择"星标"公众号 重磅干货,第一时间送达 李航的<统计 ...

  3. 复现经典:《统计学习方法》第 4 章 朴素贝叶斯

    本文是李航老师的<统计学习方法>[1]一书的代码复现. 作者:黄海广[2] 备注:代码都可以在github[3]中下载. 我将陆续将代码发布在公众号"机器学习初学者", ...

  4. python爬网页数据用什么_初学者如何用“python爬虫”技术抓取网页数据?

    原标题:初学者如何用"python爬虫"技术抓取网页数据? 在当今社会,互联网上充斥着许多有用的数据.我们只需要耐心观察并添加一些技术手段即可获得大量有价值的数据.而这里的&quo ...

  5. 2.4 使用来自不同分布的数据,进行训练和测试-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 2.3 快速搭建你的第一个系统,并进行迭代 回到目录 2.5 不匹配数据划分的偏差和误差 使用来自不同分布的数据,进行训练和测试 (Training and Testing ...

  6. 自学python数据需要多久_零基础自学Python要多久?需要怎样的基础和准备

    被誉为"胶水语言"的Python在计算机.互联网领域还有更为广阔的用途!而且Python与C.C++.C#.Java并称为目前世界上主流的5种编程语言:在数据分析.云计算系统管理. ...

  7. python数据分析从入门到精通电子工业出版社_荐书丨Python数据分析从入门到精通...

    点击上方"程序人生",选择"置顶公众号" 第一时间关注程序猿(媛)身边的故事 采用Python 3.6版本,兼容Python 3.X等众多版本 一本书搞定IPy ...

  8. 统计学习方法读书笔记(六)-逻辑斯蒂回归与最大熵模型(迭代尺度法(IIS))

    全部笔记的汇总贴:统计学习方法读书笔记汇总贴 逻辑斯谛回归 (logistic regression )是统计学习中的经典分类方法.最大熵是概率模型学习的一个准则,将其推广到分类问题得到最大熵模型(m ...

  9. notepad运行python为啥与pycharm运行的结果不一样_零基础初学Python,需要装什么软件?...

    点击蓝字"python教程"关注我们哟! 前言 Python现在非常火,语法简单而且功能强大,很多同学都想学Python!所以小的给各位看官们准备了高价值Python学习视频教程及 ...

最新文章

  1. 2020 图算法工程师面试基础、要点
  2. vue打包后axios返回html,vue项目封装axios并访问接口
  3. PHP显示今天、今月、上月、今年的起点/终点时间戳
  4. mysql集群经常无法truncate_失败的mysql cluster配置-无法顺利转换已有数据
  5. 使用Commons Logging - Java异常处理
  6. 这个世界上不止有Mysql,还有很多ClickHouse们
  7. php 常用函数 180,php 部分常用函数
  8. 华为小米入场,能拯救乐视互联网电视挖的坑吗?
  9. android之id统一管理
  10. 大工20秋C语言在线测试,大工20秋《计算机应用基础》在线测试
  11. 图像去雾算法(一)相关研究及链接
  12. 实用干货!大数据入门的常用技术栈全在这里了
  13. 用java在画布上画心形线_Java画心形线
  14. java数据结构与算法基础(二)-排序
  15. 汉明码纠错java_汉明码纠错的基本原理及优化解决方案
  16. JavaScript的String的replace和replaceAll的差别
  17. 谈谈snprintf
  18. 【转】从链下治理到理想治理模式
  19. Linux 判断文件或文件夹是否存在
  20. 物联网开发笔记(77)- 使用Micropython开发ESP32开发板之使用MAX7219驱动控制8x8LED点阵模块(续)

热门文章

  1. 从零开始学Pytorch(十五)之数据增强
  2. [Spark]Could not locate executable null\bin\winutils.exe in the Hadoop binaries
  3. Eclipse安装最新SVN插件方法
  4. 删除归档_备份与归档的“罗生门”
  5. python牛客网编程题_一波优秀的自学编程语言网站
  6. servlet 接收request发送过来的多维数组_049 JAVA-Servlet
  7. PHP电子合同对接流程,E签宝电子合同对接实战经验
  8. Eureke服务入门就这一篇就够了
  9. origin如何绘制双y轴曲线_Origin对曲线进行多峰拟合
  10. chrome ninja 文件_ninja和gn