0
点赞
收藏
分享

微信扫一扫

机器学习理论之:(2)朴素贝叶斯详细解读、公式推导和实例演练

大师的学徒 2022-03-13 阅读 16

文章目录

回顾贝叶斯公式

P(Hx)=P(xH)P(H)P(x)P(H|x) = \frac{P(x|H)P(H)}{P(x)}

  • 这里的 HH 可以认为是在分类任务中的某个类,所以 P(Hx)P(H|x) 可以表示在给出 xx 的条件下,样本被判为第 CC 类的概率,这个概率也是我们称为的后验概率

贝叶斯公式的实例

  • 当你周一去一家商店,你发现所有的灯都是 off 的,你会做什么推断?

  • 先验概率 P(H)=P(open)=0.95P(H)=P(open)=0.95 即,通过统计数据,这家店开着的概率是 95%

  • 条件概率:

    • P(offopen)=0.01P(off|open)=0.01, 当店铺开张的时候,灯灭的概率为 0.01
    • P(offclosed)=0.85P(off|closed)=0.85 当店铺关闭的时候,灯灭的概率为 0.85
  • 求后验概率 P(openoff)P(open|off)

P(openoff)=P(offopen)P(open)P(off)P(open|off) = \frac{P(off|open)P(open)}{P(off)}

P(off)=P(off,open)+P(off,closed)=P(offopen)P(open)+P(offclosed)P(closed)P(off)=P(off,open) + P(off,closed) = P(off|open)P(open)+P(off|closed)P(closed)

P(openoff)=P(offopen)P(open)P(offopen)P(open)+P(offclosed)P(closed)P(open|off) = \frac{P(off|open)P(open)}{P(off|open)P(open)+P(off|closed)P(closed)}

P(openoff)=0.010.950.010.95+0.85(10.95)=0.183P(open|off) = \frac{0.01 * 0.95}{0.01 * 0.95 + 0.85 * (1-0.95)}=0.183

  • 贝叶斯公式允许我们计算 P(Hx)P(H|x)P(xH)P(x|H) 已知或者可以估算的时候

朴素贝叶斯分类器

  • 我们已经知道:

P(C,X)=P(CX)P(X)=P(XC)P(C)P(C,X)=P(C|X)P(X)=P(X|C)P(C)

分类器的任务

  • 我们现在的任务是:将样本 TT (instance)进行分类, cjCc_j \in C,我们需要依次求出这个样本 TT 对于每一类 cjc_j
    的概率,然后选出其中最大的那一个作为最终的预测类别。
    c^=argmaxcjCP(cjT)\hat{c}=argmax_{c_j\in C}P(c_j|T)

  • c^\hat{c} 代表的是最终分类的具体类别

  • argmaxcjCargmax_{c_j\in C} 代表从几个候选的概率中选出最大值作为最后的结果

  • P(cjT)P(c_j|T) 表示给定 TT 的条件下对 cjc_j 的分类概率

\because P(cjT)=P(Tcj)P(cj)P(T)P(c_j|T)=\frac{P(T|c_j)P(c_j)}{P(T)}
\therefore c^=argmaxcjCP(Tcj)P(cj)P(T)\hat{c}=argmax_{c_j\in C}\frac{P(T|c_j)P(c_j)}{P(T)}

扔掉分母

\because 对于所有的类别 cjCc_j\in C, P(T)P(T) 的值都是相同的,因此我们可以在这个计算的时候删除公式中的 P(T)P(T)c^\hat{c} 在通过 argmaxargmax 选出最大概率值的过程中,依然会选出正确的最大值

\therefore c^=argmaxcjCP(Tcj)P(cj)\hat{c}=argmax_{c_j\in C}P(T|c_j){P(c_j)}

  • 所以接下来的任务,就是对每个类别 cjc_j 求算 P(Tcj)P(T|c_{j}),然后选出其中最大的那个概率值,就是样本 TT 所属的类别概率

TT 的组成

  • 那我们进一步探究,TT 到底是个什么东西呢?我们说 TT 是一个样本(或实例),那样本是由什么组成的呢?让我们回顾一下
import pandas as pd
columns = ['姓名','年龄','身高','是否婚恋','月薪','学历']
data = [['张三',18,181,1,18000,'本科'],
       ['李四',30,172,0,13000,'本科'],
       ['王五',14,198,1,8888,'本科'],
       ['赵六',18,176,0,3000,'本科']]

pd.DataFrame(columns=columns,data=data)

姓名 年龄 身高 是否婚恋 月薪 学历
0 张三 18 181 1 18000 本科
1 李四 30 172 0 13000 本科
2 王五 14 198 1 8888 本科
3 赵六 18 176 0 3000 本科
  • 对于这个例子来说,每一行数据都是一个 instance,而组成每一个 instance 的,就是 attributes(属性),也就是说当我们选择第一行这个样本 TT,那么 x1,..xnx_1,..x_n,就分别代表 {x1,x2,...xn}={181811,...}\{x_1,x_2,...x_n\} = \{张三,18,181,1, ...\}

  • 我们在再反过头来看我们上面的公式:
    c^=argmaxcjCP(Tcj)P(cj)\hat{c}=argmax_{c_j\in C}P(T|c_j){P(c_j)}

  • T={x1,x2,...xn}T=\{x_1,x_2,...x_n\}
    c^=argmaxcjCP(x1,x2,...xncj)P(cj)\hat{c}=argmax_{c_j\in C}P(x_1,x_2,...x_n|c_j){P(c_j)}

  • 所以,如何求 P(x1,x2,...xncj)P(x_1,x_2,...x_n|c_j)

朴素的贝叶斯为何朴素

  • 这里就是朴素贝叶斯为啥叫朴素的重要部分!!!!

  • 如果 x1,x2,...xnx_1,x_2,...x_n 之间不是相互独立的,那么概率的链式法则应该是这样的:

P(x1,x2,...xncj)=P(x1cj)P(x2x1,cj)...P(xnx1,x2...,xn,cj)P(x_1,x_2,...x_n|c_j)=P(x_1|c_j)P(x_2|x_1,c_j)...P(x_n|x1,x2...,x_n,c_j)

  • 这样的话,我们光是算这一大串公式的计算难度就非常非常大

  • 但朴素贝叶斯之所以 “朴素” 就是因为它有一个很强的假设,那就是 x1,x2,...xnx_1,x_2,...x_n 他们之间是在 cjc_j 的条件下相互独立的;

\therefore $$P(x_1,x_2,…x_n|c_j) \approx P(x_1|c_j)P(x_2|c_j)…P(x_n|c_j)\ P(x_1,x_2,…x_n|c_j) \approx \prod_i{P(x_i|c_i)}$$

  • 如果使用朴素贝叶斯这种粗暴的化简方式,分母的计算就变得容易很多了!
  • 这个如果不明白,请看条件独立部分:

P(x1,x2cj)=P(x1cj)P(x2cj)P(x_1,x_2|c_j)=P(x_1|c_j)P(x_2|c_j)

P(x1,x2)=P(x1)P(x2)P(x_1,x_2)=P(x_1)P(x_2)

  • 所以贝叶斯公式会在各个属性之间不完全独立的情况下产生不太好的结果,但是当面对各个 attribute 独立的数据,表现就会很好。

  • 通过上面的化简,我们可以进一步得到我们的类别求算公式:

c^=argmaxcjCP(cj)iP(xici)\hat{c}=argmax_{c_j\in C}P(c_j)\prod_i{P(x_i|c_i)}

整理一下:

  • 由于上面的推导过程有些细碎,在这里从头整理一下得到 c^\hat{c} 的过程:

c^=argmaxcjCP(cjT)\hat{c}=argmax_{c_j\in C}P(c_j|T)

\because P(cjT)=P(Tcj)P(cj)P(T)P(c_j|T)=\frac{P(T|c_j)P(c_j)}{P(T)}

\therefore c^=argmaxcjCP(Tcj)P(cj)P(T)\hat{c}=argmax_{c_j\in C}\frac{P(T|c_j)P(c_j)}{P(T)}

\because P(T)P(T) is equal for all categories

\therefore c^=argmaxcjCP(Tcj)P(cj)\hat{c}=argmax_{c_j\in C}P(T|c_j){P(c_j)}

T={x1,x2,...xn}\because T=\{x_1,x_2,...x_n\}

c^=argmaxcjCP(x1,x2,...xncj)P(cj)\therefore \hat{c}=argmax_{c_j\in C}P(x_1,x_2,...x_n|c_j){P(c_j)}

\because assume x1,...xnx_1,...x_n conditional independence

\therefore P(x1,x2,...xncj)P(x1cj)P(x2cj)...P(xncj)P(x_1,x_2,...x_n|c_j) \approx P(x_1|c_j)P(x_2|c_j)...P(x_n|c_j)

P(x1,x2,...xncj)iP(xici)P(x_1,x_2,...x_n|c_j) \approx \prod_i{P(x_i|c_i)}

c^=argmaxcjCP(cj)iP(xici)\therefore \hat{c}=argmax_{c_j\in C}P(c_j)\prod_i{P(x_i|c_i)}

问题

如何得到先验概率 P(cj)P(c_j) ?

  • 因为分类任务是监督学习的一种,所以对于每条数据都是有 label 的,我们可以通过统计 label 中 cjc_j 出现的频次来得到 P(cj)P(c_j)

当我们拿到一个数据集之后,我们需要知道的概率有哪些?

  • P(cj)P(c_j), P(xicj)P(x_i|c_j) 对于所有的 xi,cjx_i, c_j

具体实例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j0Ty9TUX-1647111760800)(attachment:image.png)]

实例分析与介绍

  • 对于这个例子来说,我们先看类别 cjC={Flu,Cold}c_j \in C=\{Flu, Cold\} 这是个二分类问题
  • xiTx_i \in T, T={x1,x2,...,xn}={Headache,Score,Temperature,Cough}T = \{x_1,x_2,...,x_n\} = \{Headache, Score, Temperature, Cough\}
  • 如果现在有个不头痛、轻度肌肉痛、正常体温、不咳嗽的人;他的样本 TT 就可以表示为:

T={Headache=no,Sore=mild,Temp=normal,Cough=no}T = \{Headache=no,Sore=mild,Temp=normal,Cough=no\}

  • 因此这个时候我们去求算在这个样本是 FluFlu 的概率就可以表示为:

P(Diagnosis=FluHeadache=no,Sore=mild,Temp=normal,Cough=no)P(Diagnosis=Flu | Headache=no,Sore=mild,Temp=normal,Cough=no)

求算所有的条件概率

  • 求算所有的条件概率 P(xicj)P(x_i|c_j)P(cj)P(c_j)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uyZWg9y-1647111760801)(attachment:image.png)]

得到分类概率

我们已经得到了上述所有需要的条件概率和先验概率:

  • 那么假设现在有一患者以轻度头痛(mild headache),严重酸痛(severe soreness),体温正常(normal temperature),无咳嗽(no cough)就诊。他们更容易得感冒(cold)还是流感(flu)?

  • 我们通过以后的概率来计算 Flu 和 Cold 分别的概率情况:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UIQM0fVo-1647111760802)(attachment:image.png)]

再看一个例子:

  • 病人来诊时,有严重头痛(severe headache),轻度酸痛(mild soreness),高烧(high temperature),无咳嗽(no cough)。他们更容易得感冒还是流感?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xc9YcfKE-1647111760802)(attachment:image.png)]

概率平滑

ϵ\epsilon 代替 0

  • 从上面的例子中很容易发现一个问题:

    • 贝叶斯公式在计算的过程中,如果任何一个 P(xicj)=0P(x_i|c_j)=0 那么最终的值就是 0;
    • 但是这些看起来都等于 0 的值真的是等价的么?
    • 为了解决这种 0 存在的问题,我们采用一个极小的、大于 0 的值:ϵ\epsilon 来代替 0
      • ϵ\epsilon 应该非常小,应该比任何一个不等于 0 的 P(x_i|c_j) 都小,因为只有这样,将 0 替换成 ϵ\epsilon 才会在不改变结果的情况下解决 0 的问题
      • 在真正实际操作的时候,我们会比较两个式子中谁包含的 ϵ\epsilon 的数量多,越多的 ϵ\epsilon 代表实际的概率值越小
  • 于是上面的第二个例子,就可以写成如下形式:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f2fpF5A2-1647111760802)(attachment:image.png)]

拉普拉斯 / 加数平滑

  • 看不见的事件的计数为1
  • 其他事件也会增加1:一次看到的事件会变成2,两次看到的事件会变成3,等等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jrI94qDq-1647111760803)(attachment:image.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CwzOrckg-1647111760803)(attachment:image.png)]

  • 在这个例子中,当 XXHeadacheHeadache 事件的时候,XX 的取值有三种,所以 d=3d=3α=1\alpha=1 所以计算方式如上所示
  • 最常用的拉普拉斯平滑方法是加一平滑(α=1,所有计数加1)
  • 当实例很少时,概率会发生剧烈的变化,但当实例更多时,变化会更小
  • 众所周知,加一平滑法会高估罕见事件发生的可能性
    • 但是ε或更低的α值则会导致低估罕见事件的可能性
    • 在实践中很难选择正确的α

缺失值

如果一个 instance 缺失了某些 attribute 怎么办?

  • 在测试中缺失的值可以简单地忽略——从未缺失的值计算每个类的可能性
  • 训练中缺失的值也可以忽略——不要将它们包含在属性类计数中,概率将基于未缺失的值

朴素贝叶斯实例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czQ3wL4Y-1647111760804)(attachment:image.png)]

  • 简单的图形数据集:

    • 形状是高还是宽
    • 是椭圆的还是矩形
    • 红、黄、蓝还是绿色
  • 训练和测试集如下:

    • A 类和 B 类两种标签

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75Tg4SHC-1647111760804)(attachment:image.png)]

总结

朴素贝叶斯为什么有效

  • 我们并不需要对于每个类别的 P(cT)P(c|T) 进行完美评估,我们只需知道大概即可
  • 忽略某些属性是相关的这一事实会使所有类的概率更高,但通常不会改变它们的等级(要高大家的概率都高,但是相对来说不影响筛选出那个最大的类别)
  • 朴素贝叶斯对评估 P(xicj)P(x_i|c_j)中的小错误依然是鲁棒的,虽然这些小错误可以改变每个类概率,但通常不会改变这些类的概率排序

朴素贝叶斯的优势

  • 简单易搭建,算法速度非常快
  • 计算可以很好地适应高维数据集(属性可以达到1000个)
  • 可解释的-通常容易理解为什么模型做出它所做的决定

朴素贝叶斯的缺点

  • 当缺失很多 P(xicj)P(x_i|c_j) 的时候会不准确
  • 条件独立假设对于复杂系统来说是有问题的
举报

相关推荐

0 条评论