共计 2440 个字符,预计需要花费 7 分钟才能阅读完成。
背景:为什么选择朴素贝叶斯
朴素贝叶斯算法在文本分类中有着独特的优势,尤其适合初学者快速实现基础模型。它的核心优势在于:

- 计算效率高:基于概率计算而非迭代优化,训练速度远超 SVM、神经网络等算法
- 内存占用低:只需存储特征概率分布,适合处理高维稀疏文本数据
- 可解释性强:概率输出直观反映分类置信度
但也要注意其局限性:
- 条件独立性假设:现实中文本特征往往存在关联性
- 零概率问题:未出现的特征组合会导致概率为零
技术选型:多项式 vs 伯努利
多项式朴素贝叶斯(MultinomialNB)
适用于:
- 词频统计场景(如文档分类)
- 特征值为出现次数或 TF-IDF 权重
from sklearn.naive_bayes import MultinomialNB
model = MultinomialNB(alpha=1.0) # alpha 为平滑参数
伯努利朴素贝叶斯(BernoulliNB)
适用于:
- 布尔特征场景(如垃圾邮件检测)
- 只关心特征是否出现,不关注出现次数
from sklearn.naive_bayes import BernoulliNB
model = BernoulliNB(binarize=0.5) # 设置二值化阈值
核心实现流程
1. 文本向量化
方案 A:词频统计
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(stop_words='english', max_features=5000)
X_train = vectorizer.fit_transform(train_texts)
方案 B:TF-IDF 加权
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(ngram_range=(1,2), min_df=5)
X_train = tfidf.fit_transform(train_texts)
2. 拉普拉斯平滑
数学原理:
$$ P(w_i|c) = \frac{count(w_i,c) + \alpha}{count(c) + \alpha \times |V|} $$
其中 $\alpha$ 为平滑系数,$|V|$ 为词汇表大小
代码实现:
# sklearn 自动实现平滑
model = MultinomialNB(alpha=1.0) # 默认加 1 平滑
3. 概率计算核心
# 获取各类别的先验概率
class_log_prior = model.class_log_prior_
# 获取特征条件概率的对数值
feature_log_prob = model.feature_log_prob_
# 预测样本概率示例
def predict_proba_custom(model, x):
jll = x @ model.feature_log_prob_.T + model.class_log_prior_
return np.exp(jll) / np.exp(jll).sum(axis=1, keepdims=True)
性能优化策略
特征维度控制
- 使用
max_features限制特征数量 - 通过
min_df过滤低频词
vectorizer = CountVectorizer(max_features=10000, min_df=3)
内存优化
- 使用稀疏矩阵存储
- 及时清理中间变量
from scipy.sparse import csr_matrix
X_sparse = csr_matrix(X)
del X # 释放内存
避坑指南
解决零概率问题
- 必须使用拉普拉斯平滑(alpha > 0)
- 对未知词建立默认概率
model = MultinomialNB(alpha=0.1) # 设置平滑系数
应对特征相关性
- 添加 n -gram 特征捕获局部关联
- 使用特征选择降低冗余
from sklearn.feature_selection import SelectKBest, chi2
selector = SelectKBest(chi2, k=5000)
X_new = selector.fit_transform(X, y)
完整代码模板
# 07- 4 案例完整实现
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report
# 1. 数据加载
data = pd.read_csv('07-4_dataset.csv')
texts = data['text'].values
labels = data['label'].values
# 2. 数据拆分
X_train, X_test, y_train, y_test = train_test_split(texts, labels, test_size=0.2, random_state=42)
# 3. 特征工程
tfidf = TfidfVectorizer(max_features=5000, stop_words='english')
X_train_tf = tfidf.fit_transform(X_train)
X_test_tf = tfidf.transform(X_test)
# 4. 模型训练
model = MultinomialNB(alpha=0.5)
model.fit(X_train_tf, y_train)
# 5. 模型评估
preds = model.predict(X_test_tf)
print(classification_report(y_test, preds))
思考与扩展
如何将该算法扩展到多分类场景?考虑:
- 一对多(OvR)策略
- 多项式朴素贝叶斯原生支持多类
- 类别不平衡时的调整方法
完整代码已上传 Colab:点击访问
正文完
