朴素贝叶斯案例

news2025/1/16 3:58:53

一、朴素贝叶斯算法:

朴素贝叶斯算法,是一种基于贝叶斯定理与特征条件独立假设的分类方法,基于贝叶斯后验概率建立的模型,它用于解决分类问题。朴素:特征条件独立;贝叶斯:基于贝叶斯定理。属于监督学习的生成模型,实现简单,并有坚实的数学理论(即贝叶斯定理)作为支撑。在大量样本下会有较好的表现,不适用于输入向量的特征条件有关联的场景。

它的主要思想是,通过历史数据,对每个类别建立经验概率公式,然后当新样本进来时,用各个类别的概率经验公式分别进行预测,最终,属于哪个类别的概率最大,就认为是哪个类别。

二、计算条件概率

朴素贝叶斯算法的核心内容即使贝叶斯公式,也就是计算特征在类别下的条件概率的计算,贝叶斯原理为,在已知发生B条件下,发生A的概率为:

P(A):为先验概率,即在B事件发生之前,对A事件发生概率的预判。

P(A|B):为后验概率,即在B事件发生之后,对A事件发生概率的重新评估。

P(B|A)/P(B):为可能性函数,是一个调整因子,使得预估概率更加接近真实概率。可以理解为:P(B)P(A∣B) = P(B∣A)P(A),即:发生B,且发生A = 发生A且发生B。

换个表达形式就会明朗很多,如下:

所以贝叶斯公式可以表示为:后验概率=先验概率 * 调整因子

三、预测精度的计算与评估

estimator.score():一般最常见使用的是准确率,即预测结果正确的百分比。

也可以使用召回率(Recall),真实为正例的样本中预测结果为正例的比例(查的全,对正样本的区分能力)

其他分类标准,F1-score,反映了模型的稳健型,F1值是准确率和召回率的调和平均数。

也可以使用分类模型评估API: sklearn.metrics.classification_report

sklearn.metrics.classification_report(y_true,y_pred,target_names=None)

  y_true:真实目标值

  y_pred:估计器预测目标值

  target_names:目标类别名称

  return:每个类别精确率与召回率

四、编程实现贝叶斯分类算法,并对简单应用样本数据实现预测分类

算法过程描述:

我们以西瓜的特征为变量,好坏质量为二元结果,准备数据如下:

定义一个名数组进行数据集的存储。数据集的每一行表示一个西瓜的属性,包括色泽、根蒂、敲击、纹理、脐部和触感。最后一行表示西瓜是好瓜还是坏瓜。

并且申请一个字典存放特征features(特征)的可能值,并为最终的二元结果申请一个列表标签 labels(标签)。

以上查看数据,即标签的分布比例。

from pprint import pprint
import numpy as np
dataset = np.array([
    # 色泽,根蒂,敲击,纹理,脐部,触感, 好坏
    ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],
    ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'],
    ['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],
    ['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '好瓜'],
    ['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '好瓜'],
    ['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '好瓜'],
    ['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', '好瓜'],
    ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', '好瓜'],
    ['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜'],
    ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '坏瓜'],
    ['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '坏瓜'],
    ['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '坏瓜'],
    ['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', '坏瓜'],
    ['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', '坏瓜'],
    ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '坏瓜'],
    ['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', '坏瓜'],
    ['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '坏瓜']
])

features = {
    '色泽': ['青绿', '乌黑', '浅白'],
    '根蒂': ['蜷缩', '稍蜷', '硬挺'],
    '敲击': ['浊响', '沉闷', '清脆'],
    '纹理': ['清晰', '稍糊', '模糊'],
    '脐部': ['凹陷', '稍凹', '平坦'],
    '触感': ['硬滑', '软粘']
}

labels = ["好瓜", "坏瓜"]


class Bayes:
    def __init__(self, features: dict, labels: list) -> None:
        self.features = features
        self.labels = labels
        self.feature_classes = list(self.features.keys())
        self.condi_prob = {}
        self.prior_prob = {}
        self._statistic = {}
        self._samples = 0
        for i in self.labels:
            self.prior_prob[i] = 1 / len(self.labels)
            self.condi_prob[i] = {}
            self._statistic[i] = 0
            for j in self.feature_classes:
                self.condi_prob[i][j] = {}
                for k in self.features[j]:
                    self.condi_prob[i][j][k] = 1 / len(self.features[j])
                    self._statistic['.'.join([i, j, k])] = 0

    def bayes_prob(self, arr):
        plist = []
        for i in self.labels:
            idx = 0
            p = self.prior_prob[i]
            for j in self.feature_classes:
                p *= self.condi_prob[i][j][arr[idx]]
                idx += 1
            plist.append(p)
        return plist

    def train(self, X, Y):
        rows, cols = X.shape
        for i in range(rows):
            self._statistic[Y[i]] += 1
            for j in range(cols):
                self._statistic['.'.join(
                    [Y[i], self.feature_classes[j], X[i, j]])] += 1
            self._samples += 1

        for i in self.labels:
            self.prior_prob[i] = (self._statistic[i] + 1) / (self._samples+len(self.labels))
            for j in self.feature_classes:
                for k in self.features[j]:
                    self.condi_prob[i][j][k] = (self._statistic['.'.join([i, j, k])] + 1) / (self._statistic[i] + len(self.features[j]))

    def predic(self, X):
        rows, cols = X.shape
        res = []
        for i in range(rows):
            y = self.bayes_prob(X[i])
            res.append(y)
        res = np.argmax(res, axis=1)
        res = [self.labels[x] for x in res]
        return np.array(res)

    def show_params(self) -> str:
        pprint(self.prior_prob)
        pprint(self.condi_prob , sort_dicts=False)
        # pprint(self._statistic)


if __name__ == "__main__":
    X = dataset[:, :6]
    Y = dataset[:, 6]
    print(X)
    print(Y)

    clf = Bayes(features, labels)
    clf.show_params()

    clf.train(X, Y)
    clf.show_params()

    Yp = clf.predic(X)
    print(f"原始:{Y}\n预测:{Yp}\n准确率:{np.sum(Y==Yp)/len(Y)}")

进行初始化,初始化函数来构建一个朴素贝叶斯分类器,接收两个参数:features和labels。

将features和labels分别赋值给实例变量,计算特征类的列表,并初始化self.condi_prob(条件概率)、self.prior_prob(先验概率)、self._statistic(统计信息)和self._samples(样本数量)。

函数遍历labels中的每个标签,并计算先验概率,遍历features中的每个特征,并初始化一个空字典,用于存储特征在标签下的条件概率。

函数遍历features中的每个特征和每个可能的特征值,并计算条件概率。同时,它将特征值与标签组合成一个字符串,并将其作为键添加到字典中,初始值为0。

接下来训练朴素贝叶斯分类器。

第一部分遍历所有样本,统计每个类别和每个特征值出现的次数。使用两个字典`_statistic`和`_samples`来存储这些统计信息。

第二部分计算先验概率和条件概率。先验概率是指在给定类别的情况下,某个特征值出现的概率。条件概率是指在给定某个特征值的情况下,某个类别出现的概率。使用贝叶斯公式来计算这些概率。

然后,准备计算贝叶斯的概率函数。初始化一个空列表,用于存储每个类别的贝叶斯概率。遍历类标签列表,对于每个类标签,计算先验概率。遍历特征类别列表,对于每个特征类别,计算条件概率。将计算出的条件概率乘以先验概率,并将结果添加到返回值列表中。

定义一个分类器, 申请一个空列表,用于存储每个样本的预测结果。调用前面我们提到的计算贝叶斯的概率函数方法计算当前行的概率分布。返回数组中每行的最大值的下标,即预测结果。最后将预测结果转换为对应的类别标签存储为一维数组。

在训练前后我们可以分别显示模型参数。打印两个字典,计算先验概率、条件概率,下图为训练前模型参数:

下图为训练后模型参数:

以下是模型的两次预测结果及准确率,趋于一致:

具体来说,原始的标签包括了17个样本,其中有8个属于"好瓜"类别,9个属于"坏瓜"类别。预测的结果与原始标签进行了比较,其中有14个样本的预测结果与原始标签一致,3个样本的预测结果与原始标签不一致。

根据比较结果计算得到的准确率为0.8235,召回率为0.875。这个准确率表明,贝叶斯算法在这个测试数据集上的分类表现较为良好,但仍有改进的空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1853733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Let‘s Encrypt 申请通配符证书

为什么不使用阿里云/腾讯云等公有云厂商提供的免费证书? 上篇介绍了从阿里云上面申请免费证书,有效期一年 为网站配置https证书 公有云提供的证书不支持通配符,只支持某个确定的解析。 不管是二级域名还是三级域名,只要是具体的确定的地址,都…

Go WebSocket入门+千万级别弹幕系统架构设计

Go实现WebSocket(千万级别弹幕系统架构设计) 1 websocket简介(基于HTTP协议的长连接) 使用WebSocket可以轻松的维持服务器端长连接,其次WebSocket是架构在HTTP协议之上的,并且也可以使用HTTPS方式,因此WebSocket是可靠…

图像反转入门

文章目录 1.实验目的2.需求3.代码4.运行结果图 1.实验目的 熟练掌握图像像素操作API 2.需求 自己构造一个纯黑图像,通过多种方法进行反转,最终生成一个纯白图像 3.代码 """ Time : 2024/6/23 下午3:46 Author : chensong File : 自己创建一个图像并…

287 寻找重复数-类似于环形链表II

题目 给定一个包含 n 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。 你设计的解决方案必须 不修改 数组 nums…

【python】python学生成绩数据分析可视化(源码+数据+论文)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

swift使用websocket通讯,依赖库Starscream集成,并验证apple watch实现websocket可行性

这里使用webscoket,主要是使用了Starscream这个库,看图片就知道很牛X,那么干就完了。官方开源仓库地址:https://github.com/daltoniam/Starscream?tabreadme-ov-file 安装依赖库 首先,使用 Swift Package Manager 安…

新版idea(2023)创建spring boot3项目

⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 目录 前言 汉化教程 项目模板初始化 1.点击新建项目 2.配置初始化信息 3.初始依赖选择 配置Maven 1.打开maven设置 2.重写maven配置文件 3.选择你创建的配置文件 4.重启项目 spring…

Redis预备知识

一.预备知识 1.基本全局命令 set key value 将key的值设置成value get key 得到key的值 keys [pattern] 查看匹配pattern的所有key 比如h?llo匹配hallo,hbllo,hcllo……只要用一个符号将?代替即可 比如h*llo匹配hllo,heeeello…

硕思LOGO设计师软件怎么下载安装? 【详细安装图文教程】

​相信大家都认同硕思logo设计者只需简单的点击就能够制作出各领域通用及专业的logo、商标、标志、图标等,提供了很多精心设计的logo设计模板及丰富的logo素材,为更好的创建logo作品,使用者能够导入图形或将SWF中的素材反编译到项目中。数据表…

gitlab-cicd-k8s

k8s已经准备好 kubectl get node 创建cicdYaml文件 kubectl create namespace gitlab-cicd --dry-runclient --outputyaml >> gitlab-cicd.yaml kubectl apply -f gitlab-cicd.yaml 服务器和仓库在一起可用专有地址 使用 GitLab Runner 可以自动执行 GitLab CI/CD 管道…

【CS.DS】数据结构 —— 图:深入了解三种表示方法之邻接表(Adjacency List)

文章目录 1 概念2 无向图的邻接表2.1 示例2.2 Mermaid 图示例2.3 C实现2.3.1 简单实现2.3.2 优化封装 2.4 总结 3 有向图的邻接表3.1 示例3.2 C实现3.3 总结 4 邻接图的遍历5 拓展补充References 数据结构 1 概念 优点:空间效率高,适合稀疏图。动态性强…

【C语言】解决C语言报错:Syntax Error

文章目录 简介什么是Syntax ErrorSyntax Error的常见原因如何检测和调试Syntax Error解决Syntax Error的最佳实践详细实例解析示例1:缺少分号示例2:括号不匹配示例3:变量未声明示例4:拼写错误示例5:数据类型不匹配 进一…

低代码平台实践:打造高效动态表单解决方案的探索与思考

🔥需求背景 我司业务同事在抓取到候选人的简历之后,经常会出现,很多意向候选人简历信息不完整,一个个打电话确认的情况,严重影响了HR的工作效率,于是提出我们可以通过发送邮件、短信、H5链接的方式来提醒候…

低成本STC32G8K64驱动控制BLDC开源入门学习方案

低成本STC32G8K64驱动控制BLDC开源入门学习方案 ✨采用STC32G8K64单片机,参考梁工的STC32G12K128-LQFP48驱动方案制作,梁工BLDC相关的资料:https://www.stcaimcu.com/forum.php?modviewthread&tid7472&extrapage%3D1,在此…

Node.js是什么(基础篇)

前言 Node.js是一个基于Chrome V8 JavaScript引擎的开源、跨平台JavaScript运行时环境,主要用于开发服务器端应用程序。它的特点是非阻塞I/O模型,使其在处理高并发请求时表现出色。 一、Node JS到底是什么 1、Node JS是什么 Node.js不是一种独立的编程…

算法训练与程序竞赛题目集合(L4)

目录 L4-103 就不告诉你 输入格式: 输出格式: 输入样例: 输出样例: L4-104 Wifi密码 输入格式: 输出格式: 输入样例: 输出样例: L4-105 冠军魔术 输入格式: …

Ocam:高效录屏,屏幕录制最佳?

名人说::一点浩然气,千里快哉风。 ——苏轼 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、软件介绍1、Ocam2、核心特点 二、下载安装1、下载2、安装 三、使用方法 很高兴你…

BarTender中文版安装包下载及安装教程

​根据大数据结果显示可扩充的大容量卷标数据库:利用大量已设计好的标签库,从数以千计的现成标签尺寸中进行选择,也能够定义并加入自己的标签库尺寸。习惯上来说操作简单:BarTender条码打印软件是目前功能最强大、便捷的标签设计打印软件,在150 多个国家…

WMS项目测试点

这里写目录标题 最后附有图片 仓库系统 仓库 / 库区 仓库 新增仓库 编号 必填校验 字段长度校验 20为字符 数据类型校验 名称 必填校验 字段长度校验 20为字符 数据类型校验 备注 填写备注校验 字符长度限制 不填写备注校验 新增仓库之后是否可以通过查询仓库名称和仓库编号查询…

工业互联网的独特UI风格

工业互联网的独特UI风格