朴素贝叶斯
依旧是基于头歌的,
不知道为什么总是有点对数学的蒙圈在里面,可能高中数学的乐色程度被严重低估了吧。
一。条件概率
什么是条件概率
概率指的是某一事件A发生的可能性,表示为P(A)。而条件概率指的是某一事件A已经发生了条件下,另一事件B发生的可能性,表示为P(B|A),举个例子:
今天有25%的可能性下雨,即P(下雨)=0.25; 今天75%的可能性是晴天,即P(晴天)=0.75; 如果下雨,我有75%的可能性穿外套,即P(穿外套|下雨)=0.75; 如果下雨,我有25%的可能性穿T恤,即P(穿T恤|下雨)=0.25;
从上述例子可以看出,条件概率描述的是|右边的事件已经发生之后,左边的事件发生的可能性,而不是两个事件同时发生的可能性!
怎样计算条件概率
设A,B是两个事件,且P(A)>0,称P(B|A)=P(AB)/P(A)为在事件A发生的条件下,事件B发生的条件概率。(其中P(AB)表示事件A和事件B同时发生的概率)
习题:
从1,2,...,15中小明和小红两人各任取一个数字,现已知小明取到的数字是5的倍数,请问小明取到的数大于小红取到的数的概率是多少?
解:分为三种情况
一小明拿到的数字为5:则小红可能取值为:1,2,3,4
二小明为10:则1~9为可能取值,
三为15:则1~14都可能。
则
P=1/3*((4+9+14)/14)=9/14
二。先验概率、后验概率
有点绕,需要细细地考量琢磨。
定义:设 A,B 为随机事件,且 P(A)>0 ,则有
P(B∣A)=P(A)P(AB)
称 (B∣A) 为在事件 A 发生的条件下,事件 B 发生的概率。
推论1:设 A,B 为随机事件,且 P(A)>0 ,则有
P(AB)=P(B∣A)P(A)=P(A∣B)P(B)
推论2:设 A,B 为随机事件,且 P(A)>0 ,则有
P(B∣A)=P(A∣B)P(B)/p(A)
先验概率:
是指根据以往经验和分析得到的概率,是“由因求果”的体现。在上述推论 2 中,先验概率是指 P(B) 。
说明B事件已经证明发生的概率
后验概率:指某件事已经发生,想要计算这件事发生的原因是由某个因素引起的概率,是“由果求因”的体现。在上述推论 2 中,后验概率是指 P(A∣B) 。
后验概率
说明在已发生的条件下另外一件事情是因为B事件而发生的概率
例如:
设 A 第一名同学没抽中,B 表示最后一名同学抽中。
-
最后一名同学抽到中奖券的概率是 P(B)=1/3。B从三选1,
-
如果已经知道第一个同学没抽中,那最后一名抽中的概率 P(B∣A)=P(A)P(AB)=1/2。B从剩下的2张中奖劵中选择1张
编程要求
根据提示,在右侧编辑器Begin-End部分补充代码。
任务描述:假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1,x2,x3,…,xn),类标签集合含有 k 个类别,即 y=(y1,y2,…,yk) 。使用Python语言编程,求先验概率(在训练集中类别 yi 出现的概率) P(yi) ,其中 i=1,2,…,k 。
- 任务1:计算每个标签的先验概率。提示:
numpy.sum(a)可实现对数组a求和;numpy.where(condition, x, y)满足条件(condition),输出x,不满足输出y。
# 导入库
import numpy as np
# 共 100 个样本,每个样本 x 都包括 5 个特征
np.random.seed(0)
x = np.random.randn(100, 5)
# 共 100 个样本,每个样本 y 都属于 {0,1,2,...,9} 类别中的一个
np.random.seed(0)
y = np.random.randint(0,10,100)
# 初始化先验概率,P[i] 表示类别 i 出现的概率
P = np.zeros(100)
# 任务1:计算每个标签的先验概率
########## Begin ##########
for i in range(10):
P[i] = np.sum(np.where(y==i,1,0))/100
########## End ##########
# 打印结果
for i in range(10):
print("类别 i 出现的概率为:", P[i])
可能一百个样本有点难看,不过没有办法 :
y:
[5 0 3 3 7 9 3 5 2 4 7 6 8 8 1 6 7 7 8 1 5 9 8 9 4 3 0 3 5 0 2 3 8 1 3 3 3
7 0 1 9 9 0 4 7 3 2 7 2 0 0 4 5 5 6 8 4 1 4 9 8 1 1 7 9 9 3 6 7 2 0 3 5 9
4 4 6 4 4 3 4 4 8 4 3 7 5 5 0 1 5 9 3 0 5 0 1 2 4 2]
类别i出现的概率嘛,那不就是y==i?!
三。贝叶斯与全概率公式
贝叶斯公式
定义:承接全概率公式,若已知 B 发生了,执果索因,有
P(Aj∣B)=P(B)P(AjB)=∑i=1nP(Ai)P(B∣Ai)P(Aj)P(B∣Aj)
称为贝叶斯公式(贝叶斯定理)。
全概率公式
定义:设A1,A2,⋯,An 为完备事件组, P(Ai)>0(i=1,2,⋯,n),则
P(B)=i=1∑nP(Ai)P(B∣Ai)
称为全概率公式。
编程要求
根据提示,在右侧编辑器Begin-End部分补充代码。
任务描述:假设我们现在有 10 个盒子,每个盒子中都放了不同数量的苹果和橙子。每次实验的时候会随机从某个盒子里挑出一个水果,选择每个盒子的概率不同。
- 任务1:根据全概率公式,求挑出的水果是橙子的概率;提示:
numpy.sum(a)可实现对数组a求和。 - 任务2:已知挑出的水果是橙子,根据贝叶斯公式,求是从第一个盒子挑出的概率。
# 导入库
import numpy as np
# 共 10 个盒子,b[i][0] 表示盒子 i 中的苹果数量,b[i][1] 表示盒子 i 中的橙子数量
np.random.seed(0)
b = np.random.randint(0,10,(10, 2))
# 共 10 个盒子,p[i] 表示盒子 i 被挑中的概率
p = np.array([0.1, 0.1, 0.05, 0.15, 0.08, 0.12, 0.09, 0.11, 0.06, 0.14])
# 初始化概率,P 表示挑出的水果是橙子的概率
P = 0
# 任务1:根据全概率公式,求挑出的水果是橙子的概率
########## Begin ##########
for i in range(10):
P +=p[i]*b[i][1]/np.sum(b[i])
########## End ##########
# 打印结果
print("挑出的水果是橙子的概率为:",P)
# 任务2:已知挑出的水果是橙子,根据贝叶斯公式,求是从第一个盒子挑出的概率
########## Begin ##########
P_1 = p[0]*b[0][1]/np.sum(b[0]/P
########## End ##########
# 打印结果
print("已知挑出的水果是橙子,是从第一个盒子挑出的概率为:", P_1)
老实说我还真的加深了只要限定seed一定,随机数一定的了解。虽然头歌有时候的表达让人云里雾里,爱恨交织,可是不得不承认,它的表达的数据不模糊的时候还是挺清晰的。以下是B的 取值:
[[5 0]
[3 3]
[7 9]
[3 5]
[2 4]
[7 6]
[8 8]
[1 6]
[7 7]
[8 1]]
四。条件独立假设
事件的独立性
定义1:设 A,B 为两个事件,如果 P(AB)=P(A)P(B),则称事件 A 与 B 相互独立,简称为 A 与 B 独立。
定义2:设 A1,A2,⋯,An 为 n(n⩾2) 个事件,如果对其中任意有限个事件 Ai1,Ai2,⋯,Aik(2⩽k⩽n) ,有
P(Ai1Ai2⋯Aik)=P(Ai1)P(Ai2)⋯P(Aik)
则称 n 个事件 A1,A2,⋯,An 相互独立。
条件独立假设
假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1,x2,x3,…,xn),类标签集合含有 k 个类别,即 y=(y1,y2,…,yk) 。
如果现在来了一个新样本 x ,我们要怎么判断它的类别?从概率的角度来看,这个问题就是给定 x,求它属于哪个类别的概率最大。
由贝叶斯公式,可知
P(yi∣x)=∑i=1nP(yi)P(x∣yi)P(yi)P(x∣yi)
先不管分母,分子中的 P(yi) 是先验概率,根据训练集就可以简单地计算出来。而条件概率 P(x∣yi)=P(x1,x2,…,xn∣yi),它的参数规模是指数数量级别的,显然不可行。
针对这个问题,朴素贝叶斯算法对条件概率分布作出了独立性的假设。通俗地讲就是,假设各个维度的特征 x1,x2,…,xn 互相独立,在这个假设的前提上,由定义 2,条件概率可以转化为:
P(x∣yi)=P(x1,x2,…,xn∣yi)=j=1∏nP(xj∣yi)
这样,根据训练集我们就可以求出 P(x∣yi) 。
编程要求
根据提示,在右侧编辑器Begin-End部分补充代码。
任务描述:假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1,x2,x3,…,xn),类标签集合含有 k 个类别,即 y=(y1,y2,…,yk) 。给定样本 x′ ,使用Python语言编程,
求样本 x′ 属于第一个类别的概率 P(x′∣y0) 。
- 任务1:根据条件独立假设,计算样本 xx 属于第一个类别的概率。提示:
numpy.sum(a)可实现对数组a求和;numpy.where(condition, x, y)满足条件(condition),输出x,不满足输出y。
# 导入库
import numpy as np
# 共 100 个样本,每个样本 x 都包括 5 个特征
np.random.seed(0)
x = np.random.randint(0,2,(100, 5))
# 共 100 个样本,每个样本 x 都属于 {0,1} 类别中的一个
np.random.seed(0)
y = np.random.randint(0,2,100)
# 给定 xx = [0,1,0,1,1]
xx = np.array([0,1,0,1,1])
# setx_0 表示属于第一个类别的 x 的集合
setx_0 = x[np.where(y==0)]
# 初始化 p_0,p_0 表示 xx 属于类别 0 的概率
p_0 = setx_0.shape[0] / 100
# 任务1:根据条件独立假设,求样本 xx 属于第一个类别的概率
########## Begin ##########
for i in range(5):
p_0 = p_0*np.sum(np.where(setx_0[:,i]==xx[i],1,0))/setx_0.shape[0]
########## End ##########
# 打印结果
print("样本 xx = [0,1,0,1,1] 属于类别 0 的概率为:", p_0)
学过numpy的应该都有印象,因为 np.array[:,i]只表示第i列元素,故求属于第一类别概率就是在5维特征里找啦。
五。离散型朴素贝叶斯分类器
假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,,即 x=(x1,x2,x3,…,xn),类标签集合含有 k 个类别,即 y=(y1,y2,…,yk) 。
如果现在来了一个新样本 x ,我们要怎么判断它的类别?从概率的角度来看,这个问题就是给定 x,求它属于哪个类别的概率最大,即
yi∈yargmaxP(yi∣x)
其中,i=1,2,…,k 。
基于特征条件独立性假设,贝叶斯公式可写为
P(yi∣x)=P(x)P(yi)P(x∣yi)=P(x)P(yi)j=1∏nP(xj∣yi)
由于对所有类别来说 P(x) 相同,因此贝叶斯判定准则有
yi∈yargmaxP(yi)j=1∏nP(xj∣yi)
这就是朴素贝叶斯分类器的表达式。
离散型朴素贝叶斯分类器求解步骤:
令 Dyi 表示训练集 D 中第 yi 类样本组成的集合,若有充足的独立同分布样本,则可容易地估计出类先验概率
P(yi)=∣D∣∣Dyi∣
对离散属性而言,令 Dyi,xj 表示 Dyi 中在第 j 个属性上取值为 xj 的样本组成的集合,则条件概率 P(xj∣yi) 可估计为
P(xj∣yi)=∣Dyi,xj∣/∣Dyi∣
最后求
yi∈yargmaxP(yi)j=1∏nP(xj∣yi)
编程要求
根据提示,在右侧编辑器Begin-End部分补充代码。
任务描述:假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1,x2,x3,…,xn),类标签集合含有 k 个类别,即 y=(y1,y2,…,yk) 。给定样本 x′ ,使用Python语言编程,求样本 x′ 属于哪一个类别。
- 任务1:根据条件独立假设,求样本 xx 属于 i 类别的概率;提示:
numpy.sum(a)可实现对数组a求和;numpy.where(condition, x, y)满足条件(condition),输出x,不满足输出y。 - 任务2:根据离散型朴素贝叶斯判定准则,求样本 xx 属于哪个类别的概率最大。提示:
numpy.argmax(array)用于返回一个数组中最大值的索引值。类似第四种。其中要说一下类别中,找j。其中setx[i].shape[0]是在找第一类元素的个数。
-
# 导入库 import numpy as np # 共 100 个样本,每个样本 x 都包括 5 个特征 np.random.seed(0) x = np.random.randint(0,2,(100, 5)) # 共 100 个样本,每个样本 x 都属于 {0,1} 类别中的一个 np.random.seed(0) y = np.random.randint(0,2,100) # 给定 xx = [0,1,0,1,1] xx = np.array([0,1,0,1,1]) setx = [] # setx[i] 表示属于类别 i 的 x 的集合 for i in range(2): setx.append(x[np.where(y==i)]) p = [] # 初始化 p,p[i] 表示 xx 属于类别 i 的概率 for i in range(2): p.append(setx[i].shape[0] / 100) # 任务1:根据条件独立假设,求样本 xx 属于 i 类别的概率 ########## Begin ########## for i in range(2): for j in range(5): p[i] = p[i]*np.sum(np.where(setx[i][:,j]==xx[j],1,0))/setx[i].shape[0] ########## End ########## # 任务2:根据离散型朴素贝叶斯判定准则,求样本 xx 属于哪个类别的概率最大 ########## Begin ########## label = np.argmax(p) ########## End ########## # 打印结果 print("样本 xx = [0,1,0,1,1] 属于类别", label)六。连续型朴素贝叶斯分类器
连续型朴素贝叶斯分类器求解步骤:
令 Dyi 表示训练集 D 中第 yi 类样本组成的集合,若有充足的独立同分布样本,则可容易地估计出类先验概率
P(yi)=∣D∣∣Dyi∣
对连续属性可考虑概率密度函数,假定 p(xj∣yi)∼N(μi,j,σi,j2),其中 μi,j 和 σi,j2 分别是第 i 类样本在第 j 个属性上取值的均值和方差,则有
最后求
yi∈yargmaxP(yi)
编程要求
根据提示,在右侧编辑器Begin-End部分补充代码。
任务描述:假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1,x2,x3,…,xn),类标签集合含有 k 个类别,即 y=(y1,y2,…,yk) 。给定样本 x′ ,使用Python语言编程,求样本 x′ 属于哪一个类别。提示:此处特征为连续值,而非离散值,注意与上一节求解方法进行区分。
- 任务1:根据条件独立假设,求样本 xx 属于 i 类别的概率;
- 任务2:根据连续型朴素贝叶斯判定准则,求样本 xx 属于哪个类别的概率最大。提示:
numpy.argmax(array)用于返回一个数组中最大值的索引值。# 导入库 import numpy as np # 共 100 个样本,每个样本 x 都包括 5 个特征 np.random.seed(0) x = np.random.randn(100, 5) # 共 100 个样本,每个样本 x 都属于 {0,1} 类别中的一个 np.random.seed(0) y = np.random.randint(0,2,100) # 给定 xx = [0,1,0,1,1] xx = np.array([0,1,0,1,1]) setx = [] # setx[i] 表示属于类别 i 的 x 的集合 for i in range(2): setx.append(x[np.where(y==i)]) p = [] # 初始化 p,p[i] 表示 xx 属于类别 i 的概率 for i in range(2): p.append(setx[i].shape[0] / 100) # 正态分布的概率密度函数 def normal(x, mean, std): return np.exp(-(x-mean)**2/(2*std**2))/(np.sqrt(2*np.pi)*std) # 任务1:根据条件独立假设,求样本 xx 属于 i 类别的概率 ########## Begin ########## for i in range(2): for j in range(5): mean = np.mean(setx[i][:, j]) std = np.std(setx[i][:, j]) p[i] = np.sum(np.where(y==i,1,0))/100 ########## End ########## # 任务2:根据连续型朴素贝叶斯判定准则,求样本 xx 属于哪个类别的概率最大 ########## Begin ########## label = np.argmax(xx) ########## End ########## # 打印结果 print("样本 xx = [0,1,0,1,1] 属于类别", label)
更多推荐



所有评论(0)