共计 1715 个字符,预计需要花费 5 分钟才能阅读完成。
贝叶斯学派与频率学派之争:从理论到朴素贝叶斯分类器实践
1. 开篇实例:两大学派的应用场景差异
假设我们正在进行 A / B 测试,比较两种网页设计的效果差异。频率学派会计算 p 值,判断差异是否显著;而贝叶斯学派则会计算后验概率,给出每种设计更优的概率。例如,频率学派可能得出结论 ”p=0.03,拒绝原假设 ”,而贝叶斯学派可能得出 ” 设计 A 有 78% 的概率优于设计 B ”。

2. 技术对比
2.1 频率学派方法
频率学派的核心是最大似然估计 (MLE):
$$\hat{\theta}{MLE} = \arg\max P(X|\theta)$$
假设检验中,p 值的定义为:
$$p = P(观察到的或更极端的数据 |H_0 为真)$$
2.2 贝叶斯学派方法
贝叶斯方法基于后验分布:
$$P(\theta|X) = \frac{P(X|\theta)P(\theta)}{P(X)}$$
先验选择常见的有:
- 共轭先验(计算方便)
- 无信息先验(如均匀分布)
- 层次先验(超参数也有分布)
3. 朴素贝叶斯实战
3.1 sklearn 实现
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
# TF-IDF 特征提取
tfidf = TfidfVectorizer()
X_train = tfidf.fit_transform(train_texts)
# 带拉普拉斯平滑的朴素贝叶斯
model = MultinomialNB(alpha=1.0) # alpha= 1 为加 1 平滑
model.fit(X_train, y_train)
3.2 numpy 手写实现
import numpy as np
class NaiveBayes:
def __init__(self, alpha=1.0):
self.alpha = alpha # 平滑参数
def fit(self, X, y):
# 计算先验概率
self.classes, counts = np.unique(y, return_counts=True)
self.priors = (counts + self.alpha) / (len(y) + len(self.classes)*self.alpha)
# 计算条件概率
self.cond_probs = []
for c in self.classes:
X_c = X[y==c]
total = X_c.sum(axis=0) + self.alpha
self.cond_probs.append(total / (total.sum() + X.shape[1]*self.alpha))
def predict(self, X):
# 计算后验概率
posteriors = []
for c, prior in enumerate(self.priors):
log_prob = np.log(prior) + (X * np.log(self.cond_probs[c])).sum(axis=1)
posteriors.append(log_prob)
return self.classes[np.argmax(posteriors, axis=0)]
4. 进阶讨论
4.1 半朴素贝叶斯 TAN 算法
TAN(Tree-Augmented Naive Bayes) 放宽了特征独立假设,允许特征间存在树状依赖关系。实现步骤:
- 计算每对特征间的条件互信息
- 构建最大生成树
- 选择根节点并确定边方向
- 估计条件概率表
4.2 贝叶斯深度学习
现代发展包括:
- 贝叶斯神经网络(参数作为分布)
- 变分自编码器(VAE)
- 蒙特卡洛 Dropout(近似贝叶斯推断)
5. 避坑指南
5.1 类别不平衡处理
- 调整先验概率反映真实分布
- 使用不同的损失函数权重
- 采用过采样 / 欠采样技术
5.2 高维特征处理
- 特征选择(互信息、卡方检验等)
- 降维(PCA、LDA 等)
- 正则化方法
6. 延伸思考
- 如何设计实验验证特征条件独立性假设是否成立?
- 当先验知识与样本数据冲突时,应如何权衡?
- 在什么场景下贝叶斯方法会明显优于频率学派方法?
本文从理论基础到实践实现,系统梳理了贝叶斯与频率学派的差异,并通过朴素贝叶斯分类器的实现展示了贝叶斯方法的应用。希望读者能借此理解不同概率建模范式的特点,在实际问题中选择合适的方法。
正文完
