文章目录

  • 一、实验要求
    • (1)实验目的
    • (2)数据集简介
    • (3)实验内容
    • (4)评价指标
  • 二、数据集的划分
  • 三、朴素贝叶斯
    • (1)朴素贝叶斯原理
    • (2)拉普拉斯修正
    • (3)函数变量解析
    • (4)代码如下
    • (5)结果
  • 四、AODE算法
    • (1)AODE算法原理
  • 五、结果
    • (1)acc结果对比
    • (2)结果分析
  • 参考

一、实验要求

(1)实验目的

  • 1、掌握朴素贝叶斯分类器(Naïve Bayes Classifier, NBC)。
  • 2、掌握AODE(Averaged One-Dependent Estimator)分类器

(2)数据集简介

(3)实验内容

  • 1、编写程序实现朴素贝叶斯分类器设计。
  • 2、编写程序实现AODE 分类器设计。

(4)评价指标

  • 本次实验主要利用Acc 指标对聚类结果进行评价,值越大表明分类效果越好。

二、数据集的划分

  • 将数据集8:2划分为训练集和测试集
  • dataset_parse.py
import osimport numpy as np
from scipy.io import loadmat
from sklearn.model_selection import train_test_split
np.set_printoptions(threshold=np.inf)# 数据准备
minist_path = r".\datasets\MNIST.mat"
lung_path = r".\datasets\lung.mat"
yale_path = r".\datasets\Yale.mat"# 存储路径
PATH_MINIST = './data/minist/'
PATH_LUNG = './data/lung/'
PATH_YALE = './data/yale/'# 加载数据
def create_data(path):data = loadmat(path)data_x = data["X"]data_y = data["Y"][:, 0]data_y -= 1Data = np.array(data_x)Label = np.array(data_y)return Data, Labeldef save_data(path, save_path):X, y = create_data(path)train_data, test_data, train_label, test_label = train_test_split(X, y, test_size=0.2, random_state=233)if not os.path.exists(save_path):os.makedirs(save_path)np.savetxt(save_path + 'train_data.txt', train_data)np.savetxt(save_path + 'train_label.txt', train_label)np.savetxt(save_path + 'test_data.txt', test_data)np.savetxt(save_path + 'test_label.txt', test_label)if __name__ == '__main__':save_data(yale_path, PATH_YALE)save_data(lung_path, PATH_LUNG)save_data(minist_path, PATH_MINIST)print('完成')

三、朴素贝叶斯

(1)朴素贝叶斯原理

P(类别∣特征1,特征2,...)=P(特征1,特征2,...∣类别)∗P(类别)P(特征1,特征2...)=P(特征1∣类别)∗P(特征2∣类别)∗...P(特征1)∗P(特征1)∗...P(类别|特征1,特征2,...) = \frac{P(特征1,特征2,...|类别) * P(类别)}{P(特征1,特征2...)}=\frac{P(特征1|类别)*P(特征2|类别)*...}{P(特征1)*P(特征1)*...}P(类别∣特征1,特征2,...)=P(特征1,特征2...)P(特征1,特征2,...∣类别)∗P(类别)​=P(特征1)∗P(特征1)∗...P(特征1∣类别)∗P(特征2∣类别)∗...​

  • 朴素贝叶斯的基本思想是假设所有属性都是相互独立的情况下,其中:

    1. 类别为将要识别分类的数据集的标签类别数,特征为分类数据的特征向量。
    2. P(特征n∣类别)=P(特征n,类别)P(类别)P(特征n|类别) = \frac{P(特征n,类别)}{P(类别)}P(特征n∣类别)=P(类别)P(特征n,类别)​ : 在该类别发生的情况下,是所求的特征的概率 。比如类别0的情形下,类别0和特征同时满足的概率。
    3. P(类别)P(类别)P(类别) : 每种类别在标签集中的比例,即每种标签的概率。
    4. P(特征1)+P(特征2)+...P(特征1)+P(特征2)+...P(特征1)+P(特征2)+... : 即每一个特征发生的概率,求和。
  • 因为对于一个样本来说,P(特征1)∗P(特征1)∗...P(特征1)*P(特征1)*...P(特征1)∗P(特征1)∗...一样,分母一样,只要比较分子就好了。所以只要计算条件概率p(xk|y=j)和p(y= j)的先验概率,不需要计算P(特征1)∗P(特征1)∗...P(特征1)*P(特征1)*...P(特征1)∗P(特征1)∗...。
  • 由于最后要比较每个样本在m类标签各自的概率,然后取其中最大的,而且要计算P(特征1,特征2,...∣类别)∗P(类别)P(特征1,特征2,...|类别) * P(类别)P(特征1,特征2,...∣类别)∗P(类别),不妨对其各自取对数,将其结果相加,比大小就可。

(2)拉普拉斯修正

  • 根据训练集,算条件概率P(xk|y=j) 和先验概率 P(y=j),由于这两种概率可能会为0,后面无法计算,因此一定要进行Laplace平滑,代码就一句话,分子+1,分母+种类数。
    P(类别m)=D(类别m)+1D+NP(类别m) = \frac{ D(类别m) + 1}{D+N}P(类别m)=D+ND(类别m)+1​
  • 其中D(类别m)为类别为m的数目,D为标签总数,N为标签类别数
    P(特征n∣类别m)=D(特征n,类别m)+1D(类别m)+NnP(特征n|类别m) = \frac{ D(特征n,类别m) + 1}{D(类别m)+N_{n}}P(特征n∣类别m)=D(类别m)+Nn​D(特征n,类别m)+1​
  • 其中D(类别m)为类别为m的数目,D(特征n,类别m)为特征n且为类别m的数目维数为m∗nm*nm∗n,NnN_{n}Nn​
    为第n个特征数量,即一共有多上个不同值的特征,如果是minist数据集,数据集有784维,则有必要对其二值化,变为0和1,这样NnN_{n}Nn​的值就为2,便于简化计算。

(3)函数变量解析

  • P(y=j):P(类别)P(y=j):P(类别)P(y=j):P(类别)
  • P(xk∣y=j):P(类别∣特征)P(x_{k}|y=j):P(类别|特征)P(xk​∣y=j):P(类别∣特征)
  • P(y=j∣xk):P(特征∣类别)P(y=j|x_{k}) : P(特征|类别)P(y=j∣xk​):P(特征∣类别)
  • num::2400,特征的数目
  • dimsnum:784,特征的维数
  • labelnum:10,标签类别数
  • pyj:1x10的零向量,代表P(y=j):P(类别)P(y=j):P(类别)P(y=j):P(类别)
  • pyjk1:10x784的零向量,代表P(y=j∣xk):P(特征∣类别)P(y=j|x_{k}) : P(特征|类别)P(y=j∣xk​):P(特征∣类别)
  • b=np.argmax(a)#取出a中元素最大值所对应的索引(索引值默认从0开始)
  • b=np.argmax(a, axis=0)#对二维矩阵来讲a[0][1]会有两个索引方向,第一个方向为a[0],默认按列方向搜索最大值
  • xk=0时,概率为1 - pyjxk1 ,xk=1时,概率为pyjxk1
  • 坑:由于yale数据集只有203个,但是有15维,在程序中使用for j in range(1+np.max(test_label)):来做循环,而不是for j in range(labelnum),由于样本量太少,导致在测试集里面没有某一类的样本,循环次数少了一次,导致精确度一直只有0.12。

(4)代码如下

  • naive_bayes.py
import numpy as npfrom data_handle import load_data, PATH_MINIST, PATH_LUNG, PATH_YALEnp.set_printoptions(threshold=np.inf)# p(类别|特征) = p(特征|类别)*p(类别)/p(特征)def normalize(data):  ##将图片像素二值化m, n = np.array(data).shapeh = (np.max(data) - np.min(data)) / 2for i in range(m):for j in range(n):if data[i, j] > h:data[i, j] = 1else:data[i, j] = 0return datadef CalProb(train_data, train_label):# p(y=j):p(类别)  P(xk|y=j):p(特征|类别)# 根据训练集 算条件概率P(xk|y=j) 和先验概率 P(y=j) 注意这两种概率可能会为0 后面无法计算 因此一定要进行Laplace平滑 参见李航P51# num: 2400, dimsnum: 784num, dimsnum = train_data.shape# labelnum: 标签类别数labelnum = len(set(train_label))# pyj:1x10的零向量pyj = np.zeros(labelnum)# pyjk1:10x784的零向量pyjk1 = np.zeros((labelnum, dimsnum))# num: 2400for i in range(num):# 计算出每种标签的个数 ---> p(y=j):p(类别)label = train_label[i]# 需要laplace平滑 这里是真实个数pyj[label] = pyj[label] + 1# dimsnum: 784for j in range(dimsnum):# 因为会出现条件概率为0的情况 log无法计算 需要laplace平滑  ##算 Pj k = 1# 此处计算的是所有label为1的数的个数pyjk1[label][j] += train_data[i][j]# print('pyj个数:', pyj)# 条件概率 需要Laplace平滑 分母要加上xk的种类数 这里只能取0 1像素# P y = j && xk = 1的概率  经验主义用频率去估计概率# 此时pyj为10种类别各自的数目# ni 为特征n的标签数pyjk1 = (pyjk1.T + 1) / (pyj + 2)# P y = j 的概率 先验概率 需要 Laplace平滑 分母要加上y的标签种类数pyj = (pyj + 1) / (num + labelnum)# pk1, #, pyjk1return pyj, pyjk1def CalTestProb_xk_yj(xk, pyjxk1):  # 计算条件概率 P(xk|y=j)的概率的log# xk=0时,概率为1 - pyjxk1 ,xk=1时,概率为pyjxk1return xk * np.log(pyjxk1) + (1 - xk) * np.log(1 - pyjxk1)# test  这块计算 应该可以优化
def test(test_data, test_label, pyjk1, pyj):  # 测试# num : 600 , dimsnum : 784num, dimsnum = test_data.shapelabelnum = len(set(test_label))acc = 0for i in range(num):testdata = test_data[i]# 第i个样本属于j类的概率p_yj_xi = np.log(pyj)# 计算xi 属于 第j个类别的概率for j in range(1+np.max(test_label)):for k in range(dimsnum):xk = testdata[k]  # x^i的第j个像素 或者说是 维度# print(pyjk1[j][k])p_yj_xi[j] += CalTestProb_xk_yj(xk, pyjk1[j][k])# p_yj_xi# np.argmax : 取出a中元素最大值所对应的索引,此时最大值位6,其对应的位置索引值为4,(索引值默认从0开始)p_y_xi = np.argmax(p_yj_xi)acc += (p_y_xi == test_label[i])# print('real is: ', test_label[i], '  predict is: ', p_y_xi)print('Test accuracy is: ', acc / num)def main(path):train_data, test_data, train_label, test_label = load_data(path)train_data = normalize(train_data)test_data = normalize(test_data)pyj, pyjk1 = CalProb(train_data, train_label)test(test_data, test_label, pyjk1.T, pyj)if __name__ == "__main__":print('minist:')main(PATH_MINIST)print('---------')print('lung')main(PATH_LUNG)print('---------')print('yale')main(PATH_YALE)

(5)结果

minist:
Test accuracy is:  0.8266666666666667
---------
lung
Test accuracy is:  0.926829268292683
---------
yale
Test accuracy is:  0.42424242424242425

四、AODE算法

(1)AODE算法原理

  • 由于属性之间是相互独立的假设太强在现实生活中很难满足,故不妨对独立性条件进行放松—半朴素贝叶斯分类器,适当考虑一部分属性间的相互依赖信息,最常用的是独依赖,即每个属性最多依赖一个其他属性。
  • AODE是一种基于集成学习机制、更为强大的独依赖分类器,其相关的计算公式如下:
    P(类别m,特征i)=D(类别m,特征i)+1D+N∗NiP(类别m,特征i) = \frac{ D(类别m,特征i) + 1}{D+N*N_{i}}P(类别m,特征i)=D+N∗Ni​D(类别m,特征i)+1​
  • 其中D(类别m,特征i)为类别为m且在第i个特征上取值为 特征i 的数目,D为标签总数,N为标签类别数,NiN_{i}Ni​为第i个特征可能的取值数

P(特征j∣类别m,特征i)=D(特征j,特征i,类别m)+1D(类别m,特征i)+NjP(特征j|类别m,特征i) = \frac{ D(特征j,特征i,类别m) + 1}{D(类别m,特征i)+N_{j}}P(特征j∣类别m,特征i)=D(类别m,特征i)+Nj​D(特征j,特征i,类别m)+1​

  • 其中D(特征j,特征i,类别m)为类别为m且在第i和第j个属性上取值分别为特征i和特征j的数目,D(类别m,特征i)为在类别m上,且取值为特征i的数目,NjN_{j}Nj​为第j个特征可能取值的个数。

五、结果

(1)acc结果对比

数据/方法 minist lung yale
bayes 0.826 0.926 0.424

(2)结果分析

  • 通过实验可以发现由于lung数据集的数据量最大,标签类别只有5,因此每一类标签的训练数据集较大,因此结果较高,可以到百分之九十,yale数据量小,标签类别为15,因此每一类标签的训练数据集较小,结果也相对较差。可以通过优化模型,或者增加数据记得方式来提高精确度。
  • 在本次实验中,贝叶斯方法在lung数据集上效果最好,虽然比cnn要差了一些,但是在没有涉及神经网络的领域,精度已经较高了。

参考

神奇的拉普拉斯平滑(Laplacian Smoothing)及其在正则化上的应用~
谈谈自己对正则化的一些理解~
拉普拉斯修正的朴素贝叶斯分类器及AODE分类器
Python 机器学习_基于朴素贝叶斯分类的MNIST手写数字识别 - 本文的代码原型来源
详解朴素贝叶斯分类算法 - 用男生的特征来决定女生嫁不嫁,讲的生动有趣
贝叶斯分类器(一):朴素贝叶斯分类器与半朴素贝叶斯分类器 - 讲了很多贝叶斯相关原理

朴素贝叶斯和AODE算法详解相关推荐

  1. 基于朴素贝叶斯的垃圾分类算法(Python实现)

    有代码和数据集的 https://blog.csdn.net/weixin_33734785/article/details/91428991 附有git库代码的 https://www.cnblog ...

  2. ML之NB:朴素贝叶斯Naive Bayesian算法的简介、应用、经典案例之详细攻略

    ML之NB:朴素贝叶斯Naive Bayesian算法的简介.应用.经典案例之详细攻略 目录 朴素贝叶斯Naive Bayesian算法的简介 1.朴素贝叶斯计算流程表述 2.朴素贝叶斯的优缺点 2. ...

  3. 【AI数学原理】概率机器学习(四):半朴素贝叶斯之TAN算法实例

    概率机器学习的系列博文已经写到第四篇了,依然关注者乏.虽说来只是自己的学习记录,不过这样下去显得自己贡献值比较低下.于是今天换一种模式来写博文--结合代码实现. 欢迎各位指点交流~ 预备知识: 1.朴 ...

  4. 机器学习(十)分类算法之朴素贝叶斯(Naive Bayes)算法

    贝叶斯定理 首先我们来了解一下贝叶斯定理: 贝叶斯定理是用来做什么的?简单说,概率预测:某个条件下,一件事发生的概率是多大? 了解一下公式 事件B发生的条件下,事件A发生的概率为: 这里写图片描述 同 ...

  5. 贝叶斯实例中风预测详解--python

    贝叶斯中风预测详解--python 1. 内容描述 1.1 字段描述 1.2 Exploratory Data Analysis探索性数据分析 1.2.1数据整体信息以及统计特征 1.2.2 id 1 ...

  6. 贝叶斯网络的D-separation详解和Python代码实现

    D分离(D-Separation)又被称作有向分离,是一种用来判断变量是否条件独立的图形化方法.相比于非图形化方法,D-Separation更加直观且计算简单.对于一个DAG(有向无环图),D-Sep ...

  7. 伯努利朴素贝叶斯【机器学习算法一朴素贝叶斯2】

    伯努利朴素贝叶斯方法适合于伯努利分布(即二项分布或0-1分布)的数据集. import numpy as np from sklearn.naive_bayes import BernoulliNB ...

  8. 逻辑斯蒂回归算法详解

    逻辑斯蒂回归算法可用于分类问题,其本质是在线性回归的算法上用sigmoid函数进行模型变换,使得目标值介于0-1之间.本文用于对逻辑斯蒂回归算法(Logistics Regression)进行详细讲述 ...

  9. 朴素贝叶斯详解及中文舆情分析(附代码实践)

    作者|杨秀璋  整理|AI科技大本营 本文主要讲述朴素贝叶斯分类算法并实现中文数据集的舆情分析案例,希望这篇文章对大家有所帮助,提供些思路.内容包括: 1.朴素贝叶斯数学原理知识 2.naive_ba ...

最新文章

  1. 庆祝我在博客园安家了
  2. 神策数据王灼洲 徐缓:ID-Mapping 用户打通那些事儿
  3. CentOS下安装semanage
  4. UVA - 400:Unix ls
  5. 商业认知,你每天出门看天气吗?
  6. html模板里处理数组,HTML模板 - 散列数组
  7. java 动态代理 jdk为何比cglib效率低 原理总结
  8. 人机工程学座椅设计_人体工程学与座椅设计.ppt
  9. 海马汽车经销商管理系统技术解析(四)保养管理
  10. mac 教程 终端设置代理
  11. SKU 和 SPU 有什么区别?
  12. mysql数据库报 请在mysql配置文件修sql-mode为NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
  13. android振动器(Vibrator)
  14. “TECH数字中国 2020技术年会”盛大开幕!产学研生态共议“新基建 新金融 新安全”
  15. 机器人唱歌bgm_Soul app里面机器人匹配的那首bgm是什么呀?好好听!!!求玩过soul的大神告知!!...
  16. JS如何获取指定元素下的子元素的值
  17. 服务器系统进不了路由器,Win7输入192.168.0.1打不开路由器管理界面的解决方法
  18. LitePal数据库的基本操作
  19. STM32F404的ADC之DMA的单通道
  20. 使用scrapy爬取指定内容相关的百度图片

热门文章

  1. 项目实战-信用卡识别
  2. SharePoint 2013 How to create a Power View Map
  3. 华为鸿蒙系统智能家居产品大全,搭载华为鸿蒙OS智能家居产品已上市
  4. 深度技术 GHOSTXPSP3 快速装机专业版 V2011.04
  5. 阿里云视频云技术专家 LVS 演讲全文:《“云端一体”的智能媒体生产制作演进之路》
  6. js获取当前的年月日时分秒
  7. CreateEvent、CreateSemaphore、ReleaseSemaphore、CreateMutex
  8. 2022谷歌博士奖学金名单公布:共61人获奖!
  9. 我对于C女士的初次看法
  10. 泛微OA E9 开发 创建系统工作流程提醒