900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 统计学习方法读书笔记8-朴素贝叶斯

统计学习方法读书笔记8-朴素贝叶斯

时间:2022-11-23 08:12:28

相关推荐

统计学习方法读书笔记8-朴素贝叶斯

文章目录

1.朴素贝叶斯的基本方法2.朴素贝叶斯的参数估计1.极大似然估计2.朴素贝叶斯算法3.贝叶斯估计3.后验概率最大化-期望风险最小化4.朴素贝叶斯代码实现

1.朴素贝叶斯的基本方法

2.朴素贝叶斯的参数估计

1.极大似然估计

2.朴素贝叶斯算法

3.贝叶斯估计

用极大似然估计可能出现所要估计的概率值为0的情况,这是会影响到后验概率的计算结果,使分类产生偏差。解决这一问题的方法就是采用贝叶斯估计,原理是在分子、分母中加上指定数值,使得不同项之间大小关系不变,,但消除了分母为0的可能性

3.后验概率最大化-期望风险最小化

4.朴素贝叶斯代码实现

#!usr/bin/env python# -*- coding:utf-8 _*-"""@author: liujie@software: PyCharm@file: natives.py@time: /10/21 17:18"""import timeimport numpy as npfrom tqdm import tqdmdef loaddata(filename):"""加载数据集:param filename: 文件路径:return: 数据与标签"""# 存放数据及标签dataArr = []labelArr = []# 读取文件fr = open(filename)# 遍历读取文件每一行for line in tqdm(fr.readlines()):# 获取当前行,并按','进行切割,返回列表curLine = line.strip().split(',')# 获取数据# 将数据进行了二值化处理,大于128的转换成1,小于的转换成0,方便后续计算dataArr.append([int(int(num) > 128) for num in curLine[1:]])# 获取标签labelArr.append(int(curLine[0]))# 返回数据集与标签return dataArr, labelArrdef NaivesBayes(Py, Px_y, x):"""通过贝叶斯进行概率估计:param Py: 先验概率分布:param Px_y: 条件概率分布:param x: 要估计的样本:return: 返回所有label的估计概率"""# 设置特征数目featureNum = 784# 设置类别数目classNum = 10# 建立存放所有标记的概率的数组P = [0] * classNum# 对于每一个类别,单独估计其概率for i in range(classNum):# 初始化sum为0,sum为求和项。# 在训练过程中对概率进行了log处理,所以这里原先应当是连乘所有概率,最后比较哪个概率最大# 但是当使用log处理时,连乘变成了累加,所以使用sumsum = 0# 获取某一个类别的某个特征的概率,进行累加for j in range(featureNum):# x[j] = 0或1sum += Px_y[i][j][x[j]]# 最后再和先验概率相加(也就是式4.7中的先验概率乘以后头那些东西,乘法因为log全变成了加法)P[i] = sum + Py[i]# 返回该概率最大值对应的索引,即为分类return P.index(max(P))def model_test(Py, Px_y, testDataArr, testLabelArr):"""对数据集进行测试:param Py: 先验概率:param Px_y: 条件概率:param testDataArr:测试数据集:param testLabelArr: 测试数据标签:return: 返回正确率"""# 错误值计数errorCnt = 0# 遍历测试集的每一个样本for i in tqdm(range(len(testDataArr))):# 获取预测值predict = NaivesBayes(Py, Px_y, testDataArr[i])# 如果预测值不等于标志,则errorCnt + 1if predict != testLabelArr[i]:errorCnt += 1# 返回准确率return 1 - (errorCnt / len(testDataArr))def getAllProbability(trainDataArr, trainLabelArr):"""通过训练集获得先验概率与条件概率:param trainDataArr: 训练数据集:param trainLabelArr: 训练数据集标签:return: 返回先验概率与条件概率"""# 设置特征数目featureNum = 784# 设置类别数目labelNum = 10# 初始化先验概率存放数组Py = np.zeros((labelNum, 1))# 对每个类别进行一次循环,分别计算它们的先验概率分布for i in range(labelNum):# np.mat(trainLabelArr) == i:将标签转换为矩阵形式,里面的每一位与i比较,若相等,该位变为Ture,反之False# np.sum(np.mat(trainLabelArr) == i):计算上一步得到的矩阵中Ture的个数,进行求和(直观上就是找所有label中有多少个# 为i的标记,求得4.8式P(Y = Ck)中的分子)# 贝叶斯估计:分子加1,分母加上K(K为标签可取的值数量,这里有10个数,取值为10)Py[i] = (np.sum(np.mat(trainLabelArr) == True) + 1) / (len(trainLabelArr) + 10)# 转为log形式,防止下溢出Py = np.log(Py)# 计算条件概率 Px_y=P(X=x|Y = y)# 计算条件概率分成了两个步骤,下方第一个大for循环用于累加,参考书中“4.2.3 贝叶斯估计 式4.10”,下方第一个大for循环内部是# 用于计算式4.10的分子,至于分子的+1以及分母的计算在下方第二个大For内# 初始化为全0矩阵,用于存放所有情况下的条件概率,xj只有0和1Px_y = np.zeros((labelNum, featureNum, 2))# 对标记集进行遍历for i in range(len(trainLabelArr)):# 获取当前循环所使用的标记label = trainLabelArr[i]# 获取当前要处理的样本x = trainDataArr[i]# 对该样本的每一维特诊进行遍历for j in range(featureNum):# 在矩阵中对应位置加1# 这里还没有计算条件概率,先把所有数累加,全加完以后,在后续步骤中再求对应的条件概率Px_y[label][j][int(x[j])] += 1# 第二个大for循环,计算式4.10的分母,以及分子和分母之间的除法# 循环每一个标记for label in range(labelNum):# 循环每一个标记对应的每一个特征for j in range(featureNum):# 获取y=label,第j个特诊为0的个数Px_y0 = Px_y[label][j][0]# 获取y=label,第j个特诊为1的个数Px_y1 = Px_y[label][j][1]# 对式4.10的分子和分母进行相除,再除之前依据贝叶斯估计,分母需要加上2(为每个特征可取值个数)# 分别计算对于y= label,x第j个特征为0和1的条件概率分布Px_y[label][j][0] = np.log((Px_y0 + 1) / (Px_y0 + Px_y1 + 2))Px_y[label][j][1] = np.log((Px_y1 + 1) / (Px_y0 + Px_y1 + 2))return Py, Px_yif __name__ == '__main__':start = time.time()# 读取数据集print('start to read trainSet')trainDataArr, trainLabelArr = loaddata('data/mnist_train.csv')print('start to read testSet')testDataArr, testLabelArr = loaddata('data/mnist_test.csv')# 开始训练,学习先验概率与条件概率分布print('start to train')Py, Px_y = getAllProbability(trainDataArr, trainLabelArr)# 使用习得的先验概率与条件概率分布,开始测试print('start to test')accuracy = model_test(Py, Px_y, testDataArr, testLabelArr)# 打印准确率print('accuracy = ', accuracy)# 打印时间end = time.time()print('time=', end - start)

start to read trainSet100%|██████████| 60000/60000 [00:17<00:00, 3379.31it/s]start to read testSet100%|██████████| 10000/10000 [00:02<00:00, 3418.50it/s]start to trainstart to test100%|██████████| 10000/10000 [00:41<00:00, 242.28it/s]accuracy = 0.8435time= 102.47366952896118

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。