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

2023-05-16

最近刚开始学习机器学习中的朴素贝叶斯分类器,用西瓜数据集做了一下,最后结果预测正确率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 = 0
    bad_num = 0  # 好瓜与坏瓜的个数,后面拉普拉斯修正也要用
    for i in range(train_data.shape[0]):  # 一行一行地看,shape[0]指行数
        if train_data[i, -1] == "是":
            good_num += 1
        elif train_data[i, -1] == "否":
            bad_num += 1
    # 得到好瓜6个,坏瓜7个
    # 计算先验概率
    pc_good = (good_num + 1) / (train_data.shape[0] + 2)  # 公式见西瓜书p153
    pc_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]] += 1
                else:
                    good_melon[j][train_data[i, j]] = 1  # 如果没有就创建一个键值对并赋值为1
                    good_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]] += 1
                else:
                    bad_melon[j][train_data[i, j]] = 1  # 如果没有就创建一个键值对并赋值为1
                    bad_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] = 0
            print(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)

运行结果:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • dockerfile容器的实战安装nginx和mysql服务

    第三章 实验 xff1a docker容器的实战 一 基础环境 安装docker服务 1 xff09 配置网络yum源 root 64 centos01 cd etc yum repos d root 64 centos01 yum rep
  • 使用 Learner Lab 建立 WordPress 网站 (EC2)

    使用 Learner Lab 建立 WordPress 网站 EC2 AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务 xff0c 让学生可以在 100 USD的金额下 xff0c 自行练习所
  • LaTex 排版相关记录--1 参考文献排版

    找到latex代码中的 bibligraphystyle xff0c 然后根据下面的各种需求进行替换 bibliographystyle unsrt 样式同plain xff0c 只是按照引用的先后排序 xff0c 参考文献会根据在正文中引
  • 使用rke构建企业生产k8s,安装kubectl客户端

    一 使用rke构建企业生产k8s xff0c 安装kubectl客户端 1 安装kubectl客户端工具 span class token comment wget https storage googleapis com kubernet
  • 保持pppoe不掉线

    对于无极网络的VPS 修改 etc ppp pppoe server options 这个文件里面的两个参数 默认 xff1a lcp echo interval 1 发送间隔秒 lcp echo failure 5 5次未响应断开 因为o
  • Linux环境编程06

    目录 Linux环境编程之进程管理一 进程的基本概念二 创建进程三 进程的正常退出 Linux环境编程之进程管理 一 进程的基本概念 进程与程序 程序是存储在磁盘上的可执行文件 xff0c 程序被加载到内存中开始运行时叫做进程 一个程序可以
  • 区间最大平均值

    题目链接 xff1a https www luogu com cn problem P1404 题目描述 xff1a 给一个长度为 n 的数列 xff0c 我们需要找出该数列的一个子串 xff0c 使得子串平均数最大化 xff0c 并且子串
  • 输出 0~N 内的素数 ( C++ )

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • 快读模板 ( C++ )

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • Java正整数分解质因数

    leetcode 2 Java正整数分解质因数 1 题目 xff1a 将一个正整数分解质因数 例如 xff1a 输入 90 打印出 90 61 233 5 2 题目解析 xff1a 先将数m从2开始整除 xff0c 如果能被2整除 xff0
  • you-get使用教程

    you get爬虫 xff0c 依赖于Python3 10 xff0c 可以爬取网页无法下载的视频文件 xff0c 具体步骤如下 xff1a 1 xff0c 下载Python3 10无脑下一步安装 2 xff0c 新建一个空白文件夹 xff
  • Windows如何自定义右键新建菜单栏

    目录 右键新建菜单的实现原理在右键新建菜单中新增项方法一可能出现的问题 方法二编辑右键新建菜单的图标 修改右键新建菜单栏的顺序 右键新建菜单的实现原理 参考文章 修改 win10 右键 新建 菜单 xff08 原理 两种方法及注意事项 xf
  • Centos 8升级至Centos 8 Stream

    文章目录 一 背景 xff1a 二 分析 xff1a 三 升级步骤 xff1a 四 成功安装 openstack 软件仓库参考链接 xff1a 一 背景 xff1a 因使用华为云ecs部署 openstack yoga 版本过程中 xff0
  • Ceph OSD为DOWN时修复

    本文所使用Ceph版本为luminous 不同版本删除OSD基本操作相同 xff09 xff0c 当出现Ceph OSD为down的情况时 xff0c 可以通过以下方法解决 xff08 假设ceph admin节点OSD 1 Down xf
  • 【Anaconda创建虚拟环境】报错及解决办法

    Q1 CondaHTTPError HTTP 000 CONNECTION FAILED for url 错误原因 xff1a 下载网速过慢 xff0c 时间过长 xff0c 自动断开 解决方法 xff1a 在下载命令前加入 conda c
  • 二叉树的绘制

    目录 一 知乎方法 二 动手实践 DOT 语言 无向图 有向图 绘制二叉树 设置属性 如何绘制优美的二叉树 一 知乎方法 知乎上的大佬提供了一系列画图的方法 xff0c 感兴趣的朋友可以自行去看看 用 Graphviz 绘制一棵漂亮的二叉树
  • 修改CPU的调频策略

    cat proc cpuinfo 查看CPU信息 CPU的调频策略修改 xff0c scaling governor xff1a governor 调频 策略 xff0c Linux 内核一共有 5 中调频策略 Performance xf
  • 一文看懂map、odom、base_link、laser之间的tf关系

    这三者之间的关系到底是怎样的 xff1f 尤其是map坐标系到odom坐标系之间的变换 xff0c 到底是有什么意义呢 xff1f 我当时被这个问题也是困扰了很久 现在经过实践终于有机会记录一下拙见 xff0c 如有错误 xff0c 还请指
  • VTK库cmake编译时找不到Qt5UiPlugin_DIR和QT5Sql_DIR

    ubuntu使用cmake gui编译VTK时 xff0c Qt5UiPlugin DIR和QT5Sql DIR是红的 xff0c 怎么办 xff1f 答 xff1a 安装libqt5x11extras5 dev和qt5 default两个
  • 超前进位加法器原理与递推式超详细推导+verilog实现与测试

    当记忆的线缠绕过往支离破碎 xff0c 是慌乱占据了心扉 寂寞沙洲冷 超前进位加法器原理 1 一位二进制的加法 首先考虑两个1位二进制相加 a 43 b xff0c 不考虑上一级的进位 xff0c 0和1简单相加 xff0c 即使是三岁小孩

随机推荐

  • 一生一芯 算术逻辑部件 ALU verilog浅析与实现

    仙歌音 xff0c 玉笛灵 xff0c 酒盏玉露清 剑舞轻 xff0c 潇洒过白袍影 谪仙 一生一芯项目 xff0c 预学习部分 xff0c 数电实验学习记录 xff0c 笔者电子寄术挂科 xff0c 基础知识甚是不熟 xff0c 故文中可
  • Verilated model didn‘t converge报错原因及解决

    还留着你的回忆 xff0c 分不清南北东西 我真的不想从此迷失在这幻境 迷失幻境 想必你急于知道原因 xff0c 不想听笔者解决问题的过程 xff0c 所以我先放结论 xff0c 再说我发现的过程 1 错误原因 一句话概括 xff0c 根本
  • CMake初级简明教程

    我藏在人群中 然后失去晴空 像我的名字 从你的记忆清空 你头顶的风 本文仅仅介绍了一些常用函数的参数的简单写法以及个人理解 xff0c 如果你想了解更多 xff0c 可以去查找专门介绍该函数的博客 本文只能保证你读完之后对各个函数有基本的认
  • ubuntu18安装ros1

    是非成败转头空 青山依旧在 xff0c 几度夕阳红 临江仙 滚滚长江东逝水 杨慎 0 前言 我都不明白安装一个ros有这么难么 xff0c 某学弟经常说卡住了安不了啥啥的 真是服了 xff0c 我再安一遍看看还有谁特么再说安不上 1 添加源
  • centos urllib3安装出错

    当卸载urllib3之后 xff0c 尝试重新安装 xff0c 发现出现问题 而后 xff0c 经过一番学习 xff0c 找到了解决办法 pip install upgrade urllib3 问题解决 xff01
  • Numpy简单学习(Spyder)

    1 Numpy创建 A 61 np array 1 2 3 4 5 6 两行三列的列表 类型为n维列表 Z 61 np zeros 3 2 3行2列的全0矩阵 Z1 61 np zeros 3 5 3行5列全0矩阵 全1矩阵 np ones
  • sip篇——服务器

    上篇提到sip定义了如何管理整个会话过程 xff0c 其实就是负责建立连接 监控和断开一个或多个参与者参与的会话 xff0c 利用IP地址和协议建立网络会话 xff0c 使得世界各地的人都可以通过互联网及时建立连接 1 sip中的逻辑组件
  • RTSP协议,与sip区别

    RTSP Real Time Streaming Protocol 是应用层中的实时流协议 xff0c 处于RTP RTCP SRTP等之上 xff0c 使用RTP或TCP来进行数据的传输 xff0c 其本身并不传输媒体流数据 xff0c
  • sip服务器搭建篇——虚拟机

    1 摘要 sip服务器 xff08 上篇所述的代理 注册 重定向等服务器功能组合而成的服务器软件 xff09 基于Linux操作系统而搭建 xff0c 这就需要在windows操作系统中下载虚拟机 xff0c 然后在虚拟机中才能使用Linu
  • Ubuntu常用命令[1]-ls、pwd、cd、mkdir、rmdir、apt

    xff0a ls ls是list的缩写 xff0c 列出当前目录下所有的文件或子目录 ls l 则是以更详细的模式进行查看 要点1 xff1a 在输入命令和路径时 xff0c 按tab键可自动补全 xff0c 例如ls ho xff0c 按
  • 什么是网关,网关的作用是什么

    1 什么是网关 网关又称网间连接器 协议转换器 xff0c 也就是网段 局域网 广域网 关卡 xff0c 不同网段中的主机不能直接通信 xff0c 需要通过关卡才能进行互访 xff0c 比如IP地址为192 168 31 9 子网掩码 xf
  • 无法访问opensips control panel

    OpenSIPS控制面板是一个用于供应的PHP Web门户OpenSIPS服务器 xff0c 可以为opensips提供系统和用户配置 xff0c 我们可以在该面板上添加 修改 管理sip账户信息和权限 有时候无法访问 xff0c 需要先将
  • sip电话注册失败问题解决心得总结

    这是我学习搭建opensips服务器以来持续性最长的一个问题 xff0c 具体就是终端电话软件一直注册不了已经创建好的sip会话账号 我刚开始用的终端电话软件是Zoiper xff0c 要么一直在注册中 xff0c 要么直接注册失败 xff
  • 面向对象以及类和对象的概念

    面向对象 面向对象和面向过程的区别 面向过程 xff1a 主要的关注点是实现具体的过程 xff0c 因果关系 集成显卡的开发思路 优点 xff1a 对于业务逻辑比较简单的程序 xff0c 可以达到快速开发 xff0c 前期投入成本较低 缺点
  • 尚硅谷hadoop3.x集群配置笔记及常见错误解决方式

    1 搭建集群准备工作 总体流程 准备3台客户机 xff08 关闭防火墙 静态IP 主机名称 xff09 安装JDK 配置环境变量 安装Hadoop 配置环境变量 配置集群 单点启动 配置ssh 群起并测试集群 一 模板虚拟机的搭建 配置要求
  • Centos 7系统下NTP时间同步服务配置

    NTP分为服务器端与客户端 xff08 自己选择某一台机器为服务器端 xff0c 其他机器则为客户端 xff09 xff0c 其中 xff0c 客户端通过向服务器端发送时间同步请求实现整个集群的时间同步 具体操作步骤如下所示 xff1a 1
  • EduCoder-程序设计技术R(第四部分循环结构程序设计1)- 第5关:求sn=a+aa+aaa+aaaa+......的值

    大家好鸭 x1f60e xff0c 前几期的EduCoder题解 xff0c 阅读量超过了之前的好多文章 xff01 谢谢大家的阅读 如果题目AC的话 xff0c 求一个免费的赞噢 x1f47b 如果有编程相关的问题 xff0c 可以一起交
  • 和风天气获取天气情况

    和风天气api xff08 实时天气 xff09 https dev qweather com docs api weather weather now 控制台 https console qweather com apps 1 进入控制台
  • Java习题练习:组队

    目录 题目描述 思路 其他真题 题目描述 作为篮球队教练 你需要从以下名单中选出1 号位至5 号位各一名球员 组成球队的首发阵容 每位球员担任1 号位至5 号位时的评分如下表所示 请你计算首发阵容1 号位至5 号位的评分之和最大可能是多少
  • 基于朴素贝叶斯分类器的西瓜数据集(实战)

    最近刚开始学习机器学习中的朴素贝叶斯分类器 xff0c 用西瓜数据集做了一下 xff0c 最后结果预测正确率75 xff0c 其中运用到的python语法并不复杂 xff0c 适合小白观看 目录 朴素贝叶斯分类器思想的自然语言描述 xff1