朴素贝叶斯

依旧是基于头歌的,

不知道为什么总是有点对数学的蒙圈在里面,可能高中数学的乐色程度被严重低估了吧

一。条件概率

什么是条件概率

概率指的是某一事件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. 任务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(Aj​B)​=∑i=1n​P(Ai​)P(B∣Ai​)P(Aj​)P(B∣Aj​)​

称为贝叶斯公式(贝叶斯定理)。

全概率公式

定义:设A1​,A2​,⋯,An​ 为完备事件组, P(Ai​)>0(i=1,2,⋯,n),则

P(B)=i=1∑n​P(Ai​)P(B∣Ai​)

称为全概率公式。

编程要求

根据提示,在右侧编辑器Begin-End部分补充代码。

任务描述:假设我们现在有 10 个盒子,每个盒子中都放了不同数量的苹果和橙子。每次实验的时候会随机从某个盒子里挑出一个水果,选择每个盒子的概率不同。

  1. 任务1:根据全概率公式,求挑出的水果是橙子的概率;提示:numpy.sum(a) 可实现对数组 a 求和。
  2. 任务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(Ai1​​Ai2​​⋯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=1n​P(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∏n​P(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. 任务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​∈yargmax​P(yi​∣x)

其中,i=1,2,…,k 。

基于特征条件独立性假设,贝叶斯公式可写为

P(yi​∣x)=P(x)P(yi​)P(x∣yi​)​=P(x)P(yi​)​j=1∏n​P(xj​∣yi​)

由于对所有类别来说 P(x) 相同,因此贝叶斯判定准则有

yi​∈yargmax​P(yi​)j=1∏n​P(xj​∣yi​)

这就是朴素贝叶斯分类器的表达式。

离散型朴素贝叶斯分类器求解步骤:

令 Dyi​​ 表示训练集 D 中第 yi​ 类样本组成的集合,若有充足的独立同分布样本,则可容易地估计出类先验概率

P(yi​)=∣D∣∣Dyi​​∣​

对离散属性而言,令 Dyi​,xj​​ 表示 Dyi​​ 中在第 j 个属性上取值为 xj​ 的样本组成的集合,则条件概率 P(xj​∣yi​) 可估计为

P(xj​∣yi​)=∣Dyi​​,xj∣/∣​Dyi​​​∣

最后求

yi​∈yargmax​P(yi​)j=1∏n​P(xj​∣yi​)

编程要求

根据提示,在右侧编辑器Begin-End部分补充代码。

任务描述:假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1​,x2​,x3​,…,xn​),类标签集合含有 k 个类别,即 y=(y1​,y2​,…,yk​) 。给定样本 x′ ,使用Python语言编程,求样本 x′ 属于哪一个类别。

  1. 任务1:根据条件独立假设,求样本 xx 属于 i 类别的概率;提示:numpy.sum(a) 可实现对数组 a 求和;numpy.where(condition, x, y) 满足条件(condition),输出 x,不满足输出 y 。
  2. 任务2:根据离散型朴素贝叶斯判定准则,求样本 xx 属于哪个类别的概率最大。提示:numpy.argmax(array) 用于返回一个数组中最大值的索引值。

    类似第四种。其中要说一下类别中,找j。其中setx[i].shape[0]是在找第一类元素的个数。

  3. # 导入库
    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​∈yargmax​P(yi​)

编程要求

根据提示,在右侧编辑器Begin-End部分补充代码。

任务描述:假设给定训练数据集 (X,Y),其中每个样本 x 都包括 n 维特征,即 x=(x1​,x2​,x3​,…,xn​),类标签集合含有 k 个类别,即 y=(y1​,y2​,…,yk​) 。给定样本 x′ ,使用Python语言编程,求样本 x′ 属于哪一个类别。提示:此处特征为连续值,而非离散值,注意与上一节求解方法进行区分。

  1. 任务1:根据条件独立假设,求样本 xx 属于 i 类别的概率;
  2. 任务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)

 

 

  • 28
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值