Python3 实现朴素贝叶斯分类

article/2025/10/15 20:05:02

Python3 实现朴素贝叶斯分类

  • 贝叶斯定理
  • 朴素贝叶斯
  • 源代码
  • 样例测试

贝叶斯定理

贝叶斯定理是由已知事件概率和条件概率计算未知条件概率的概率推理算法,其公式如下:
贝叶斯公式
其中,P(Bi|A)是要计算的目标条件概率,表示事件 A 发生的条件下,事件 Bi 发生的概率。Bi 为互斥且完整的事件 B1,B2,……,Bn 中的一项
P(Bi)P(A|Bi)是联合概率P(A Bi),表示事件 A 和事件 Bi 同时发生的概率
nj=1P(Bj)P(A|Bj)的结果为随机事件 A 发生的概率

贝叶斯分类算法是贝叶斯定理在统计学中的一项应用,基于贝叶斯分类算法实现的贝叶斯分类器是可以媲美决策树和人工神经网络分类的强大分类器,具有方法简单、准确率高、速度快的特点

朴素贝叶斯

朴素贝叶斯分类是基于特征条件独立假设下的贝叶斯分类算法,它和决策树分类是目前应用最为广泛的两个分类模型
特征条件独立假设,即假定实例的各个属性互相独立,互不影响

假设有 n 个类别 C1,C2,……,Cn,给定一个实例的特征向量 w,则此实例属于类 Ci 的概率为
朴素贝叶斯分类公式
P(w|Ci)的计算:
w 是特征向量,若将其展开,则可将P(w|Ci)写作P(w0,w1,w2,…,wn|Ci),由特征条件独立的假设,即有如下运算

P(w|Ci) = P(w0|Ci)P(w1|Ci)P(w2|Ci)…P(wn|Ci)

朴素贝叶斯分类基于特征独立假设的条件,但现实世界中各属性之间往往不是互相独立的,或多或少都存在互相依赖的关系。但即使是在这样的条件下,朴素贝叶斯分类仍然可以得到较为接近真实情况的分类结果

源代码

下面是我用 Python3.7 写的一个朴素贝叶斯的分类器

# naive_bayes.py  -- 朴素贝叶斯import mathclass NB():def __init__(self):self.cla_all_num = 0self.cla_num = {}self.cla_tag_num = {}self.landa = 1  # 拉普拉斯修正值def train(self, taglist, cla):  # 训练,每次插入一条数据# 插入分类self.cla_all_num += 1if cla in self.cla_num:  # 是否已存在该分类self.cla_num[cla] += 1else:self.cla_num[cla] = 1if cla not in self.cla_tag_num:self.cla_tag_num[cla] = {}  # 创建每个分类的标签字典# 插入标签tmp_tags = self.cla_tag_num[cla]  # 浅拷贝,用作别名for tag in taglist:if tag in tmp_tags:tmp_tags[tag] += 1else:tmp_tags[tag] = 1def P_C(self, cla):  # 计算分类 cla 的先验概率return self.cla_num[cla] / self.cla_all_numdef P_all_C(self):  # 计算所有分类的先验概率tmpdict = {}for key in self.cla_num.keys():tmpdict[key] = self.cla_num[key] / self.cla_all_numreturn tmpdictdef P_W_C(self, tag, cla):  # 计算分类 cla 中标签 tag 的后验概率tmp_tags = self.cla_tag_num[cla]  # 浅拷贝,用作别名if tag not in self.cla_tag_num[cla]:return self.landa / (self.cla_num[cla] + len(tmp_tags) * self.landa)  # 拉普拉斯修正return (tmp_tags[tag] + self.landa) / (self.cla_num[cla] + len(tmp_tags) * self.landa)def test(self, test_tags):  # 测试res = ''res_P = Nonefor cla in self.cla_num.keys():log_P_W_C = 0for tag in test_tags:log_P_W_C += math.log(self.P_W_C(tag, cla))tmp_P = log_P_W_C + math.log(self.P_C(cla))  # P(w|Ci) * P(Ci)if res_P is None:res = clares_P = tmp_Pif tmp_P > res_P:res = clares_P = tmp_Preturn resdef set_landa(self, landa):self.landa = landadef clear(self):  # 重置模型self.cla_all_num = 0self.cla_num.clear()self.cla_tag_num.clear()

这里有几个需要注意的点:

零概率问题:
零概率问题,即测试样例的标签属性中,出现了模型训练过程中没有记录的值,或者某个分类没有记录的值,从而出现该标签属性值的出现概率 P(wi|Ci) = 0 的现象。因为 P(w|Ci) 等于各标签属性值 P(wi|Ci) 的乘积,当分类 Ci 中某一个标签属性值的概率为 0,最后的 P(w|Ci) 结果也为 0。很显然,这不能真实地代表该分类出现的概率

解决方法:
拉普拉斯修正,又叫拉普拉斯平滑,这是为了解决零概率问题而引入的处理方法。其修正过程:
拉普拉斯修正
在源码中的体现:

def P_W_C(self, tag, cla):  # 计算分类 cla 中标签 tag 的后验概率tmp_tags = self.cla_tag_num[cla]  # 浅拷贝,用作别名if tag not in self.cla_tag_num[cla]:return self.landa / (self.cla_num[cla] + len(tmp_tags) * self.landa)  # 拉普拉斯修正return (tmp_tags[tag] + self.landa) / (self.cla_num[cla] + len(tmp_tags) * self.landa)

浮点数溢出问题:
在计算 P(w|Ci) 时,各标签属性概率的值可能很小,而很小的数再相乘,可能会导致浮点数溢出

解决方法:
对 P(w|Ci) 取对数,把概率相乘转换为相加
概率取对数
在源码中的体现:

for cla in self.cla_num.keys():log_P_W_C = 0for tag in test_tags:log_P_W_C += math.log(self.P_W_C(tag, cla))tmp_P = log_P_W_C + math.log(self.P_C(cla))  # P(w|Ci) * P(Ci)

在这里,因为概率 P(w|Ci) 的值为小于 1 的小数,取对数后的结果 log_P_W_C 为负值,不能直接与 P(Ci) 相乘。否则,可能出现相反的结果
不妨把 P(Ci) 的值也取对数,结果相加。因为对数是单调曲线,这并不影响最后的决策结果

样例测试

有如下样例,
测试数据集
这里共有两个分类: “买了电脑” 和 “未买电脑”
每个训练实例有 4 个属性: “年龄”,“收入”,“是否学生”,“信用等级”

训练模型的代码如下:


if __name__ == '__main__':nb = NB()  # 生成模型# 训练模型# 年龄,收入,是否学生,信用等级  --->  是否买了电脑nb.train(['<30', '高', '否', '一般'], '否')nb.train(['<30', '高', '否', '好'], '否')nb.train(['30-40', '高', '否', '一般'], '是')nb.train(['>40', '中', '否', '一般'], '是')nb.train(['>40', '低', '是', '一般'], '是')nb.train(['>40', '低', '是', '好'], '否')nb.train(['30-40', '低', '是', '好'], '是')nb.train(['<30', '中', '否', '一般'], '否')nb.train(['<30', '低', '是', '一般'], '是')nb.train(['>40', '中', '是', '一般'], '是')nb.train(['<30', '中', '是', '好'], '是')nb.train(['30-40', '中', '否', '好'], '是')nb.train(['30-40', '高', '是', '一般'], '是')nb.train(['>40', '中', '否', '好'], '否')

模型训练好了

我们再给出一个测试实例:(年龄<30,收入中等,是学生,信用一般)

测试模型的代码如下:

	# 测试模型testdata = ['<30', '中', '是', '一般']print('测试结果:', nb.test(testdata))

运行结果:
运行结果
结果显示,Ta 买了电脑

再计算验证一下

w = ( 年龄 <30,收入中等,是学生,信用一般 )
P(w|Ci) = P(w0|Ci) ) * P(w1|Ci) * P(w2|Ci) * P(w3|Ci)

计算 P(w|买了电脑) :

P( 买了电脑 ) = 9/14 = 0.643
P( 年龄<30 | 买了电脑 ) = 2/9 = 0.222
P( 收入中等 | 买了电脑 ) = 4/9 = 0.444
P( 是学生 | 买了电脑 ) = 6/9 = 0.667
P( 信用一般 | 买了电脑 ) = 6/9 = 0.667
P( w | 买了电脑 ) = 0.222 * 0.444 * 0.667 * 0.667 = 0.044
P( w | 买了电脑 ) * P( 买了电脑 ) = 0.044 * 0.643 = 0.028

计算 P(w| 未买电脑 ) :

P( 未买电脑 ) = 5/14 = 0.357
P( 年龄<30 | 未买电脑 ) = 3/5 = 0.600
P( 收入中等 | 未买电脑 ) = 2/5 = 0.400
P( 是学生 | 未买电脑 ) = 1/5 = 0.200
P( 信用一般 | 未买电脑 ) = 2/5 = 0.400
P( w | 未买电脑 ) = 0.6 * 0.4 * 0.2 * 0.4 = 0.019
P( w | 未买电脑 ) * P( 未买电脑 ) = 0.019 * 0.357 = 0.007

则有,
P( 买了电脑 | w ) = P( w | 买了电脑 ) * P( 买了电脑 ) / P(w) = 0.028 / P(w)
P( 未买电脑 | w ) = P( w | 未买电脑 ) * P( 未买电脑 ) / P(w) = 0.007 / P(w)

很显然 P( 买了电脑 | w ) > P( 未买电脑 | w ) ,结果是买了电脑


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

相关文章

浅谈贝叶斯分类

贝叶斯分类 贝叶斯分类是一类分类算法的总称&#xff0c;以贝叶斯定理为基础。其中我们较为熟悉的朴素朴素贝叶斯分类是贝叶斯分类中最简单&#xff0c;也是常见的一种分类方法。 贝叶斯网络 贝叶斯网络是一种概念图模型。概率图模型就是用图论和概率论的知识&#xff0c;利…

基于Python实现的图片贝叶斯分类器分类

使用流程及应用展示&#xff1a; 1. 选择图片&#xff1a; 控制台版本从命令行输入 当直接回车时将读取默认路径图片&#xff08;./assets/生活照-武.jpg&#xff09;,相对路径是从打开程序的文件夹开始的&#xff0c;若输入路径无效或不可读将继续询问输入 GUI 从文件浏览器…

【贝叶斯分类4】贝叶斯网

文章目录 1. 半朴素贝叶斯分类器知识回顾2. 贝叶斯网学习笔记2.1 引言2.2 知识卡片2.3 概率图模型(PGM)2.3.1 引言2.3.2 为什么引入概率图?2.3.3 概率图的三个基本问题&#xff08;表示&#xff0c;学习&#xff0c;推断&#xff09; 2.4 贝叶斯网2.4.1 贝叶斯网的表达2.4.2 结…

机器学习算法-朴素贝叶斯分类

机器学习算法--朴素贝叶斯分类 引入贝叶斯决策论条件概率和全概率公式贝叶斯推断和朴素贝叶斯推断拉普拉斯平滑 代码实例1、言论过滤器2、垃圾邮件过滤器 代做 引入 贝叶斯决策论(Bayesian decision theory)是概率论框架下实施决策的基本方法。对分类任务来说&#xff0c;在所有…

【ML】贝叶斯分类和朴素贝叶斯分类

一、介绍 贝叶斯定理是英国数学家托马斯贝叶斯提出的&#xff0c;为了解决一个“逆概率”问题。 贝叶斯分类是一类分类算法的总称&#xff0c;这类算法均以贝叶斯定理为基础&#xff0c;故统称为贝叶斯分类。而朴素贝叶斯分类是贝叶斯分类中最简单&#xff0c;也是常见的一种…

机器学习之朴素贝叶斯分类

朴素贝叶斯分类 贝叶斯定理和基础概率论朴素贝叶斯高斯朴素贝叶斯&#xff0c;多项式朴素贝叶斯&#xff0c;伯努利朴素贝叶斯的区别几种朴素贝叶斯实战总结 贝叶斯定理和基础概率论 概率&#xff0c;其实在我们生活中十分常见&#xff0c;它是对未来事件发生可能性的表述&…

机器学习--朴素贝叶斯分类函数

一、前言 朴素贝叶斯算法是有监督的学习算法&#xff0c;解决的是分类问题&#xff0c;如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但由于该算法以自变量之间的独…

机器学习之贝叶斯算法图像分类

数据集&#xff1a;数据集采用Sort_1000pics数据集。数据集包含1000张图片&#xff0c;总共分为10类。分别是人(0)&#xff0c;沙滩&#xff08;1&#xff09;&#xff0c;建筑&#xff08;2&#xff09;&#xff0c;大卡车&#xff08;3&#xff09;&#xff0c;恐龙&#xff…

使用 Python 进行朴素贝叶斯分类

定义 在机器学习中&#xff0c;贝叶斯分类器是一种简单的概率分类器&#xff0c;它基于应用贝叶斯定理。朴素贝叶斯分类器使用的特征模型做出了很强的独立性假设。这意味着一个类的特定特征的存在与其他所有特征的存在是独立的或无关的。 独立事件的定义&#xff1a; 两个事件…

数据分类《二》贝叶斯分类

本博客是参考《数据仓库与数据挖掘技术》以及诸多道友的blog。仅作为自己学习的一个总结。 贝叶斯分类是一种基于统计学的分类方法&#xff0c;可以预测一个类成员关系的可能性。数据挖掘主要使用两种分类&#xff0c;朴素贝叶斯和贝叶斯网络方法。前者使用贝叶斯进行预测&…

贝叶斯分类及其代码

学期末的综述报告我选择了贝叶斯分类&#xff0c;既然已经写了就将它分享一下。 主要目的就是以教促学。 如有问题欢迎在评论区进行讨论。 随着现代社会信息技术的发展&#xff0c;对于数据的挖掘越来越重要&#xff0c;分类是数据挖掘中应用领域极其广泛的技术之一[1]&#…

栈和队列、

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

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

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

栈与队列-

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

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

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

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

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

栈和队列--栈

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

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

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

栈和队列——相关例题

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

【栈和队列】

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