朴素贝叶斯(Naive Bayes)是一类基于贝叶斯定理的简单而有效的分类算法。它假设特征之间是相互独立的,即在给定目标变量的情况下,每个特征都不依赖于其他特征。尽管这个假设在实际中很难成立,朴素贝叶斯在许多场景下仍表现得非常好,特别是对于文本分类等高维数据的应用。
贝叶斯定理表明给定一个事件发生的条件下另一个事件发生的概率:
P ( A ∣ B ) = P ( B ∣ A ) ⋅ P ( A ) P ( B ) {P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)}} P(A∣B)=P(B)P(B∣A)⋅P(A)
P(A∣B) 是在已知B的情况下A发生的概率(后验概率)。
P(B∣A)是在已知A的情况下B发生的概率(条件概率)。
P(A)是A发生的先验概率。
P(B)是 B发生的总概率。
在分类问题中,给定一个特征向量 X = ( x 1 , x 2 , x 3 . . . x n ) X = (x_1,x_2,x_3...x_n) X=(x1,x2,x3...xn),目标是计算每个类别 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)都是相等的,所以只需要比较分子
P ( X ∣ C k ) ⋅ P ( C k ) P(X | C_k) \cdot P(C_k) P(X∣Ck)⋅P(Ck)来决定分类结果
朴素贝叶斯的“朴素”假设是特征 xi 之间是条件独立的,因此:
P ( X ∣ C k ) = P ( x 1 ∣ C k ) ⋅ P ( x 2 ∣ C k ) ⋅ ⋯ ⋅ P ( x n ∣ C k ) P(X | C_k) = P(x_1 | C_k) \cdot P(x_2 | C_k) \cdot \dots \cdot P(x_n | C_k) P(X∣Ck)=P(x1∣Ck)⋅P(x2∣Ck)⋅⋯⋅P(xn∣Ck)
最终,分类器的决策规则变为:
P ( C k ∣ X ) ∝ P ( C k ) ⋅ ∏ i = 1 n P ( x i ∣ C k ) P(C_k | X) \propto P(C_k) \cdot \prod_{i=1}^n P(x_i | C_k) P(Ck∣X)∝P(Ck)⋅i=1∏nP(xi∣Ck)
在朴素贝叶斯分类中,贝叶斯估计用于避免由于零概率问题而导致模型失效的情况。通过引入伪计数(通常称为拉普拉斯平滑或贝叶斯平滑),可以确保所有的概率都不会为零。
拉普拉斯平滑通过在每个类别的词频上加上一个常数(通常为 1)来防止零概率问题。拉普拉斯平滑后的条件概率公式为:
P ( x i ∣ C k ) = N ( x i , C k ) + λ N ( C k ) + λ ⋅ ∣ V ∣ P(x_i | C_k) = \frac{N(x_i, C_k) + \lambda}{N(C_k) + \lambda \cdot |V|} P(xi∣Ck)=N(Ck)+λ⋅∣V∣N(xi,Ck)+λ
N ( x i , C k ) N(x_i,C_k) N(xi,Ck) 是在类别 C k C_k Ck中,特征 x i x_i xi出现的次数
N ( C k ) N(C_k) N(Ck)是类别 C k C_k Ck中所有特征出现的总次数。
λ \lambda λ是平滑参数,通常取值为 1(拉普拉斯平滑),但也可以取其他值
∣ V ∣ |V| ∣V∣是特征的总数
平滑后,所有的特征都会有一个非零的概率,即使某些特征在某类别中没有出现过
在引入平滑后,分类器的决策规则变为:
P ( C k ∣ X ) ∝ P ( C k ) ⋅ ∏ i = 1 n N ( x i , C k ) + λ N ( C k ) + λ ⋅ ∣ V ∣ P(C_k | X) \propto P(C_k) \cdot \prod_{i=1}^n \frac{N(x_i, C_k) + \lambda}{N(C_k) + \lambda \cdot |V|} P(Ck∣X)∝P(Ck)⋅i=1∏nN(Ck)+λ⋅∣V∣N(xi,Ck)+λ
通过调整 λ \lambda λ 的值,可以控制平滑的强度。在文本分类中,通常会使用较小的平滑参数来防止过度平滑。
在sklearn
中,提供了多个朴素贝叶斯分类器的实现,包括 GaussianNB
、MultinomialNB
和 BernoulliNB
。下面是一个简单的使用MultinomialNB
处理文本分类问题的示例。
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score
# 加载新闻组数据
newsgroups = fetch_20newsgroups(subset='train')
X = newsgroups.data
y = newsgroups.target
# 将文本数据转换为词频矩阵
vectorizer = CountVectorizer()
X_counts = vectorizer.fit_transform(X)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_counts, y, test_size=0.25, random_state=42)
# 初始化多项式朴素贝叶斯分类器
nb = MultinomialNB()
# 训练模型
nb.fit(X_train, y_train)
# 预测
y_pred = nb.predict(X_test)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')
通过调整超参数(如 alpha
)可以提高模型的性能。例如,在文本分类中,通常会使用拉普拉斯平滑来处理零概率问题。
# 使用拉普拉斯平滑(alpha)
nb = MultinomialNB(alpha=0.5)
nb.fit(X_train, y_train)
# 预测并评估
y_pred = nb.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy with alpha=0.5: {accuracy:.2f}')