600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 基于朴素贝叶斯分类器的西瓜数据集(实战)

基于朴素贝叶斯分类器的西瓜数据集(实战)

时间:2023-03-22 17:21:25

相关推荐

基于朴素贝叶斯分类器的西瓜数据集(实战)

最近刚开始学习机器学习中的朴素贝叶斯分类器,用西瓜数据集做了一下,最后结果预测正确率75%,其中运用到的python语法并不复杂,适合小白观看。

目录

朴素贝叶斯分类器思想的自然语言描述:

详细步骤在代码中说明

思想的自然语言描述:

朴素贝叶斯分类器其实就是计算先验概率和每一个属性的条件概率,作乘积并比较,哪个大就是哪一类的,其中对离散属性做拉普拉斯修正,连续属性用概率密度函数

因此要保存每一个属性的每一个取值在每一个分类中的条件概率,比如色泽是青绿在好瓜中的条件概率。由于属性个数很多每一个属性的取值也有很多,因此要考虑冗杂的数据如何保存,这点清楚了预测时直接乘就行。我们可以用字典数组来保存离散属性的先验概率和条件概率(或连续属性的均值和方差)。

给定表1中的训练数据,编程实现贝叶斯分类器算法,并为表2中测试数据进行分类;

表1:训练集

表2:测试集

详细步骤在代码中说明

import pandas as pdimport numpy as np# 将数据集分别保存在excel表中的不同工作表中,用pandas导入,其余都用numpy来做def load_data():# 导入数据train_data = pd.read_excel('data.xlsx', sheet_name='train')test_data = pd.read_excel('data.xlsx', sheet_name='test')# ['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '含糖率', '好瓜‘]train_data = np.array(train_data)[:, 1:]test_data = np.array(test_data)[:, 1:]return train_data, test_data# 训练贝叶斯分类器,其实就是计算离散属性的先验概率和条件概率、连续属性的均值和方差def train_bayes(train_data): # 13行9列# 先计算先验概率P(c),即好瓜和坏瓜的个数分别占总训练集样本个数的比例good_num = 0bad_num = 0 # 好瓜与坏瓜的个数,后面拉普拉斯修正也要用for i in range(train_data.shape[0]): # 一行一行地看,shape[0]指行数if train_data[i, -1] == "是":good_num += 1elif train_data[i, -1] == "否":bad_num += 1# 得到好瓜6个,坏瓜7个# 计算先验概率pc_good = (good_num + 1) / (train_data.shape[0] + 2) # 公式见西瓜书p153pc_bad = (bad_num + 1) / (train_data.shape[0] + 2)# 将分类结果的好瓜与坏瓜分开,典的第一个键值对保存该属性的取值个数,例如本训练集中色泽有三种取值(青绿,乌黑,浅白),就保存# 保存每一个属性的取值个数是为了进行拉普拉斯修正good_melon = [{'sumType': 0} for i in range(8)]bad_melon = [{'sumType': 0} for i in range(8)]# 计算条件概率P(xi | c),例如计算在好瓜中色泽为青绿的个数占好瓜总数的比例for j in range(train_data.shape[1] - 3): # 一列一列地看,shape[1]指列数,最后三列不看# 一行一行地看,这两行正反都一样for i in range(train_data.shape[0]):# 首先保证是好瓜if train_data[i, -1] == "是":# 如果字典数组中已经有了这个属性对应的值(如青绿)就直接加一if train_data[i, j] in good_melon[j]:good_melon[j][train_data[i, j]] += 1else:good_melon[j][train_data[i, j]] = 1 # 如果没有就创建一个键值对并赋值为1good_melon[j]['sumType'] += 1 # 该属性增加一个取值else: # 如果是坏瓜,把上面good_melon换成bad_melon就行if train_data[i, j] in bad_melon[j]: # 如果字典数组中已经有了这个属性对应的值(如青绿)就直接加一bad_melon[j][train_data[i, j]] += 1else:bad_melon[j][train_data[i, j]] = 1 # 如果没有就创建一个键值对并赋值为1bad_melon[j]['sumType'] += 1 # 该属性增加一个取值# 因为拉普拉斯修正中每一个属性的取值是整个训练集的取值,上面只是单独收集好瓜与坏瓜for i in range(len(good_melon) - 2):# if或者elif成立说明有属性只在好瓜和坏瓜中存在,要统一一下if good_melon[i]['sumType'] > bad_melon[i]['sumType']:# 统一属性取值个数bad_melon[i]['sumType'] = good_melon[i]['sumType']# 统一取值key = good_melon[i].keys() - bad_melon[i].keys()bad_melon[i][key] = 0print(bad_melon[i][key])elif good_melon[i]['sumType'] < bad_melon[i]['sumType']:# 统一属性取值个数good_melon[i]['sumType'] = bad_melon[i]['sumType']# 统一取值key = list(bad_melon[i].keys() - good_melon[i].keys())for j in key:good_melon[i][j] = 0# 上面只是统计了个数,下面才是计算条件概率,直接用统计出来的数值除以好瓜或者坏瓜的个数for i in range(train_data.shape[1] - 3): # 有train_data.shape[0] - 3个是离散属性,需要进行拉普拉斯修正for key, value in good_melon[i].items(): # 遍历每一个键值对,好瓜if key != "sumType": # 除了字典的第一个值good_melon[i][key] = (good_melon[i][key] + 1) / (good_num + good_melon[i]['sumType'])for key, value in good_melon[i].items(): # 遍历每一个键值对,坏瓜if key != "sumType": # 除了字典的第一个值bad_melon[i][key] = (bad_melon[i][key] + 1) / (bad_num + bad_melon[i]['sumType'])# 以上是离散属性的先验概率和条件概率# 下面是连续属性的均值和方差 -1是含糖率,-2是密度good_melon[-1]['mean'] = np.mean(train_data[:6, -2], axis=0)good_melon[-1]['var'] = np.var(train_data[:6, -2], axis=0)bad_melon[-1]['mean'] = np.mean(train_data[6:, -2], axis=0)bad_melon[-1]['var'] = np.var(train_data[6:, -2], axis=0)good_melon[-2]['mean'] = np.mean(train_data[:6, -3], axis=0)good_melon[-2]['var'] = np.var(train_data[:6, -3], axis=0)bad_melon[-2]['mean'] = np.mean(train_data[6:, -3], axis=0)bad_melon[-2]['var'] = np.var(train_data[6:, -3], axis=0)# print(f'好瓜 {good_melon}')# print(f'坏瓜 {bad_melon}')# 结果如下: 好瓜[{'sumType': 3, '青绿': 0.4444444444444444, '乌黑': 0.3333333333333333, '浅白': 0.2222222222222222},# { 'sumType': 3, '蜷缩': 0.6666666666666666, '稍蜷': 0.2222222222222222, '硬挺': 0.1111111111111111}, { 'sumType': 3,# '浊响': 0.5555555555555556, '沉闷': 0.3333333333333333, '清脆': 0.1111111111111111}, { 'sumType': 3,# '清晰': 0.7777777777777778, '模糊': 0.1111111111111111, '稍糊': 0.1111111111111111}, { 'sumType': 3,# '凹陷': 0.6666666666666666, '稍凹': 0.2222222222222222, '平坦': 0.1111111111111111}, { 'sumType': 2, '硬滑': 0.75,# '软粘': 0.25}, {'sumType': 0, 'means': 0.612, 'var': 0.01346433333333333}, { 'sumType': 0,# 'means': 0.3116666666666667, 'var': 0.0072288888888888915}] 坏瓜[{'sumType': 3, '浅白': 0.5, '青绿': 0.3, '乌黑': 0.2},# {'sumType': 3, '硬挺': 0.2, '蜷缩': 0.4, '稍蜷': 0.4}, { 'sumType': 3, '清脆': 0.2, '浊响': 0.5, '沉闷': 0.3}, {'sumType':# 3, '模糊': 0.4, '稍糊': 0.4, '清晰': 0.2}, { 'sumType': 3, '平坦': 0.4, '凹陷': 0.3, '稍凹': 0.3}, {'sumType': 2,# '硬滑': 0.6666666666666666, '软粘': 0.3333333333333333}, {'sumType': 0, 'mean': 0.508,# 'var': 0.029915142857142855}, { 'sumType': 0, 'mean': 0.14714285714285716, 'var': 0.010841551020408164}]return pc_good,pc_bad,good_melon, bad_melon# 开始对测试集分类def classify_bayes(pc_good,pc_bad,good_melon, bad_melon, test_data):# 对每一个测试数据进行计算好瓜与坏瓜的概率for i in range(test_data.shape[0]):# 每一个测试数据都要先令其等于先验概率的对数,后面全部取对数直接相加good_probability = np.log(pc_good)bad_probability = np.log(pc_bad)for j in range(test_data.shape[1] - 3): # 先处理离散属性if test_data[i][j] in good_melon[j]: # 如果这个特征训练集没有就跳过good_probability += np.log(good_melon[j][test_data[i][j]]) # 转化为对数相加if test_data[i][j] in bad_melon[j]:bad_probability += np.log(bad_melon[j][test_data[i][j]])for j in range(test_data.shape[1] - 3, test_data.shape[1] - 1): # 处理连续属性good_probability += np.log((2 * np.pi * good_melon[j]['var']) ** (-1 / 2)) + \(-1 / 2) * ((test_data[i][j] - good_melon[j]['mean']) ** 2) / (good_melon[j]['var'] ** (-2))bad_probability += np.log((2 * np.pi * bad_melon[j]['var']) ** (-1 / 2)) + \(-1 / 2) * ((test_data[i][j] - bad_melon[j]['mean']) ** 2) / (bad_melon[j]['var'] ** (-2))print(f'The positive probability of the sample {i + 1} is {good_probability}\n\The negative probability of the sample {i + 1} is {bad_probability}')if good_probability > bad_probability:print(f'Lucky! The test data numbered {i + 1} is a good melon\n')else:print(f'Not good! The test data numbered {i + 1} is a bad melon\n')if __name__ == "__main__":train_data, test_data = load_data()pc_good,pc_bad,good_melon, bad_melon = train_bayes(train_data)classify_bayes(pc_good,pc_bad,good_melon, bad_melon, test_data)

运行结果:

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