贝叶斯分类及其代码

article/2025/10/15 22:13:19

        学期末的综述报告我选择了贝叶斯分类,既然已经写了就将它分享一下。 主要目的就是以教促学。   如有问题欢迎在评论区进行讨论。

        随着现代社会信息技术的发展,对于数据的挖掘越来越重要,分类是数据挖掘中应用领域极其广泛的技术之一[1], 目前应用比较普遍 的几种分类方法中,朴素贝叶斯[2]在处理分类问题上简单 高效,是机器学习和数据挖掘中一个重要的算法。朴素贝叶斯算法是机器学习和数据挖掘中被广泛应 用的一种分类算法[3],,它先基于贝叶斯定理和属性条件独 立性假设来计算待判样本属于各类的条件概率,再将其判别为概率最大的那一类。[4]

基本思想及理论

        与其他绝大部分机器学习分类算法不同,贝叶斯分类器并不是直接学习特征输出类别Y与x之间的关系来进行分类,而是找出输出类别Y与特征之间的联合分布函数P(X,Y),然后利用贝叶斯公式获得分类的结果。贝叶斯分类是在概率框架下实施决策,在概率已知的理想情况下,利用概率和损失来标识数据类别。其中比较常用的朴素贝叶斯分类器是基于特征条件相互独立的条件下利用贝叶斯公式进行分类。主要步骤为在训练集中基于特征相互独立的条件输出联合概率分布;在此基础上,对于输入的样本x,输出后验概率较大的类别y。

        在通常的模式识别问题中,我们的目标都是事错误率最小化。利用概率论的贝叶斯公式,可以获得使错误率最小的分类决策,即最小错误率贝叶斯决策。概率中贝叶斯公式为

p(\omega _{i} |x)=\frac{p(x|\omega _{i}))}{p(x))},i=1,2...

p(\omega _{i})是先验概率;p(x,\omega _{i})是x与的联合概率密度;p(x)为总体密度;p(x|\omega _{i})是类条件密度。贝叶斯决策是在类条件概率密度和先验概率已知的情况下,通过贝叶斯公式计算后验概率,以后验概率最大的类别为样本的类别。朴素贝叶斯分类是通过计算条件概率实现分类预测,条件概率计算的理论依据是贝叶斯定理[5]。

样本有n种类型标记,即y=w^{_{1}},w_{2},...,w_{i}\lambda _{ij}是将真w_{j}误分类为w_{i}所造成的损失,利用后验概率P(w_{i}|x)可以求得样本x分成的期望损失R(w_{i}|x)=\sum_{j=1}^{n}\lambda _{ij}P(w_{j}|x),即条件风险,对于整个数据样本集,样本集总风险R(h)=E_{x}[R(w_{i}|x)],也就是条件风险的期望。分类器的目的是最小化样本数据集的总体风险,倘若每一个样本的条件风险都最小,那么总体风险也就会最小。这也就是贝叶斯判定准则:在每一个样本上都以条件风险最小的类型为类型标定,即h^{*}(x)=arg min(P(w|x))。在实际的数据集中,需要从中获得样本x的先验概率和后验概率。先验概率依据大数定律直接通过训练集的频率计算出来,后验概率则需要通过极大似然估计来获得。

 

朴素贝叶斯分类器

朴素贝叶斯分类器基于“属性条件相互独立的”假设上。基于贝叶斯公式p(\omega _{i} |x)=\frac{p(x|\omega _{i}))}{p(x))},i=1,2...来判定样本属性需要求取先验概率p(\omega _{i})和类条件概率p(x|\omega _{i})。先验概率可以通过大数定理转化为频率,表示为P(w_{i})=\tfrac{\left | D \right |}{\left | D_{w} \right |}D_{w}表示为训练集D中第w类样本的集合。

对于后验概率常用策略是假设数据集服从一定的概率分布,在训练集上利用已知样本对参数进行估计。假设P(x|w_{i})具是被参数唯一确定的形式,可以利用训练集D估计参数.基于朴素贝叶斯分类所有样本独立同分布的假设,利用极大似然估计可以获得P(D_{w}|\theta _{c})=\prod_{}^{}P(x|\theta _{w}),使用对数似然L(\theta _{w})=log(P(D_{w})|\theta _{w})=\sum_{}^{}log(P(x|\theta _{w})),此时参数的极大似然估计就为\theta _{w}=argminL(\theta _{w}).在实际分类器中,离散数据的后验概率为P(x_{_{i}}|w)=\tfrac{\left | D_{w,i} \right |}{\left | D_{w} \right |},其中D_{w,i}表示第i个属性上取值为的集合大小。如果是连续性的数据的话,则考虑其服从正态分布,\mu _{w,x}代表第w类样本在第i个属性上的均值,\sigma _{w,i}代表方差,也就是P(x_{i}|w)=\tfrac{1}{\sqrt{2\pi }\sigma _{ij}}exp(-\tfrac{x_{i}-\mu _{w,i}}{2\sigma _{w,i}^{2}})

朴素贝叶斯算法流程

1、确定分类的类型和特征属性,量化所有的特征属性,将总样本按照一定的比例分成训练集和验证集。假设此时训练集由m个样本,n个特征属性,一共可以分为k个类别,每个类别的样本数量为m_{1},m_{2},...,m_{i}类别标记为w。

2、计算此时k个类别的先验概率:

P(Y=w_{k})=\tfrac{m_{k}+\lambda }{\sum_{i=1}^{n}m_{i}+\lambda }

3、计算第k个类别的第j个特征的第i个取值的条件概率,一般情况下建立概率密度函数,认为后验概率服从正态分布,即P(x_{i}|w)=\tfrac{1}{\sqrt{2\pi }\sigma _{ij}}exp(-\tfrac{x_{i}-\mu _{w,i}}{2\sigma _{w,i}^{2}}),求解出方差\sigma _{w,i}和均值\mu _{w,x}

4、对于测试集中的样本x,分别计算其在各个类别中的概率即P(x=w_{k})=P(y=w_{k})\prod_{j=1}^{n}p(x|w_{i})

5、在计算完样本x所有类别的概率后,选择概率最大的类别作为样本的类别特征w_{x}=argmaxp(x=w_{i}),i=1,2,..,k

贝叶斯分类器的python代码实现

基于贝叶斯算法的流程,可以编写出相应的代码。分为三个基本部分,计算类型的先验概率,和对应的条件概率、方差、均值;获取测试样本的条件概率,计算后验概率;将测试样本概率可能性最大的类别作为判断的类型。具体代码已经放在附录了。

参考文献

[1]刘红岩,陈剑,陈国青.数据挖掘中的数据分类算法综述[J].清华大 学学报(自然科学版),2002,(6).

[2]郭勋诚.朴素贝叶斯分类算法应用研究[J].通讯世界,2019,26(1)

[3]李琼阳,田萍.基于主成分分析的朴素贝叶斯算法在垃圾短信用户 识别中的应用[J].数学的实践与认识,2019,49(1)

[4]基于改进PCA的朴素贝叶斯分类算法 李思奇; 吕王勇; 邓柙; 陈雯 统计与决策 [J] 2021-12-06

[5]毛国君,段立娟.数据挖掘原理与算法[M].北京: 清华大学出版社,2015: 138-139.

[6]https://blog.csdn.net/qq_38163244/article/details/109144003

[7]https://blog.csdn.net/a16111597162163/article/details/101646332

#代码来自​https://blog.csdn.net/a16111597162163/article/details/101646332​,我将其调整使其可以正常运行。
import numpy as np
import pandas as pd
class NaiveBayes():def __init__(self):self._X_train = Noneself._y_train = Noneself._classes = Noneself._priorlist = Noneself._meanmat = Noneself._varmat = Nonedef fit(self, X_train, y_train):self._X_train = X_trainself._y_train = y_train#  得到各个类别self._classes = np.unique(self._y_train)                      priorlist = []#生成与样本特征数相同的零矩阵meanmat0 = np.zeros((1,self._X_train.shape[1]))      varmat0 = np.zeros((1,self._X_train.shape[1]))for i, c in enumerate(self._classes):# 计算每个种类的平均值,方差,先验概率# 属于某个类别的样本组成的“矩阵”X_Index_c = self._X_train[np.where(self._y_train == c)] # 计算类别的先验概率priorlist.append(X_Index_c.shape[0] / self._X_train.shape[0]) # 计算该类别下每个特征的均值,结果保持二维状态[[3 4 6 2 1]]X_index_c_mean = np.mean(X_Index_c, axis=0, keepdims=True) # 方差X_index_c_var = np.var(X_Index_c, axis=0, keepdims=True)# 各个类别下的特征均值矩阵罗成新的矩阵,每行代表一个类别。meanmat0 = np.append(meanmat0, X_index_c_mean, axis=0)         varmat0 = np.append(varmat0, X_index_c_var, axis=0)self._priorlist = priorlist#除去开始多余的第一行self._meanmat = meanmat0[1:, :]                                   self._varmat = varmat0[1:, :]def predict(self,X_test):# 防止分母为0eps = 1e-10#用于存放测试集中各个实例的所属类别classof_X_test = []                                               for x_sample in X_test:#将每个实例沿列拉长,行数为样本的类别数matx_sample = np.tile(x_sample,(len(self._classes),1))         mat_numerator = np.exp(-(matx_sample - self._meanmat) ** 2 / (2 * self._varmat + eps))mat_denominator = np.sqrt(2 * np.pi * self._varmat + eps)# 每个类别下的类条件概率取对数后相加list_log = np.sum(np.log(mat_numerator/mat_denominator),axis=1)# 加上类先验概率的对数prior_class_x = list_log + np.log(self._priorlist)             # 取对数概率最大的索引prior_class_x_index = np.argmax(prior_class_x)     # 返回一个实例对应的类别classof_x = self._classes[prior_class_x_index]                 classof_X_test.append(classof_x)return classof_X_testdef score(self, X_test, y_test):j = 0for i in range(len(self.predict(X_test))):if self.predict(X_test)[i] == y_test[i]:j += 1return ('accuracy: {:.10%}'.format(j / len(y_test)))
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split,cross_val_score
dataSet=load_breast_cancer()data=dataSet.data#获取数据集
label=dataSet.target#标签
x_train,x_test,y_train,y_test=train_test_split(data,label,test_size=0.2)
forcast = NaiveBayes()
forcast.fit(x_train,y_train)
print(forcast.predict(x_test))
print(forcast.score(x_test,y_test))from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
clf.fit(x_train,y_train)
clf.predict(x_test)
clf.score(x_test,y_test)


http://chatgpt.dhexx.cn/article/aYTopTa7.shtml

相关文章

栈和队列、

目录 1、栈: 1.1、栈的概念及结构: 1.2、栈的实现: 1.2.1、test.c源文件: 1.2.2、Stack.c源文件: 1.2.3、Stack.h头文件: 1.3、例题1: 2、队列: 2.1、队列的概念及结构&…

栈和队列——表达式求值大全

表达式求值 一.关于三种表达式的分类 中缀表达式:即我们最为常见的表达式,运算符号位于参与运算的连个操作数中间的表达式称作中缀表达式前缀表达式:前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将…

栈与队列-

基础 stl中栈和队列不是容器,而是容器适配器。它们提供接口,由其他容器实现。 20. 有效的括号 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否…

数据结构----栈和队列

xdm这玩意我不会导入,只能截图了。 目录 栈篇 1.1栈 1.2.栈操作数据元素的两种动作: 2.代码实现 2.1初始化和销毁 2.2插入 2.3删除和判空 2.4返回栈顶值,计算栈长 队列篇 3.1队列 4.代码实现 4.1初始化和销毁和判空 4.2入列 4.3出列 4.4…

栈(Stack)和队列(Queue)详解

1. 什么是栈,栈存储结构详解 同顺序表和链表一样,栈也是用来存储逻辑关系为 “一对一” 数据的线性存储结构,如图 1 所示。 图 1 栈存储结构示意图 从图 1 我们看到,栈存储结构与之前所学的线性存储结构有所差异,这缘…

栈和队列--栈

1、顺序栈 一组地址连续的存储单元加一个标识栈顶元素的指针。 #define MaxSize 50 //定义栈中最大元素个数 typedef struct{ ElemType data[MaxSize];//存放栈中的元素int Top;//栈顶指针 }SqStack;栈空:s.top-1 栈满:s.topMaxSize-1 栈长&#xff…

什么是栈?什么是队列?栈与队列的特点

栈 栈(Stack)是限定在仅在表尾插入的线性表。 因此对于栈来说,表尾具有特殊的含义。我们把表尾称作栈顶(top),把表头称作栈底(bottom)。不含元素的栈称为空栈。 想象一下进栈的顺序…

栈和队列——相关例题

文章目录 一、栈例题——模拟栈具体实现1. 模板1.1 代码注解1.2 实现代码 2. STL2.1 代码注解2.2 实现代码 二、栈例题——表达式求值具体实现1. 实现思路2. 代码注解3. 实现代码 三、单调栈例题——单调栈具体实现1. 实现思路2. 实现代码 四、队列例题——模拟队列具体实现1. …

【栈和队列】

大家好,这里是针对栈和队列做的一些总结归类,主要是介绍了栈和队列的相关操作,特意整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步! 文章目录 一:栈1.1 栈的概念及结构1.2 栈的实现1.3 典型案例…

栈、队列

顺序栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈项元素在顺序栈中的位置。通常的习惯做法是以top=0表示空栈,鉴于C语言中数组的下标约定从0开始,则当以C…

栈、队列、数组

栈 定义 #include <stdio.h>/* 栈只允许在栈顶插入删除操作的线性表Last Insert First Out. */// 顺序栈#define MaxSize 10typedef struct {int data[MaxSize]; // 静态数组存放栈元素int top; // 栈顶指针 } SqStack; 栈顶指针指向栈顶元素的栈 空为-1 // 栈顶指针指…

使用SQL进行两个表关联查询(inner)

结果显示 公司类型表 公司表 实现方式 SELECTt_company.id,cName, typeName, cDescribe, t_company.modifyTime, t_company.createTime FROMt_company INNER JOIN t_company_type ON t_company.cType t_company_type.id代码解析 SELECT 显示字段,如果两个表都有字段,则需要…

sql进行两个关联表,根据其中一个表的一个属性进行条件查询查询

我最近遇到了表的查询,但是通过查询发现,网上的sql的大神,写的文章到底是什么玩意? 我打算自己写一个sql专栏,特意讲解sql的使用,来帮助大家 这篇文章技术指导为sql进行两个关联表,根据其中一个表的一个属性进行条件查询查询 假设只有两张表,其中一张表最后一个外键连…

SQL关联查询详解,SQL JOIN详解

关联查询&#xff0c;也称为多表查询&#xff0c;指两个或更多个表一起完成查询操作。 前提条件&#xff1a;这些一起查询的表之间是有关系的&#xff08;一对一、一对多&#xff09;&#xff0c;它们之间一定是有关联字段&#xff0c;这个关联字段可能建立了外键&#xff0c;也…

SQL-多表关联查询详解

为了在工作中能更顺利的使用多表关联查询&#xff0c;今天这篇博客就写这个内容了。 在讲解多表关联查询之前&#xff0c;先生成测试表。 登录scott用户&#xff0c;运行以下语句生成测试表。 create table ex1 as select * from emp; create table ex2 as select * from dept…

Mysql如何对两张表的相同字段,同时查询两张数据表

前言 假设现在有两张数据表 表1如下&#xff1a; 表2如下&#xff1a; 表1和表2同时都再mysql的情况下&#xff0c;只有他们的uuid是一样的&#xff0c;其他字段信息不同&#xff0c;现在需要用sql语句根据uuid&#xff0c;同时将符合要求的数据查询出来&#xff0c;怎么做呢&…

SQL- join多表关联

一、SQL 连接(JOIN) 1、笛卡尔积 &#xff08;1&#xff09;当多张表进行连接查询&#xff0c;没有任何条件限制的时候&#xff0c;最终查询结果条数&#xff0c;是多张表条数的乘积 如A表15条&#xff08;行&#xff09;数据&#xff0c;B表20条&#xff08;行&#xff09;…

SQL语言多表关联查询

新建两张表&#xff1a; 表1&#xff1a;student 截图如下&#xff1a; 表2&#xff1a;course 截图如下&#xff1a; &#xff08;此时这样建表只是为了演示连接SQL语句&#xff0c;当然实际开发中我们不会这样建表&#xff0c;实际开发中这两个表会有自己不同的主键。&…

[转载]静息态fMRI、DTI、VBM

[转载]静息态fMRI、DTI、VBM (2014-06-19 19:00:15) 转载▼ 标签&#xff1a; 转载 分类&#xff1a; fMRI-EEG 原文地址&#xff1a;静息态fMRI、DTI、VBM作者&#xff1a;426l 一、 简介 1、静息态fMRI数据处理学习内容 BOLD-fMRI技术自1990年发明至今&#xff0c;已经成…