基于朴素贝叶斯分类器的西瓜数据集(实战)
最近刚开始学习机器学习中的朴素贝叶斯分类器,用西瓜数据集做了一下,最后结果预测正确率75%,其中运用到的python语法并不复杂,适合小白观看。
目录
朴素贝叶斯分类器思想的自然语言描述:
详细步骤在代码中说明
思想的自然语言描述:
朴素贝叶斯分类器其实就是计算先验概率和每一个属性的条件概率,作乘积并比较,哪个大就是哪一类的,其中对离散属性做拉普拉斯修正,连续属性用概率密度函数。
因此要保存每一个属性的每一个取值在每一个分类中的条件概率,比如色泽是青绿在好瓜中的条件概率。由于属性个数很多每一个属性的取值也有很多,因此要考虑冗杂的数据如何保存,这点清楚了预测时直接乘就行。我们可以用字典数组来保存离散属性的先验概率和条件概率(或连续属性的均值和方差)。
给定表1中的训练数据,编程实现贝叶斯分类器算法,并为表2中测试数据进行分类;
表1:训练集
编号 |
色泽 |
根蒂 |
敲声 |
纹理 |
脐部 |
触感 |
密度 |
含糖率 |
好瓜 |
1 |
青绿 |
蜷缩 |
浊响 |
清晰 |
凹陷 |
硬滑 |
0.697 |
0.46 |
是 |
2 |
乌黑 |
蜷缩 |
沉闷 |
清晰 |
凹陷 |
硬滑 |
0.774 |
0.376 |
是 |
3 |
乌黑 |
蜷缩 |
浊响 |
清晰 |
凹陷 |
硬滑 |
0.634 |
0.264 |
是 |
4 |
青绿 |
蜷缩 |
沉闷 |
清晰 |
凹陷 |
硬滑 |
0.608 |
0.318 |
是 |
5 |
浅白 |
蜷缩 |
浊响 |
清晰 |
凹陷 |
硬滑 |
0.556 |
0.215 |
是 |
6 |
青绿 |
稍蜷 |
浊响 |
清晰 |
稍凹 |
软粘 |
0.403 |
0.237 |
是 |
7 |
浅白 |
硬挺 |
清脆 |
模糊 |
平坦 |
硬滑 |
0.245 |
0.057 |
否 |
8 |
浅白 |
蜷缩 |
浊响 |
模糊 |
平坦 |
软粘 |
0.343 |
0.099 |
否 |
9 |
青绿 |
稍蜷 |
浊响 |
稍糊 |
凹陷 |
硬滑 |
0.639 |
0.161 |
否 |
10 |
浅白 |
稍蜷 |
沉闷 |
稍糊 |
凹陷 |
硬滑 |
0.657 |
0.198 |
否 |
11 |
乌黑 |
稍蜷 |
浊响 |
清晰 |
稍凹 |
软粘 |
0.36 |
0.37 |
否 |
12 |
浅白 |
蜷缩 |
浊响 |
模糊 |
平坦 |
硬滑 |
0.593 |
0.042 |
否 |
13 |
青绿 |
蜷缩 |
沉闷 |
稍糊 |
稍凹 |
硬滑 |
0.719 |
0.103 |
否 |
表2:测试集
编号 |
色泽 |
根蒂 |
敲声 |
纹理 |
脐部 |
触感 |
密度 |
含糖率 |
好瓜 |
1 |
乌黑 |
稍蜷 |
浊响 |
稍糊 |
稍凹 |
软粘 |
0.481 |
0.149 |
是 |
2 |
乌黑 |
稍蜷 |
浊响 |
清晰 |
稍凹 |
硬滑 |
0.437 |
0.211 |
是 |
3 |
乌黑 |
稍蜷 |
沉闷 |
稍糊 |
稍凹 |
硬滑 |
0.666 |
0.091 |
否 |
4 |
青绿 |
硬挺 |
清脆 |
清晰 |
平坦 |
软粘 |
0.243 |
0.267 |
否 |
详细步骤在代码中说明
import pandas as pd
import 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)
运行结果:
基于朴素贝叶斯分类器的西瓜数据集(实战)相关推荐
- 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_第十章:利用Python实现朴素贝叶斯模型
免责声明:本文是通过网络收集并结合自身学习等途径合法获取,仅作为学习交流使用,其版权归出版社或者原创作者所有,并不对涉及的版权问题负责.若原创作者或者出版社认为侵权,请联系及时联系,我将立即删除文章, ...
- 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_朴素贝叶斯为什么被称为“朴素”?...
一.基本理解 1.朴素贝叶斯分类器: 例:如果有一种水果具有红.椭圆形.直径约3英寸等特征,则该水果可以被判定为是苹果. 尽管这些特征相互依赖或者有些特征由其他特征决定,然而朴素贝叶斯分类器认为这些属 ...
- 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_朴素贝叶斯(转载自Morgan)...
什么是朴素贝叶斯 要搞懂朴素贝叶斯分类,首先需要了解什么是贝叶斯定理和特征条件独立假设,朴素贝叶斯算法就是基于这两个来实现的分类方法. 贝叶斯定理 贝叶斯定理通俗点讲就是求在事件 B 已经发生的前提下 ...
- 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_机器学习之朴素贝叶斯
1.贝叶斯原理 朴素贝叶斯分类(Naive Bayesian,NB)源于贝叶斯理论,是一类基于概率的分类器,其基本思想:假设样本属性之间相互独立,对于给定的待分类项,求解在此项出现的情况下其他各个类别 ...
- MNIST | 基于朴素贝叶斯分类器的0-9数字手写体识别
MNIST | 基于朴素贝叶斯分类器的0-9数字手写体识别 1 背景说明 2 关于数据集 2.1 什么是MNIST 2.2 数据集处理 3 代码实现 3.1 文件目录 3.2 核心代码 3.3 注意点 ...
- 基于朴素贝叶斯分类器的钞票真伪识别模型
基于朴素贝叶斯分类器的钞票真伪识别模型 内容 本实验通过实现钞票真伪判别案例来展开学习朴素贝叶斯分类器的原理及应用. 本实验的主要技能点: 1. 朴素贝叶斯分类器模型的构建 2. 模型的评估与预测 3 ...
- c语言贝叶斯分类,基于朴素贝叶斯分类器的文本分类算法(C语言)
基于朴素贝叶斯分类器的文本分类算法(C语言) 基于朴素贝叶斯分类器的文本分类算法(C语言).txt两个人吵架,先说对不起的人,并不是认输了,并不是原谅了.他只是比对方更珍惜这份感情.#include ...
- 朴素贝叶斯分类器及西瓜判定实例
朴素贝叶斯分类器是一系列以假设特征之间强(朴素)独立下运用贝叶斯定理为基础的简单概率分类器.下面我们通过西瓜判定的实例,阐述利用贝叶斯算法进行简单模式识别分类的过程. 鉴于概率论与数理统计基础,我们直 ...
- 用Python开始机器学习(6:朴素贝叶斯分类器)
朴素贝叶斯分类器是一个以贝叶斯定理为基础,广泛应用于情感分类领域的优美分类器.本文我们尝试使用该分类器来解决上一篇文章中影评态度分类. 1.贝叶斯定理 假设对于某个数据集,随机变量C表示样本为C类的概 ...
最新文章
- TextVew中文空格
- 江苏有线门户网站服务器地址,江苏有线手机客户端的登录服务器
- 机器学习入门系列四(关键词:BP神经网络)
- python urllib2及beautifulsoup学习
- 值得一谈的鸿蒙2.0,程序员们拿起你们手中的编译器撸一下hello world
- java如何添加进程_如何创建一个进程,如何进程调用进程
- 男女薪酬差异扩大 2018年女性薪酬不及男性8成?
- 有关Select 语句查询.四
- python写出租车计费系统_用VHDL设计出租车计费系统
- 自定义控件属性英文类别
- 自研DCI网络路由交换协议DCIP-白牌交换机时代的企业网络
- 算法系列之二十一:实验数据与曲线拟合
- 沪牌软件操作开发说明
- 被chatGPT割了一块钱韭菜
- Java 仿 Excel 公式计算
- 华为android10手机指纹,华为P10这些指纹功能你知道几个?
- 汉诺塔问题的递归和非递归算法
- windows全局激活conda(包括cmd,powershell,pycharm)
- [导入]WAP广告钱景一致看好 现PUSH模式受质疑
- 《我想进大厂》之Dubbo普普通通9问