朴素贝叶斯是一种基于贝叶斯定理的分类算法,它的主要思想是利用先验概率和条件概率来计算后验概率,从而进行分类。

那么什么是先验概率,条件概率和后验概率呢?

贝叶斯定理

现在假设我们要解决分类问题,此问题中,有一组特征,我们用X来表示,$X=(X_1,X_2,…,X_n)$,有了特征后,需要找出正确的标签,用Y来表示。

当我们从概率的角度来处理这个问题,需要把这个Y和X视为随机变量。 $$P(Y=y|X=(x_1,x_2,…,x_n))$$,为了找出正确的标签,需要求出这个表达式在Y所有可能值中的最大值。所以这个条件概率就等于在给定X等于这个集合时,Y等于小写y的概率,更具体的说需要找出小写y的那个特定值,是这个条件概率最大。

但直接找出给定X的Y的概率是很困难的,所以才有的贝叶斯定理。


贝叶斯定理是一个基本的概率公式,它可以用于计算在已知某些条件下,某个事件发生的概率。$$ P(Y \mid X)=\frac{P(X \mid Y) P(Y)}{P(X)} $$。此公式说明了想要找出给定X的Y的概率,等于给定Y的X的概率乘以Y的概率,然后再除以X的概率。

其中,

  • P(Y|X)表示在已知X发生的情况下,Y发生的概率,它是后验概率;
  • P(Y)表示先验概率;
  • P(X|Y)表示在已知Y发生的情况下,X发生的概率;也叫似然度
  • P(X)表示标准化常量;当比较不同类别级别的这个条件概率,我们可以忽略它。因为特征是不变的

先验:在考虑任何证据之前,事情的概率。 后验:指在考虑了一些证据后,事情的概率。而证据实际上就是一组特征。

举例

$X_1$$X_2$Y
000
011
121
001
220
110
021
200
210
100

其中 $ X_1, X_2 \in {0, 1, 2}$, $ Y \in {0, 1}$

求(0,2)是属于哪个类别? 转为求: $$ P(Y=0|X=(0,2)) = ? \ P(Y=1|X=(0,2)) = ? \ $$

经计算: $$ P(Y=0)= \frac{6}{10} \ P(Y=1)= \frac{4}{10} \ P(X=(0,2)|Y=0) = 0 \ P(X=(0,2)|Y=1) = \frac{1}{4} \ $$

所以 $$ P(X=(0,2)|Y=0) * P(Y=0) = 0 \ P(X=(0,2)|Y=1) * P(Y=1) = \frac{1}{10}\ $$

问题是如果特定的特征组合我们没有遇到,那么计算出的概率就是零,如果有多个零,那么我们就没办法比较了。

所以需要朴素贝叶斯分类器,只需假设特征都是相互独立的,这样我们并不需要在数据集中找到$X_1$ 和 $X_2$的特定组合,只需要把X在Y的条件下的概率写成一连串的乘积,而如果特征不是独立的,那我们就不能这么写。这就是朴素贝叶斯所做的一个重大假设。

现实世界中,特征可能并不完全独立,所以被称为朴素的原因。

$$ \begin{aligned} P(X=(0,2) \mid Y=1)= & P\left(X_{1}=0 \mid Y=1\right) * P\left(X_{2}=2 \mid Y=1\right)=\frac{3}{4} \frac{2}{4} \ P(X=(0,2) \mid Y=0)= & P\left(X_{1}=0 \mid Y=0\right) * P\left(X_{2}=2 \mid Y=0\right)=\frac{1}{6} \frac{1}{6} \ & \frac{3}{4} * \frac{2}{4}>\frac{1}{6} * \frac{1}{6} \end{aligned} $$

零概率问题

零概率问题:在计算事件的概率时,如果某个事件在观察样本库(训练集)中没有出现过,会导致该事件的概率结果是0。这是不合理的,不能因为一个事件没有观察到,就被认为该事件一定不可能发生(即该事件的概率为0)。

拉普拉斯平滑

拉普拉斯平滑(Laplacian smoothing) 是为了解决零概率的问题。

法国数学家 拉普拉斯 最早提出用 加1 的方法,估计没有出现过的现象的概率。 理论假设:假定训练样本很大时,每个分量x的计数加1造成的估计概率变化可以忽略不计,但可以方便有效的避免零概率问题

对于一个随机变量z, 它的取值范围是 {1,2,3,…,k},对于m次试验后的观测结果 $\left{z^{(1)}, z^{(2)}, z^{(3)}, \ldots, z^{(m)}\right}$ , 极大似然估计按照下式计算:

$$ \varphi_{j}=\frac{\sum_{i=1}^{m} I\left{z^{(i)}=j\right}}{m} $$

使用 Laplace 平滑后, 计算公式变为:

$$ \varphi_{j}=\frac{\sum_{i=1}^{m} I\left{z^{(i)}=j\right}+1}{m+\mathrm{k}} $$

即在分母上加上取值范围的大小, 在分子加 1 。

朴素贝叶斯算法

在朴素贝叶斯算法中,我们将待分类的数据看作一个向量,每个特征值都独立地对分类结果产生影响。所以,我们可以通过计算每个特征值的条件概率来得到该向量属于每个类别的概率,并选择概率最大的类别作为分类结果。

具体来说,假设有n个类别C1,C2,…,Cn,待分类的向量为 $X=(X_1,X_2,…,X_m)$,则朴素贝叶斯算法的分类过程如下:

  1. 计算每个类别的先验概率$P(C_i)$;
  2. 对于每个类别$C_i$,计算向量X属于该类别的条件概率$ P(X|C_i) $;
  3. 根据贝叶斯定理,计算向量X属于每个类别的后验概率$ P(C_i|X)=\frac{P(X|C_i)P(C_i);}{P(X)} $;
  4. 选择后验概率最大的类别作为分类结果。

在实际应用中,朴素贝叶斯算法常用于文本分类、垃圾邮件过滤、推荐系统等领域。由于其简单有效,且对于高维度数据表现良好,因此被广泛应用。

举例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB

def nb_news():
    """
    用朴素贝叶斯算法对新闻进行分类
    :return:
    """
    # 1)获取数据
    news = fetch_20newsgroups(subset="all")

    # 2)划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)

    # 3)特征工程:文本特征抽取-tfidf
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4)朴素贝叶斯算法预估器流程
    estimator = MultinomialNB()
    estimator.fit(x_train, y_train)

    # 5)模型评估
    # 方法1:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法2:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)

    return None

if __name__ == "__main__":
    # 用朴素贝叶斯算法对新闻进行分类
    nb_news()
1
2
3
4
5
6
y_predict:
 [15  4  5 ...  3  2 12]
直接比对真实值和预测值:
 [False  True  True ...  True  True  True]
准确率为:
 0.8399830220713073