朴素贝叶斯实战:从原理到07-4案例的完整实现指南

1次阅读
没有评论

共计 2440 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

背景:为什么选择朴素贝叶斯

朴素贝叶斯算法在文本分类中有着独特的优势,尤其适合初学者快速实现基础模型。它的核心优势在于:

朴素贝叶斯实战:从原理到 07- 4 案例的完整实现指南

  • 计算效率高:基于概率计算而非迭代优化,训练速度远超 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))

思考与扩展

如何将该算法扩展到多分类场景?考虑:

  1. 一对多(OvR)策略
  2. 多项式朴素贝叶斯原生支持多类
  3. 类别不平衡时的调整方法

完整代码已上传 Colab:点击访问

正文完
 0
评论(没有评论)