Bootstrap

朴素贝叶斯算法

研究背景

朴素贝叶斯算法是一种基于概率模型的分类算法,其研究历史可以追溯到18世纪。以下是一些关于朴素贝叶斯算法的经典论文:

Laplace, P. S. (1812). Mémoire sur la probabilité des causes par les événements. Memoirs of the Royal Academy of Sciences of Paris, 6, 621-656.
这篇论文是朴素贝叶斯算法的先驱之一,提出了贝叶斯公式,为后来的朴素贝叶斯算法提供了理论基础。

Duda, R. O., & Hart, P. E. (1973). Pattern classification and scene analysis (Vol. 3). John Wiley & Sons.
这本书介绍了朴素贝叶斯算法在模式分类和场景分析中的应用,为朴素贝叶斯算法在实际应用中的发展提供了重要的参考。

Zhang, H. (2004). The optimality of naive Bayes. Proceedings of the 17th International Florida Artificial Intelligence Research Society Conference (pp. 562-567).
这篇论文证明了朴素贝叶斯算法在某些情况下的最优性,为其在实际应用中的合理性提供了理论支持。

Rish, I. (2001). An empirical study of the naive Bayes classifier. Proceedings of the 2001 International Joint Conference on Neural Networks. IEEE.
这篇论文对朴素贝叶斯算法进行了实证研究,分析了其在不同数据集上的性能表现和应用效果。

McCallum, A., & Nigam, K. (1998). A comparison of event models for naive Bayes text classification. AAAI-98 Workshop on Learning for Text Categorization.
这篇论文比较了朴素贝叶斯算法中不同的事件模型在文本分类中的表现,为朴素贝叶斯算法在文本分类领域的应用提供了参考。

这些论文为朴素贝叶斯算法的研究和应用提供了重要的参考和指导,对于学习和掌握朴素贝叶斯算法具有重要意义。

原理说明

朴素贝叶斯算法是一种基于概率论和贝叶斯定理的分类算法,它基于先验概率和条件概率对样本进行分类。

在朴素贝叶斯算法中,我们假设所有特征都是独立的。在实际情况中,这个假设并不一定成立,但是朴素贝叶斯算法仍然是一种非常有效的分类算法。

假设有一个样本 x = ( x 1 , x 2 , … , x n ) x=(x_1,x_2,\ldots,x_n) x=(x1,x2,,xn),它属于类别 y y y。我们需要计算在给定特征 x 1 , x 2 , … , x n x_1,x_2,\ldots,x_n x1,x2,,xn的条件下,该样本属于类别 y y y的概率 P ( y ∣ x 1 , x 2 , … , x n ) P(y|x_1,x_2,\ldots,x_n) P(yx1,x2,,xn),然后将样本分类到概率最大的类别。

根据贝叶斯定理,我们可以得到:

P ( y ∣ x 1 , x 2 , … , x n ) = P ( y ) P ( x 1 , x 2 , … , x n ∣ y ) P ( x 1 , x 2 , … , x n ) P(y|x_1,x_2,\ldots,x_n)=\frac{P(y)P(x_1,x_2,\ldots,x_n|y)}{P(x_1,x_2,\ldots,x_n)} P(yx1,x2,,xn)=P(x1,x2,,xn)P(y)P(x1,x2,,xny)

其中, P ( y ) P(y) P(y)表示类别 y y y在整个数据集中的出现概率,称为先验概率; P ( x 1 , x 2 , … , x n ∣ y ) P(x_1,x_2,\ldots,x_n|y) P(x1,x2,,xny)表示在类别 y y y的条件下,样本特征 x 1 , x 2 , … , x n x_1,x_2,\ldots,x_n x1,x2,,xn的概率,称为条件概率; P ( x 1 , x 2 , … , x n ) P(x_1,x_2,\ldots,x_n) P(x1,x2,,xn)表示样本特征 x 1 , x 2 , … , x n x_1,x_2,\ldots,x_n x1,x2,,xn在整个数据集中的概率。

朴素贝叶斯算法中,我们将样本特征 x 1 , x 2 , … , x n x_1,x_2,\ldots,x_n x1,x2,,xn看做条件独立的,即:

P ( x 1 , x 2 , … , x n ∣ y ) = P ( x 1 ∣ y ) P ( x 2 ∣ y ) ⋯ P ( x n ∣ y ) P(x_1,x_2,\ldots,x_n|y)=P(x_1|y)P(x_2|y)\cdots P(x_n|y) P(x1,x2,,xny)=P(x1y)P(x2y)P(xny)

根据上述公式,我们可以得到:

P ( y ∣ x 1 , x 2 , … , x n ) = P ( y ) P ( x 1 ∣ y ) P ( x 2 ∣ y ) ⋯ P ( x n ∣ y ) P ( x 1 , x 2 , … , x n ) P(y|x_1,x_2,\ldots,x_n)=\frac{P(y)P(x_1|y)P(x_2|y)\cdots P(x_n|y)}{P(x_1,x_2,\ldots,x_n)} P(yx1,x2,,xn)=P(x1,x2,,xn)P(y)P(x1y)P(x2y)P(xny)

将分母移项,得到:

P ( y ∣ x 1 , x 2 , … , x n ) ∝ P ( y ) P ( x 1 ∣ y ) P ( x 2 ∣ y ) ⋯ P ( x n ∣ y ) P(y|x_1,x_2,\ldots,x_n)\propto P(y)P(x_1|y)P(x_2|y)\cdots P(x_n|y) P(yx1,x2,,xn)P(y)P(x1y)P(x2y)P(xny)

其中, ∝ \propto 表示与样本特征 x 1 , x 2 , … , x n x_1,x_2,\ldots,x_n x1,x2,,xn无关的常数,可以省略。

根据上式,我们可以计算样本属于各个类别的概率,然后将样本分类到概率最大的类别。

在实际应用中,朴素贝叶斯算法常用于文本分类、垃圾邮件过滤等领域

在朴素贝叶斯算法中,我们需要估计先验概率 P ( y ) P(y) P(y)和条件概率 P ( x i ∣ y ) P(x_i|y) P(xiy)

对于先验概率 P ( y ) P(y) P(y),我们可以通过计算每个类别在整个数据集中的出现频率来进行估计。

对于条件概率 P ( x i ∣ y ) P(x_i|y) P(xiy),我们需要对每个特征进行估计。在朴素贝叶斯算法中,常用的做法是使用极大似然估计来估计条件概率。

假设有一个特征 x i x_i xi,它可以取 k k k个不同的取值 a 1 , a 2 , … , a k {a_1,a_2,\ldots,a_k} a1,a2,,ak,在类别 y y y的条件下,样本特征 x i x_i xi等于 a j a_j aj的概率可以用下式计算:

P ( x i = a j ∣ y ) = 在类别y中特征 x i = a j 的样本个数 在类别y中的样本个数 P(x_i=a_j|y)=\frac{\text{在类别y中特征}x_i=a_j\text{的样本个数}}{\text{在类别y中的样本个数}} P(xi=ajy)=在类别y中的样本个数在类别y中特征xi=aj的样本个数

其中, 在类别y中特征 x i = a j 的样本个数 \text{在类别y中特征}x_i=a_j\text{的样本个数} 在类别y中特征xi=aj的样本个数表示在类别 y y y的样本中,特征 x i x_i xi等于 a j a_j aj的样本个数。

假设有 n n n个特征,将上述条件概率带入贝叶斯公式,我们可以得到分类模型:

y ^ = arg ⁡ max ⁡ y ∈ Y P ( y ) ∏ i = 1 n P ( x i ∣ y ) \hat{y}=\mathop{\arg\max}{y\in Y} P(y)\prod{i=1}^{n}P(x_i|y) y^=argmaxyYP(y)i=1nP(xiy)

其中, y ^ \hat{y} y^表示预测的类别, Y Y Y表示所有可能的类别。

朴素贝叶斯算法的优点包括简单、高效、适用于大规模数据等;缺点包括对数据的分布假设过于简单,不能很好地处理特征之间的依赖关系,当特征之间存在依赖关系时,分类效果可能不佳。

公式推导

朴素贝叶斯算法的核心是贝叶斯公式:

P ( y ∣ x ) = P ( x ∣ y ) P ( y ) P ( x ) P(y|x)=\frac{P(x|y)P(y)}{P(x)} P(yx)=P(x)P(xy)P(y)

其中, P ( y ∣ x ) P(y|x) P(yx)表示在已知特征 x x x的条件下类别 y y y的后验概率, P ( x ∣ y ) P(x|y) P(xy)表示在类别 y y y的条件下特征 x x x的条件概率, P ( y ) P(y) P(y)表示类别 y y y的先验概率, P ( x ) P(x) P(x)表示特征 x x x的边缘概率。

朴素贝叶斯算法假设各个特征之间相互独立,即

P ( x 1 , x 2 , … , x n ∣ y ) = ∏ i = 1 n P ( x i ∣ y ) P(x_1,x_2,\ldots,x_n|y)=\prod_{i=1}^{n}P(x_i|y) P(x1,x2,,xny)=i=1nP(xiy)

这个假设是朴素贝叶斯算法的核心。基于上述假设,我们可以将贝叶斯公式改写为:

P ( y ∣ x ) = ∏ i = 1 n P ( x i ∣ y ) P ( y ) P ( x ) P(y|x)=\frac{\prod_{i=1}^{n}P(x_i|y)P(y)}{P(x)} P(yx)=P(x)i=1nP(xiy)P(y)

由于对于同一个输入样本 x x x P ( x ) P(x) P(x)在不同的类别下是相同的,因此我们可以忽略 P ( x ) P(x) P(x),得到:

P ( y ∣ x ) ∝ ∏ i = 1 n P ( x i ∣ y ) P ( y ) P(y|x)\propto \prod_{i=1}^{n}P(x_i|y)P(y) P(yx)i=1nP(xiy)P(y)

这个公式告诉我们,在已知特征 x x x的情况下,类别 y y y的后验概率与各个特征在该类别下的条件概率和类别的先验概率的乘积成正比。由于我们只需要找到后验概率最大的类别,因此可以使用最大后验概率来进行分类:

y ^ = arg ⁡ max ⁡ y ∈ Y P ( y ∣ x ) ∝ ∏ i = 1 n P ( x i ∣ y ) P ( y ) \hat{y}=\mathop{\arg\max}{y\in Y} P(y|x)\propto \prod{i=1}^{n}P(x_i|y)P(y) y^=argmaxyYP(yx)i=1nP(xiy)P(y)

其中, y ^ \hat{y} y^表示预测的类别, Y Y Y表示所有可能的类别。

接下来,我们需要估计先验概率 P ( y ) P(y) P(y)和条件概率 P ( x i ∣ y ) P(x_i|y) P(xiy)。在朴素贝叶斯算法中,常用的做法是使用极大似然估计来估计条件概率。

接下来我们考虑如何估计先验概率 P ( y ) P(y) P(y)。在训练数据集中,我们可以统计每个类别在数据集中出现的次数,并计算每个类别的出现频率作为其先验概率。即

P ( y ) = N y N P(y)=\frac{N_y}{N} P(y)=NNy

其中, N y N_y Ny表示训练集中类别为 y y y的样本数, N N N表示训练集中的总样本数。

现在我们可以将先验概率和条件概率代入最大后验概率的公式,得到:

y ^ = arg ⁡ max ⁡ y ∈ Y ∏ i = 1 n P ( x i ∣ y ) P ( y ) \hat{y}=\mathop{\arg\max}{y\in Y} \prod{i=1}^{n}P(x_i|y)P(y) y^=argmaxyYi=1nP(xiy)P(y)

为了避免出现概率乘积为零的情况,我们通常使用对数变换将其转化为求和:

y ^ = arg ⁡ max ⁡ y ∈ Y ( ln ⁡ P ( y ) + ∑ i = 1 n ln ⁡ P ( x i ∣ y ) ) \hat{y}=\mathop{\arg\max}{y\in Y} \left(\ln P(y)+\sum{i=1}^{n}\ln P(x_i|y)\right) y^=argmaxyY(lnP(y)+i=1nlnP(xiy))

这个公式是朴素贝叶斯算法的分类公式,我们可以将其应用于新的未知样本进行分类。

需要注意的是,当训练数据集中某个特征在某个类别下没有出现时,条件概率 P ( x i ∣ y ) P(x_i|y) P(xiy)会等于零,这会导致后验概率为零。为了避免这种情况,我们可以采用拉普拉斯平滑(Laplace smoothing)的方法,即将所有的条件概率加上一个平滑系数 α \alpha α,如下:

P ( x i ∣ y ) = N y , x i + α N y + α n i P(x_i|y)=\frac{N_{y,x_i}+\alpha}{N_y+\alpha n_i} P(xiy)=Ny+αniNy,xi+α

其中, N y , x i N_{y,x_i} Ny,xi表示训练集中类别为 y y y且特征 x i x_i xi取值为该样本中的取值的样本数, n i n_i ni表示特征 x i x_i xi可能取值的个数。

拉普拉斯平滑的目的是避免在样本数较少或特征数较多时,由于零概率的出现而导致概率乘积为零的情况,从而影响模型的分类准确度。

至此,我们完成了朴素贝叶斯算法的公式推导。需要注意的是,朴素贝叶斯算法的核心是对各个特征之间的独立性进行假设,这一假设在实际应用中可能不成立,从而影响模型的准确性。因此,在使用朴素贝叶斯算法时,我们需要根据实际问题对其假设进行合理性检验,并根据需要进行模型选择和参数调整。

代码示意

class NaiveBayes:
    def __init__(self):
        self.vocab = set()
        self.class_total = {}
        self.class_word_freq = {}
        self.class_prob = {}

    def train(self, documents, labels):
        # 计算先验概率
        for label in labels:
            if label not in self.class_total:
                self.class_total[label] = 0
            self.class_total[label] += 1
        
        for label, total in self.class_total.items():
            self.class_prob[label] = total / len(labels)
            self.class_word_freq[label] = {}

        # 计算词频
        for doc, label in zip(documents, labels):
            for word in doc.split():
                self.vocab.add(word)
                if word not in self.class_word_freq[label]:
                    self.class_word_freq[label][word] = 0
                self.class_word_freq[label][word] += 1

        # 计算条件概率
        for label, freq in self.class_word_freq.items():
            total = sum(freq.values())
            for word in self.vocab:
                if word in freq:
                    self.class_word_freq[label][word] /= total
                else:
                    self.class_word_freq[label][word] = 0

    def predict(self, document):
        probs = {}
        for label in self.class_prob:
            probs[label] = 1
            for word in document.split():
                if word in self.vocab:
                    probs[label] *= self.class_word_freq[label][word]
            probs[label] *= self.class_prob[label]
        return max(probs, key=probs.get)

;