avatar


8.朴素贝叶斯

朴素贝叶斯的计算方法

首先,我们回忆一下从前学的概率知识。

联合概率

联合概率:包含多个事件,且所有事件都发生的概率。
记作:P(AB)P(AB)

P(AB)=P(A)P(B)P(AB) = P(A) * P(B)

条件概率

条件概率:已知事件BB已经已经发生,在该条件下事件AA发生的概率。
记作:P(AB)P(A|B)

P(AB)=P(AB)P(B)P(A|B) = \frac{P(AB)}{P(B)}

特别的

P(A1,A2B)=P(A1B)P(A2B)P(A_1,A_2|B) = P(A_1|B) * P(A_2|B)

  • 该公式要求A1A_1A2A_2相互独立。

A1A_1A2A_2相互独立,这也是朴素贝叶斯中朴素两个字的含义,即特征独立。
所以朴素贝叶斯的前提是特征独立,如果特征不独立当然也可以用朴素贝叶斯,但是效果不一定好。

贝叶斯

贝叶斯的公式

在讲贝叶斯公式之前,我们假设有这么一个场景,文档分类。
给定一篇文档,分别求这篇文档是科技类的概率和经济类的概率,哪种概率大就认为是哪一种。
该文档是科技类的概率

P(科技文档)P(\text{科技}|\text{文档})

该文档是经济类的概率

P(经济文档)P(\text{经济}|\text{文档})

当然,文档都可用词1、词2、词3···表示。
所以有

P(科技词1,词2,词3)P(\text{科技}|\text{词1},\text{词2},\text{词3}···)

P(经济词1,词2,词3)P(\text{经济}|\text{词1},\text{词2},\text{词3}···)

这时候,我们需要求"多个条件下一件事情发生的概率"。

P(CF1,F2,F3)=P(F1,F2,F3C)P(C)P(F1,F2,F3)P(C|F_1,F_2,F_3···) = \frac{P(F_1,F_2,F_3···|C)P(C)}{P(F_1,F_2,F_3···)}

其中
P(C)P(C)是每个文档类别的概率。

P(C)=某类别文档数文档总数P(C) = \frac{\text{某类别文档数}}{\text{文档总数}}

P(F1,F2,F3C)P(F_1,F_2,F_3···|C)是给定类别下,词语出现的概率。 计算方法为上述的"条件概率"公式。
例如:P(F1C)P(F_1|C)的计算方法为

P(F1C)=F1在C类别所有文档中出现的次数C类别所有文档中所有词出现的次数P(F_1|C) = \frac{F_1\text{在C类别所有文档中出现的次数}}{\text{C类别所有文档中所有词出现的次数}}

在上述例子中
我们有

P(科技词1,词2,词3,)=P(词1,词2,词3,科技)P(科技)P(词1,词2,词3,)P(\text{科技}|\text{词1},\text{词2},\text{词3},···) = \frac{P(\text{词1},\text{词2},\text{词3},···|\text{科技})P(\text{科技})}{P(\text{词1},\text{词2},\text{词3},···)}

P(经济词1,词2,词3,)=P(词1,词2,词3,经济)P(经济)P(词1,词2,词3,)P(\text{经济}|\text{词1},\text{词2},\text{词3},···) = \frac{P(\text{词1},\text{词2},\text{词3},···|\text{经济})P(\text{经济})}{P(\text{词1},\text{词2},\text{词3},···)}

我们会发现,两个式子的分母部分是一样的。因此,实际上,我们只需要比较分子部分。

贝叶斯的计算

我们举个例子,这个更好理解。
假设训练集中存在统计结果如下

特征 科技(30篇) 经济(60篇) 合计(90篇)
证券 9 51 60
基金 8 56 64
大数据 20 15 35
特征工程 63 0 63
合计 100 121 221

同时,存在一篇待预测文档,出现了基金、大数据、特征工程这几个词。
分别求

P(科技基金,大数据,特征工程)P(\text{科技}|\text{基金},\text{大数据},\text{特征工程})

P(经济基金,大数据,特征工程)P(\text{经济}|\text{基金},\text{大数据},\text{特征工程})

根据上述分析,实际上我们只需要比较

P(基金,大数据,特征工程科技)P(科技)P(\text{基金},\text{大数据},\text{特征工程}|\text{科技})P(\text{科技})

P(基金,大数据,特征工程经济)P(经济)P(\text{基金},\text{大数据},\text{特征工程}|\text{经济})P(\text{经济})

计算"科技"的过程

P(基金,大数据,特征工程科技)P(科技)=P(基金科技)P(大数据科技)P(特征工程科技)P(科技)P(\text{基金},\text{大数据},\text{特征工程}|\text{科技})P(\text{科技}) = P(\text{基金}|\text{科技}) * P(\text{大数据}|\text{科技}) * P(\text{特征工程}|\text{科技}) * P(\text{科技})

P(基金,大数据,特征工程科技)P(科技)=8100201006310030900.00456P(\text{基金},\text{大数据},\text{特征工程}|\text{科技})P(\text{科技}) = \frac{8}{100} * \frac{20}{100} * \frac{63}{100} * \frac{30}{90} \approx 0.00456

计算"经济"的过程

P(基金,大数据,特征工程经济)P(经济)=P(基金经济)P(大数据经济)P(特征工程经济)P(经济)P(\text{基金},\text{大数据},\text{特征工程}|\text{经济})P(\text{经济}) = P(\text{基金}|\text{经济}) * P(\text{大数据}|\text{经济}) * P(\text{特征工程}|\text{经济}) * P(\text{经济})

P(基金,大数据,特征工程经济)P(经济)=561211512101216090=0P(\text{基金},\text{大数据},\text{特征工程}|\text{经济})P(\text{经济}) = \frac{56}{121} * \frac{15}{121} * \frac{0}{121} * \frac{60}{90} = 0

综上所述,在朴素贝叶斯下,该文章属于"科技"文章。

拉普拉斯平滑

上述因为词频列表中有出现次数为0的词,导致"经济"的概率为0,这是不合理的。
解决办法为进行拉普拉斯平滑。

P(F1C)=Ni+αN+αmP(F_1|C) = \frac{N_i + \alpha}{N + \alpha m}

其中

  • α\alpha为指定的系数,一般为11
  • mm为训练文档中特征的个数

例如,进行拉普拉斯平滑后

P(基金,大数据,特征工程经济)P(经济)=56+1121+1415+1121+140+1121+146090P(\text{基金},\text{大数据},\text{特征工程}|\text{经济})P(\text{经济}) = \frac{56 + 1}{121 + 1 * 4} * \frac{15 + 1}{121 + 1 * 4} * \frac{0 + 1}{121 + 1*4} * \frac{60}{90}

当然,如果要进行拉普拉斯平滑,所有的都要进行平滑。

正如“平滑”两字的含义,只是为了避免概率为00,不改变每一种情况下概率的大小关系。

朴素贝叶斯的实现

我们继续以文本分类这个场景为例。

1
from sklearn.naive_bayes import MultinomialNB
  • 需要传入一个参数alpha,注意alpha不是上一章所说的超参数,而是拉普拉斯平滑的α\alpha,只是为了避免概率为00,但不改变每一种情况下概率的大小关系。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
import ssl

ssl._create_default_https_context = ssl._create_unverified_context
news = fetch_20newsgroups(data_home='Desktop', subset='all')

x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25)
# 特征抽取
tf = TfidfVectorizer()
x_train = tf.fit_transform(x_train)
# 注意!这里是transform
x_test = tf.transform(x_test)

# 朴素贝叶斯
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train, y_train)
y_predict = mlt.predict(x_test)
print(y_predict)
print(mlt.score(x_test, y_test))

运行结果:

1
2
3
4
Downloading 20news dataset. This may take a few minutes.
Downloading dataset from https://ndownloader.figshare.com/files/5975967 (14 MB)
[15 13 0 ... 7 0 1]
0.8605687606112055

朴素贝叶斯的优缺点

  1. 优点

    1. 基于古典数学理论,有稳定的分类效率。
    2. 不容易受缺失数据集的影响。
  2. 缺点

    1. 非常依赖于所建立的重要的词
    2. 假设了特征之间相互独立,如果特征之间存在关联性的话,效果不一定好。
文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/10208
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

评论区