共计 1706 个字符,预计需要花费 5 分钟才能阅读完成。
算法原理:从贝叶斯定理到文本分类
朴素贝叶斯算法的核心是贝叶斯定理:

$$P(y|x) = \frac{P(x|y)P(y)}{P(x)}$$
其中 $y$ 是类别,$x$ 是特征。在文本分类中,我们假设每个词的出现是相互独立的(这就是 ” 朴素 ” 的由来),这样可以将条件概率简化为:
$$P(x|y) = \prod_{i=1}^{n}P(x_i|y)$$
这种算法特别适合文本分类是因为:
- 文本数据天然具有高维度特征(每个词都是一个特征)
- 朴素假设虽然简单,但在实践中表现意外地好
- 计算效率高,适合处理大规模文本数据
三种朴素贝叶斯变体比较
- 多项式朴素贝叶斯 (MultinomialNB)
- 最适合词频统计的文本分类
- 考虑词出现的次数
-
典型应用:新闻分类、垃圾邮件检测
-
伯努利朴素贝叶斯 (BernoulliNB)
- 只考虑词是否出现(二值特征)
- 适合短文本或文档中词出现与否比频率更重要的情况
-
典型应用:情感分析
-
高斯朴素贝叶斯 (GaussianNB)
- 假设特征服从正态分布
- 不太适合文本数据,更适合连续数值特征
代码实战:中文文本分类完整流程
# 1. 数据准备和预处理
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
# 中文分词函数
def chinese_word_cut(text):
return " ".join(jieba.cut(text))
# 示例数据:假设我们有文本和对应标签
texts = ["这个产品很好", "质量很差", "服务不错", "不推荐购买"]
labels = [1, 0, 1, 0] # 1 表示正面,0 表示负面
# 2. 分词处理
texts_cut = [chinese_word_cut(text) for text in texts]
# 3. 特征提取(TF-IDF)tfidf = TfidfVectorizer(token_pattern=r'(?u)\b\w+\b')
X = tfidf.fit_transform(texts_cut)
y = labels
# 4. 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
# 5. 训练模型
model = MultinomialNB(alpha=1.0) # alpha 是平滑参数
model.fit(X_train, y_train)
# 6. 评估
print("准确率:", model.score(X_test, y_test))
性能优化技巧
- TF-IDF 特征加权
- 比单纯的词频统计更能反映词的重要性
- 自动降低常见词(如 ” 的 ”、” 是 ”)的权重
-
提升有区分度的关键词的影响
-
拉普拉斯平滑 (alpha 参数)
- 解决零概率问题(训练集中未出现的词)
- 通常设置为 1(加 1 平滑),但可以调整
-
太小可能导致过拟合,太大可能欠拟合
-
停用词处理
- 可以自定义停用词列表
- 或者使用现有的中文停用词库
常见问题及解决方案
- 特征稀疏问题
- 现象:大部分文档只包含词汇表的一小部分词
-
解决:使用 TF-IDF 而非词频;考虑 n -gram 特征
-
停用词干扰
- 现象:常见词对分类没有帮助但影响模型
-
解决:使用停用词表;设置 min_df 参数过滤低频词
-
新词处理
- 现象:测试集中出现训练集没有的词
-
解决:确保平滑参数 alpha 合理;增大训练数据
-
长尾词问题
- 现象:很多词出现频率极低
- 解决:设置 min_df 参数;使用词干提取或词形还原
延伸思考
- 如何处理类别不平衡问题?
- 可以考虑 class_prior 参数设置先验概率
-
或者对少数类样本进行过采样
-
如何应对领域特定术语?
- 可以自定义词典添加到分词器中
-
或者使用领域特定的预训练词向量
-
如何评估模型在业务场景中的真实效果?
- 准确率之外,还要看召回率、F1 值
- 特别是对于不均衡数据集
朴素贝叶斯虽然在理论上做了简化假设,但在实际文本分类任务中往往能取得不错的效果,尤其是当特征维度很高而数据量不是特别大的时候。它的训练速度快、实现简单的特点,使其成为文本分类任务的一个很好的基线模型。
正文完
