素贝叶斯算法(Naive Bayes)是一种基于贝叶斯定理的简单而有效的分类算法。其“朴素”之处在于假设各特征之间相互独立,即在给定类别的条件下,各个特征是独立的。尽管这一假设在实际中不一定成立,合理的平滑技术和数据预处理仍能使其在许多任务中表现良好。
优点:
缺点:
贝叶斯定理是朴素贝叶斯算法的核心公式,它将后验概率表示为先验概率、似然和证据的关系:
P ( C k ∣ X ) = P ( X ∣ C k ) ⋅ P ( C k ) P ( X ) P(C_k|X) = \frac{P(X|C_k) \cdot P(C_k)}{P(X)} P(Ck∣X)=P(X)P(X∣Ck)⋅P(Ck)
其中:
朴素贝叶斯的核心假设是条件独立性,即假设在给定类别的条件下,特征之间相互独立。对于特征向量 X = ( x 1 , x 2 , . . . , x n ) X = (x_1, x_2, ..., x_n) X=(x1,x2,...,xn),我们有:
P ( X ∣ C ) = P ( x 1 ∣ C ) ⋅ P ( x 2 ∣ C ) ⋅ … ⋅ P ( x n ∣ C ) P(X|C) = P(x_1|C) \cdot P(x_2|C) \cdot \ldots \cdot P(x_n|C) P(X∣C)=P(x1∣C)⋅P(x2∣C)⋅…⋅P(xn∣C)
这一假设使得模型简化为每个特征独立对分类结果的贡献。朴素贝叶斯模型的分类过程是通过最大化后验概率来进行的:
C ^ = argmax C P ( C ∣ X ) \hat{C} = \underset{C}{\text{argmax}} \ P(C|X) C^=Cargmax P(C∣X)
根据贝叶斯定理,可以转换为:
C ^ = argmax C P ( X ∣ C ) ⋅ P ( C ) \hat{C} = \underset{C}{\text{argmax}} \ P(X|C) \cdot P(C) C^=Cargmax P(X∣C)⋅P(C)
其中 P ( X ∣ C ) P(X|C) P(X∣C) 的计算可以通过假设特征独立性简化为各个特征的条件概率的乘积。在不知道 P ( C k ) P(C_k) P(Ck) 和 P ( X ∣ C k ) P(X|C_k) P(X∣Ck) 的情况下,我们可以使用极大似然估计来估计这些概率。
1. 先验概率的极大似然估计
对于类别 C k C_k Ck 的先验概率 P ( C k ) P(C_k) P(Ck),假设类别 C k C_k Ck 在训练集中以独立同分布的方式出现。基于极大似然估计,先验概率可以通过类别 C k C_k Ck 出现的频率来估计。设 n n n 是总样本数, I ( y i = C k ) I(y_i = C_k) I(yi=Ck) 为指示函数,当第 i i i 个样本属于类别 C k C_k Ck 时取 1,否则取 0。则先验概率 P ( C k ) P(C_k) P(Ck) 估计为:
P ( C k ) = ∑ i = 1 n I ( y i = C k ) n P(C_k) = \frac{\sum_{i=1}^n I(y_i = C_k)}{n} P(Ck)=n∑i=1nI(yi=Ck)
这里, I ( ⋅ ) I(\cdot) I(⋅) 是指示函数,即当条件成立时值为 1,否则为 0。
2. 条件概率的极大似然估计
条件概率 P ( X ∣ C k ) P(X|C_k) P(X∣Ck) 表示在类别 C k C_k Ck 给定的条件下,特征向量 X X X 出现的概率。假设特征之间条件独立,特征向量 X = ( x 1 , x 2 , … , x m ) X = (x_1, x_2, \ldots, x_m) X=(x1,x2,…,xm),则:
P ( X ∣ C k ) = ∏ j = 1 m P ( x j ∣ C k ) P(X|C_k) = \prod_{j=1}^{m} P(x_j|C_k) P(X∣Ck)=j=1∏mP(xj∣Ck)
我们使用极大似然估计来估计每个特征 x j x_j xj 在类别 C k C_k Ck 下的条件概率。假设第 j j j 个特征是离散的(如词频或二元特征),则:
P ( x j ∣ C k ) = ∑ i = 1 n I ( x i j = 1 and y i = C k ) ∑ i = 1 n I ( y i = C k ) P(x_j|C_k) = \frac{\sum_{i=1}^n I(x_{ij} = 1 \ \text{and} \ y_i = C_k)}{\sum_{i=1}^n I(y_i = C_k)} P(xj∣Ck)=∑i=1nI(yi=Ck)∑i=1nI(xij=1 and yi=Ck)
其中 x i j x_{ij} xij 表示第 i i i 个样本的第 j j j 个特征的取值。这个估计表示第 j j j 个特征在类别 C k C_k Ck 下出现的频率。
我们的目标是最大化后验概率 P ( C k ∣ X ) P(C_k|X) P(Ck∣X),根据贝叶斯定理,可以写为:
P ( C k ∣ X ) = P ( X ∣ C k ) ⋅ P ( C k ) P ( X ) P(C_k|X) = \frac{P(X|C_k) \cdot P(C_k)}{P(X)} P(Ck∣X)=P(X)P(X∣Ck)⋅P(Ck)
由于边缘概率 P ( X ) P(X) P(X) 对所有类别 C k C_k Ck 都相同,在分类问题中我们可以忽略它。因此,最大化后验概率 P ( C k ∣ X ) P(C_k|X) P(Ck∣X) 等价于最大化 P ( X ∣ C k ) ⋅ P ( C k ) P(X|C_k) \cdot P(C_k) P(X∣Ck)⋅P(Ck):
C ^ = argmax C k P ( X ∣ C k ) ⋅ P ( C k ) \hat{C} = \underset{C_k}{\text{argmax}} \ P(X|C_k) \cdot P(C_k) C^=Ckargmax P(X∣Ck)⋅P(Ck)
结合极大似然估计的结果,我们有:
C ^ = argmax C k ( ∏ j = 1 m P ( x j ∣ C k ) ⋅ P ( C k ) ) \hat{C} = \underset{C_k}{\text{argmax}} \ \left( \prod_{j=1}^m P(x_j|C_k) \cdot P(C_k) \right) C^=Ckargmax (j=1∏mP(xj∣Ck)⋅P(Ck))
由于对数函数是单调递增的,我们可以取对数,将乘法转换为加法,得到更便于计算的公式:
C ^ = argmax C k ( ∑ j = 1 m log P ( x j ∣ C k ) + log P ( C k ) ) \hat{C} = \underset{C_k}{\text{argmax}} \ \left( \sum_{j=1}^m \log P(x_j|C_k) + \log P(C_k) \right) C^=Ckargmax (j=1∑mlogP(xj∣Ck)+logP(Ck))
在实际应用中,如果某个特征在类别 C k C_k Ck 中未出现,即 ∑ I ( x i j = 1 and y i = C k ) = 0 \sum I(x_{ij} = 1 \ \text{and} \ y_i = C_k) = 0 ∑I(xij=1 and yi=Ck)=0,则 P ( x j ∣ C k ) = 0 P(x_j|C_k) = 0 P(xj∣Ck)=0,这会导致整个后验概率 P ( C k ∣ X ) = 0 P(C_k|X) = 0 P(Ck∣X)=0。为了避免这种情况,我们使用拉普拉斯平滑。
拉普拉斯平滑的基本思想是对每个计数增加一个常数 α > 0 \alpha > 0 α>0,通常取 α = 1 \alpha = 1 α=1。经过平滑处理后,条件概率 P ( x j ∣ C k ) P(x_j|C_k) P(xj∣Ck) 的估计变为:
P ( x j ∣ C k ) = ∑ i = 1 n I ( x i j = 1 and y i = C k ) + α ∑ i = 1 n I ( y i = C k ) + α ⋅ 2 P(x_j|C_k) = \frac{\sum_{i=1}^n I(x_{ij} = 1 \ \text{and} \ y_i = C_k) + \alpha}{\sum_{i=1}^n I(y_i = C_k) + \alpha \cdot 2} P(xj∣Ck)=∑i=1nI(yi=Ck)+α⋅2∑i=1nI(xij=1 and yi=Ck)+α
这里的 2 2 2 是因为 x j x_j xj 是二元特征(取值为 0 或 1),如果特征有更多的取值(如多项分布),则分母的平滑项应该为 α ⋅ 取值数 \alpha \cdot \text{取值数} α⋅取值数。
贝叶斯估计是一种将先验知识与数据相结合的概率估计方法。拉普拉斯平滑可以看作是贝叶斯估计的一种特殊形式。通过贝叶斯估计,我们为 P ( x j ∣ C k ) P(x_j|C_k) P(xj∣Ck) 设定一个先验分布,将其与数据观察结合,得到修正后的估计值:
P ( x j ∣ C k ) = ∑ i = 1 n I ( x i j = 1 and y i = C k ) + α ∑ i = 1 n I ( y i = C k ) + α ⋅ 特征取值数 P(x_j|C_k) = \frac{\sum_{i=1}^n I(x_{ij} = 1 \ \text{and} \ y_i = C_k) + \alpha}{\sum_{i=1}^n I(y_i = C_k) + \alpha \cdot \text{特征取值数}} P(xj∣Ck)=∑i=1nI(yi=Ck)+α⋅特征取值数∑i=1nI(xij=1 and yi=Ck)+α
其中 α \alpha α 是平滑参数,通常设置为 1(即拉普拉斯平滑)。当 α > 1 \alpha > 1 α>1 时,平滑效果更强,适合处理极端数据稀疏的情况。
以下是一个简单的朴素贝叶斯分类器实现(以多项式朴素贝叶斯为例):
import numpy as np
class NaiveBayes:
def fit(self, X, y):
n_samples, n_features = X.shape
self._classes = np.unique(y)
n_classes = len(self._classes)
# 初始化先验概率和条件概率
self._priors = np.zeros(n_classes, dtype=np.float64)
self._likelihoods = np.zeros((n_classes, n_features), dtype=np.float64)
for idx, c in enumerate(self._classes):
X_c = X[y == c]
self._priors[idx] = X_c.shape[0] / float(n_samples)
self._likelihoods[idx, :] = (X_c.sum(axis=0) + 1) / (X_c.shape[0] + n_features)
def predict(self, X):
return [self._predict(x) for x in X]
def _predict(self, x):
posteriors = []
for idx, c in enumerate(self._classes):
prior = np.log(self._priors[idx])
likelihood = np.sum(np.log(self._likelihoods[idx, :]) * x)
posteriors.append(prior + likelihood)
return self._classes[np.argmax(posteriors)]
# 使用实例
X_train = np.array([[1, 0, 1], [1, 1, 0], [0, 1, 1], [0, 0, 1]])
y_train = np.array([0, 0, 1, 1])
nb = NaiveBayes()
nb.fit(X_train, y_train)
X_test = np.array([[1, 0, 0], [0, 1, 0]])
predictions = nb.predict(X_test)
print(predictions)
在实际应用中,使用Scikit-learn的GaussianNB
、MultinomialNB
和BernoulliNB
类可以更高效地实现朴素贝叶斯模型。