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

回顾贝叶斯公式

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

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

贝叶斯公式的实例

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

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

  • 条件概率:

    • P ( o f f ∣ o p e n ) = 0.01 P(off|open)=0.01 P(offopen)=0.01, 当店铺开张的时候,灯灭的概率为 0.01
    • P ( o f f ∣ c l o s e d ) = 0.85 P(off|closed)=0.85 P(offclosed)=0.85 当店铺关闭的时候,灯灭的概率为 0.85
  • 求后验概率 P ( o p e n ∣ o f f ) P(open|off) P(openoff)

先验概率和后验概率可以这么理解:

  • P ( H ) P(H) P(H) P ( H ∣ x ) P(H|x) P(Hx) 相比,一个 H H H 是预先知道的,所以是先验的,一个是 H H H 需要在 x x x 的条件下算出来的,所以是后验的

P ( o p e n ∣ o f f ) = P ( o f f ∣ o p e n ) P ( o p e n ) P ( o f f ) P(open|off) = \frac{P(off|open)P(open)}{P(off)} P(openoff)=P(off)P(offopen)P(open)

P ( o f f ) = P ( o f f , o p e n ) + P ( o f f , c l o s e d ) = P ( o f f ∣ o p e n ) P ( o p e n ) + P ( o f f ∣ c l o s e d ) P ( c l o s e d ) P(off)=P(off,open) + P(off,closed) = P(off|open)P(open)+P(off|closed)P(closed) P(off)=P(off,open)+P(off,closed)=P(offopen)P(open)+P(offclosed)P(closed)

P ( o p e n ∣ o f f ) = P ( o f f ∣ o p e n ) P ( o p e n ) P ( o f f ∣ o p e n ) P ( o p e n ) + P ( o f f ∣ c l o s e d ) P ( c l o s e d ) P(open|off) = \frac{P(off|open)P(open)}{P(off|open)P(open)+P(off|closed)P(closed)} P(openoff)=P(offopen)P(open)+P(offclosed)P(closed)P(offopen)P(open)

P ( o p e n ∣ o f f ) = 0.01 ∗ 0.95 0.01 ∗ 0.95 + 0.85 ∗ ( 1 − 0.95 ) = 0.183 P(open|off) = \frac{0.01 * 0.95}{0.01 * 0.95 + 0.85 * (1-0.95)}=0.183 P(openoff)=0.010.95+0.85(10.95)0.010.95=0.183

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

朴素贝叶斯分类器

  • 我们已经知道:

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

分类器的任务

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

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

  • a r g m a x c j ∈ C argmax_{c_j\in C} argmaxcjC 代表从几个候选的概率中选出最大值作为最后的结果

  • P ( c j ∣ T ) P(c_j|T) P(cjT) 表示给定 T T T 的条件下对 c j c_j cj 的分类概率

∵ \because P ( c j ∣ T ) = P ( T ∣ c j ) P ( c j ) P ( T ) P(c_j|T)=\frac{P(T|c_j)P(c_j)}{P(T)} P(cjT)=P(T)P(Tcj)P(cj)
∴ \therefore c ^ = a r g m a x c j ∈ C P ( T ∣ c j ) P ( c j ) P ( T ) \hat{c}=argmax_{c_j\in C}\frac{P(T|c_j)P(c_j)}{P(T)} c^=argmaxcjCP(T)P(Tcj)P(cj)

扔掉分母

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

∴ \therefore c ^ = a r g m a x c j ∈ C P ( T ∣ c j ) P ( c j ) \hat{c}=argmax_{c_j\in C}P(T|c_j){P(c_j)} c^=argmaxcjCP(Tcj)P(cj)

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

T T T 的组成

  • 那我们进一步探究, T T T 到底是个什么东西呢?我们说 T T T 是一个样本(或实例),那样本是由什么组成的呢?让我们回顾一下
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张三18181118000本科
1李四30172013000本科
2王五1419818888本科
3赵六1817603000本科
  • 对于这个例子来说,每一行数据都是一个 instance,而组成每一个 instance 的,就是 attributes(属性),也就是说当我们选择第一行这个样本 T T T,那么 x 1 , . . x n x_1,..x_n x1,..xn,就分别代表 { x 1 , x 2 , . . . x n } = { 张 三 , 18 , 181 , 1 , . . . } \{x_1,x_2,...x_n\} = \{张三,18,181,1, ...\} {x1,x2,...xn}={181811,...}

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

  • T = { x 1 , x 2 , . . . x n } T=\{x_1,x_2,...x_n\} T={x1,x2,...xn}
    c ^ = a r g m a x c j ∈ C P ( x 1 , x 2 , . . . x n ∣ c j ) P ( c j ) \hat{c}=argmax_{c_j\in C}P(x_1,x_2,...x_n|c_j){P(c_j)} c^=argmaxcjCP(x1,x2,...xncj)P(cj)

  • 所以,如何求 P ( x 1 , x 2 , . . . x n ∣ c j ) P(x_1,x_2,...x_n|c_j) P(x1,x2,...xncj)

朴素的贝叶斯为何朴素

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

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

P ( x 1 , x 2 , . . . x n ∣ c j ) = P ( x 1 ∣ c j ) P ( x 2 ∣ x 1 , c j ) . . . P ( x n ∣ x 1 , x 2... , x n , c j ) 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) P(x1,x2,...xncj)=P(x1cj)P(x2x1,cj)...P(xnx1,x2...,xn,cj)

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

  • 但朴素贝叶斯之所以 “朴素” 就是因为它有一个很强的假设,那就是 x 1 , x 2 , . . . x n x_1,x_2,...x_n x1,x2,...xn 他们之间是在 c j c_j cj 的条件下相互独立的;

∴ \therefore P ( x 1 , x 2 , . . . x n ∣ c j ) ≈ 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 P(x_1|c_j)P(x_2|c_j)...P(x_n|c_j) P(x1,x2,...xncj)P(x1cj)P(x2cj)...P(xncj)
P ( x 1 , x 2 , . . . x n ∣ c j ) ≈ ∏ i P ( x i ∣ c j ) P(x_1,x_2,...x_n|c_j) \approx \prod_i{P(x_i|c_j)} P(x1,x2,...xncj)iP(xicj)

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

条件独立:
假设现在有 x 1 , x 2 x_1,x_2 x1,x2 是在 c j c_j cj 的条件下相互独立的,那么我们可以得到下述结论:

P ( x 1 , x 2 ∣ c j ) = P ( x 1 ∣ c j ) P ( x 2 ∣ c j ) P(x_1,x_2|c_j)=P(x_1|c_j)P(x_2|c_j) P(x1,x2cj)=P(x1cj)P(x2cj)

完全独立:假设现在有 x 1 , x 2 x_1,x_2 x1,x2 是相互独立的随机变量,那么我们可以得到下述结论:

P ( x 1 , x 2 ) = P ( x 1 ) P ( x 2 ) P(x_1,x_2)=P(x_1)P(x_2) P(x1,x2)=P(x1)P(x2)

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

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

c ^ = a r g m a x c j ∈ C P ( c j ) ∏ i P ( x i ∣ c j ) \hat{c}=argmax_{c_j\in C}P(c_j)\prod_i{P(x_i|c_j)} c^=argmaxcjCP(cj)iP(xicj)

整理一下:

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

c ^ = a r g m a x c j ∈ C P ( c j ∣ T ) \hat{c}=argmax_{c_j\in C}P(c_j|T) c^=argmaxcjCP(cjT)

∵ \because P ( c j ∣ T ) = P ( T ∣ c j ) P ( c j ) P ( T ) P(c_j|T)=\frac{P(T|c_j)P(c_j)}{P(T)} P(cjT)=P(T)P(Tcj)P(cj)

∴ \therefore c ^ = a r g m a x c j ∈ C P ( T ∣ c j ) P ( c j ) P ( T ) \hat{c}=argmax_{c_j\in C}\frac{P(T|c_j)P(c_j)}{P(T)} c^=argmaxcjCP(T)P(Tcj)P(cj)

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

∴ \therefore c ^ = a r g m a x c j ∈ C P ( T ∣ c j ) P ( c j ) \hat{c}=argmax_{c_j\in C}P(T|c_j){P(c_j)} c^=argmaxcjCP(Tcj)P(cj)

∵ T = { x 1 , x 2 , . . . x n } \because T=\{x_1,x_2,...x_n\} T={x1,x2,...xn}

∴ c ^ = a r g m a x c j ∈ C P ( x 1 , x 2 , . . . x n ∣ c j ) P ( c j ) \therefore \hat{c}=argmax_{c_j\in C}P(x_1,x_2,...x_n|c_j){P(c_j)} c^=argmaxcjCP(x1,x2,...xncj)P(cj)

∵ \because assume x 1 , . . . x n x_1,...x_n x1,...xn conditional independence

∴ \therefore P ( x 1 , x 2 , . . . x n ∣ c j ) ≈ 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 P(x_1|c_j)P(x_2|c_j)...P(x_n|c_j) P(x1,x2,...xncj)P(x1cj)P(x2cj)...P(xncj)

P ( x 1 , x 2 , . . . x n ∣ c j ) ≈ ∏ i P ( x i ∣ c j ) P(x_1,x_2,...x_n|c_j) \approx \prod_i{P(x_i|c_j)} P(x1,x2,...xncj)iP(xicj)

∴ c ^ = a r g m a x c j ∈ C P ( c j ) ∏ i P ( x i ∣ c j ) \therefore \hat{c}=argmax_{c_j\in C}P(c_j)\prod_i{P(x_i|c_j)} c^=argmaxcjCP(cj)iP(xicj)

问题

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

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

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

  • P ( c j ) P(c_j) P(cj), P ( x i ∣ c j ) P(x_i|c_j) P(xicj) 对于所有的 x i , c j x_i, c_j xi,cj

具体实例

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

实例分析与介绍

  • 对于这个例子来说,我们先看类别 c j ∈ C = { F l u , C o l d } c_j \in C=\{Flu, Cold\} cjC={Flu,Cold} 这是个二分类问题
  • x i ∈ T x_i \in T xiT, T = { x 1 , x 2 , . . . , x n } = { H e a d a c h e , S c o r e , T e m p e r a t u r e , C o u g h } T = \{x_1,x_2,...,x_n\} = \{Headache, Score, Temperature, Cough\} T={x1,x2,...,xn}={Headache,Score,Temperature,Cough}
  • 如果现在有个不头痛、轻度肌肉痛、正常体温、不咳嗽的人;他的样本 T T T 就可以表示为:

T = { H e a d a c h e = n o , S o r e = m i l d , T e m p = n o r m a l , C o u g h = n o } T = \{Headache=no,Sore=mild,Temp=normal,Cough=no\} T={Headache=no,Sore=mild,Temp=normal,Cough=no}

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

P ( D i a g n o s i s = F l u ∣ H e a d a c h e = n o , S o r e = m i l d , T e m p = n o r m a l , C o u g h = n o ) P(Diagnosis=Flu | Headache=no,Sore=mild,Temp=normal,Cough=no) P(Diagnosis=FluHeadache=no,Sore=mild,Temp=normal,Cough=no)

求算所有的条件概率

  • 求算所有的条件概率 P ( x i ∣ c j ) P(x_i|c_j) P(xicj) P ( c j ) P(c_j) P(cj)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 ( x i ∣ c j ) = 0 P(x_i|c_j)=0 P(xicj)=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)]

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

缺失值

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

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

朴素贝叶斯实例

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

  • 简单的图形数据集:

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

    • A 类和 B 类两种标签

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

总结

朴素贝叶斯为什么有效

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

朴素贝叶斯的优势

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

朴素贝叶斯的缺点

  • 当缺失很多 P ( x i ∣ c j ) P(x_i|c_j) P(xicj) 的时候会不准确
  • 条件独立假设对于复杂系统来说是有问题的
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您的问题是关于Python识别虚假新闻的分类器,那么您可以使用机器学习算法中的朴素贝叶斯分类器MultinomialNB来预测新闻的类别。下面是一个简单的Python代码示例,演示如何使用MultinomialNB分类器来识别虚假新闻: 首先,您需要准备好数据集,其中包括已标记的真实新闻和虚假新闻。接下来,您需要将数据集分成训练集和测试集,以便评估分类器的性能。 ```python import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.model_selection import train_test_split # 读取数据集 df = pd.read_csv('news_dataset.csv') # 将文本数据转换为数字向量 vectorizer = CountVectorizer(stop_words='english') X = vectorizer.fit_transform(df['text']) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, df['label'], test_size=0.2, random_state=42) # 建立朴素贝叶斯分类器 clf = MultinomialNB() # 训练模型 clf.fit(X_train, y_train) # 测试模型 accuracy = clf.score(X_test, y_test) print('Accuracy:', accuracy) ``` 在上面的代码中,我们首先使用CountVectorizer将文本数据转换为数字向量。然后,我们使用train_test_split函数将数据集分成训练集和测试集。接下来,我们建立一个MultinomialNB分类器,并使用fit函数训练模型。最后,我们使用score函数在测试集上评估模型的准确性。 需要注意的是,上述代码仅提供了一个简单的示例,您需要根据您的数据集和需求进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暖仔会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值