机器学习之朴素贝叶斯

目录

  1. 简介
  2. 贝叶斯定理基础
  3. 朴素假设
  4. 算法原理
  5. 朴素贝叶斯的变体
  6. 优缺点分析
  7. 应用场景
  8. 代码示例
  9. 参数估计与平滑
  10. 总结

简介

朴素贝叶斯(Naive Bayes)是一类基于贝叶斯定理的概率分类器,具有"朴素"的特征假设:假设特征之间相互独立。尽管这个假设在现实世界中很少成立,但朴素贝叶斯分类器在许多实际应用中表现出了惊人的有效性。

朴素贝叶斯算法由以下特点:

  • 理论基础扎实:基于严格的概率论和统计学理论
  • 计算效率高:训练和预测的时间复杂度都较低
  • 对小数据集友好:在数据量较少时也能有不错的表现
  • 适合高维数据:能够处理具有大量特征的数据

贝叶斯定理基础

朴素贝叶斯的核心是贝叶斯定理(Bayes’ Theorem),它描述了条件概率之间的关系:

P ( A ∣ B ) = P ( B ∣ A ) ⋅ P ( A ) P ( B ) P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)

其中:

  • P ( A ∣ B ) P(A|B) P(AB) 是在事件 B B B 发生的条件下事件 A A A 发生的概率(后验概率)
  • P ( B ∣ A ) P(B|A) P(BA) 是在事件 A A A 发生的条件下事件 B B B 发生的概率(似然概率)
  • P ( A ) P(A) P(A) 是事件 A A A 发生的先验概率
  • P ( B ) P(B) P(B) 是事件 B B B 发生的边际概率

在分类问题中,我们将贝叶斯定理应用于给定特征向量 x = ( x 1 , x 2 , … , x n ) \mathbf{x} = (x_1, x_2, \ldots, x_n) x=(x1,x2,,xn) 的条件下,预测类别 y y y

P ( y ∣ x ) = P ( x ∣ y ) ⋅ P ( y ) P ( x ) P(y|\mathbf{x}) = \frac{P(\mathbf{x}|y) \cdot P(y)}{P(\mathbf{x})} P(yx)=P(x)P(xy)P(y)

由于 P ( x ) P(\mathbf{x}) P(x) 对于所有类别都是相同的(它只是特征向量的边际概率),我们可以忽略它,只需要比较分子:

P ( y ∣ x ) ∝ P ( x ∣ y ) ⋅ P ( y ) P(y|\mathbf{x}) \propto P(\mathbf{x}|y) \cdot P(y) P(yx)P(xy)P(y)

因此,朴素贝叶斯分类器的决策规则为:

y ^ = arg ⁡ max ⁡ y P ( y ) ⋅ P ( x ∣ y ) \hat{y} = \arg\max_{y} P(y) \cdot P(\mathbf{x}|y) y^=argymaxP(y)P(xy)


朴素假设

朴素贝叶斯的"朴素"之处在于它假设所有特征在给定类别条件下相互独立

P ( x ∣ y ) = P ( x 1 , x 2 , … , x n ∣ y ) = ∏ i = 1 n P ( x i ∣ y ) P(\mathbf{x}|y) = P(x_1, x_2, \ldots, x_n|y) = \prod_{i=1}^{n} P(x_i|y) P(xy)=P(x1,x2,,xny)=i=1nP(xiy)

这个假设将联合概率分解为各个特征条件概率的乘积,大大简化了计算。

虽然这个假设在实际中很少成立(特征之间往往存在相关性),但朴素贝叶斯在许多应用中仍然表现良好,原因包括:

  1. 分类任务只需要相对排序:即使概率估计不准确,只要排序正确即可
  2. 特征相关性可能相互抵消:某些特征的正相关和负相关可能相互平衡
  3. 高维空间的特性:在高维空间中,独立性假设的影响可能被稀释

算法原理

训练阶段

在训练阶段,朴素贝叶斯需要估计两类参数:

  1. 类别先验概率
    P ( y = c ) = N c N P(y = c) = \frac{N_c}{N} P(y=c)=NNc

    其中 N c N_c Nc 是类别 c c c 的样本数, N N N 是总样本数。

  2. 每个特征的条件概率
    P ( x i ∣ y = c ) P(x_i|y = c) P(xiy=c)

    这取决于具体的朴素贝叶斯变体(高斯、多项式或伯努利)。

预测阶段

对于一个新的样本 x = ( x 1 , x 2 , … , x n ) \mathbf{x} = (x_1, x_2, \ldots, x_n) x=(x1,x2,,xn)

  1. 计算每个类别的后验概率(忽略分母):
    P ( y = c ) ⋅ ∏ i = 1 n P ( x i ∣ y = c ) P(y = c) \cdot \prod_{i=1}^{n} P(x_i|y = c) P(y=c)i=1nP(xiy=c)

  2. 选择后验概率最大的类别:
    y ^ = arg ⁡ max ⁡ c [ P ( y = c ) ⋅ ∏ i = 1 n P ( x i ∣ y = c ) ] \hat{y} = \arg\max_{c} \left[ P(y = c) \cdot \prod_{i=1}^{n} P(x_i|y = c) \right] y^=argcmax[P(y=c)i=1nP(xiy=c)]

对数空间计算

为了避免数值下溢问题(多个小概率相乘可能导致结果为零),通常在对数空间进行计算:

y ^ = arg ⁡ max ⁡ c [ log ⁡ P ( y = c ) + ∑ i = 1 n log ⁡ P ( x i ∣ y = c ) ] \hat{y} = \arg\max_{c} \left[ \log P(y = c) + \sum_{i=1}^{n} \log P(x_i|y = c) \right] y^=argcmax[logP(y=c)+i=1nlogP(xiy=c)]


朴素贝叶斯的变体

根据特征分布的不同假设,朴素贝叶斯有几种常见的变体:

1. 高斯朴素贝叶斯 (Gaussian Naive Bayes)

适用场景:特征是连续值,且假设每个特征在给定类别下服从正态分布

概率密度函数
P ( x i ∣ y = c ) = 1 2 π σ c , i 2 exp ⁡ ( − ( x i − μ c , i ) 2 2 σ c , i 2 ) P(x_i|y = c) = \frac{1}{\sqrt{2\pi\sigma_{c,i}^2}} \exp\left(-\frac{(x_i - \mu_{c,i})^2}{2\sigma_{c,i}^2}\right) P(xiy=c)=2πσc,i2 1exp(2σc,i2(xiμc,i)2)

其中:

  • μ c , i \mu_{c,i} μc,i 是类别 c c c 中特征 i i i 的均值
  • σ c , i 2 \sigma_{c,i}^2 σc,i2 是类别 c c c 中特征 i i i 的方差

参数估计
μ c , i = 1 N c ∑ j : y j = c x j , i \mu_{c,i} = \frac{1}{N_c} \sum_{j: y_j = c} x_{j,i} μc,i=Nc1j:yj=cxj,i
σ c , i 2 = 1 N c ∑ j : y j = c ( x j , i − μ c , i ) 2 \sigma_{c,i}^2 = \frac{1}{N_c} \sum_{j: y_j = c} (x_{j,i} - \mu_{c,i})^2 σc,i2=Nc1j:yj=c(xj,iμc,i)2

特点

  • 适用于连续型特征
  • 对异常值较为敏感
  • 假设特征服从正态分布

2. 多项式朴素贝叶斯 (Multinomial Naive Bayes)

适用场景:特征是计数数据,常用于文本分类(如词频统计)。

概率计算
P ( x i ∣ y = c ) = N c , i + α N c + α ⋅ n P(x_i|y = c) = \frac{N_{c,i} + \alpha}{N_c + \alpha \cdot n} P(xiy=c)=Nc+αnNc,i+α

其中:

  • N c , i N_{c,i} Nc,i 是类别 c c c 中特征 i i i 的总计数
  • N c N_c Nc 是类别 c c c 中所有特征的总计数
  • n n n 是特征的总数(词汇表大小)
  • α \alpha α 是平滑参数(拉普拉斯平滑)

特点

  • 适用于离散计数数据
  • 广泛用于文本分类
  • 需要平滑处理零频率问题

3. 伯努利朴素贝叶斯 (Bernoulli Naive Bayes)

适用场景:特征是二元变量(0/1),表示特征是否出现。

概率计算
P ( x i ∣ y = c ) = p c , i x i ⋅ ( 1 − p c , i ) 1 − x i P(x_i|y = c) = p_{c,i}^{x_i} \cdot (1 - p_{c,i})^{1 - x_i} P(xiy=c)=pc,ixi(1pc,i)1xi

其中 p c , i p_{c,i} pc,i 是类别 c c c 中特征 i i i 出现的概率:

p c , i = N c , i + α N c + 2 α p_{c,i} = \frac{N_{c,i} + \alpha}{N_c + 2\alpha} pc,i=Nc+2αNc,i+α

特点

  • 适用于二元特征
  • 关注特征是否出现而非出现次数
  • 常用于短文本分类

4. 补充朴素贝叶斯 (Complement Naive Bayes)

适用场景:多项式朴素贝叶斯的改进版本,专门用于处理类别不平衡问题。

核心思想:通过计算"补集"(非目标类别)的概率来平衡类别权重。

特点

  • 对类别不平衡更鲁棒
  • 在文本分类中表现优于标准多项式朴素贝叶斯
  • 适用于正负样本差异较大的场景

优缺点分析

优点

  1. 计算效率高

    • 训练时间复杂度: O ( n ⋅ d ) O(n \cdot d) O(nd),其中 n n n 是样本数, d d d 是特征数
    • 预测时间复杂度: O ( d ) O(d) O(d)
    • 适合大规模数据集
  2. 易于实现

    • 算法原理简单直观
    • 参数估计直接
    • 不需要复杂的优化过程
  3. 对小数据集友好

    • 在样本量较少时也能有不错的表现
    • 不会过拟合
  4. 适合高维数据

    • 特征数量远大于样本数量时仍能工作
    • 在文本分类等高维场景表现良好
  5. 可解释性强

    • 可以通过条件概率了解每个特征对分类的贡献
    • 结果易于理解和解释

缺点

  1. 独立性假设过强

    • 特征之间的相关性会降低分类准确性
    • 在特征高度相关的场景中表现不佳
  2. 对特征分布敏感

    • 高斯朴素贝叶斯假设正态分布
    • 当实际分布与假设不符时,性能下降
  3. 零概率问题

    • 如果某个特征值在训练集中从未出现,会导致零概率
    • 需要平滑技术(如拉普拉斯平滑)来解决
  4. 输出概率校准

    • 朴素贝叶斯输出的概率往往过于极端(接近0或1)
    • 可能需要概率校准(如Platt Scaling或Isotonic Regression)
  5. 无法捕捉特征交互

    • 由于独立性假设,无法学习特征之间的交互作用
    • 对于需要特征组合的任务表现有限

应用场景

朴素贝叶斯在以下领域有广泛应用:

1. 文本分类

  • 垃圾邮件检测:判断邮件是否为垃圾邮件
  • 新闻分类:将新闻自动分类到不同主题
  • 情感分析:判断文本的情感倾向(正面/负面)
  • 主题分类:将文档分配到预定义的主题类别

2. 医疗诊断

  • 疾病预测:根据症状预测患者是否患有某种疾病
  • 医学影像分析:辅助医生进行诊断

3. 推荐系统

  • 个性化推荐:根据用户历史行为预测兴趣
  • 广告点击预测:预测用户是否点击广告

4. 欺诈检测

  • 信用卡欺诈检测:识别可疑交易
  • 网络入侵检测:识别异常网络行为

5. 其他应用

  • 客户流失预测:预测客户是否会流失
  • 拼写检查:纠正拼写错误
  • 生物信息学:基因序列分类

代码示例

Python 使用 scikit-learn

import numpy as np
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report

# 生成示例数据
np.random.seed(42)
n_samples = 1000
n_features = 20
n_classes = 3

# 生成高斯分布数据
X = np.random.randn(n_samples, n_features)
y = np.random.randint(0, n_classes, n_samples)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 1. 高斯朴素贝叶斯
gnb = GaussianNB()
gnb.fit(X_train, y_train)
y_pred_gnb = gnb.predict(X_test)

print("高斯朴素贝叶斯:")
print(f"准确率: {accuracy_score(y_test, y_pred_gnb):.4f}")
print("-" * 50)

# 2. 多项式朴素贝叶斯(适用于非负整数特征)
X_multinomial = np.random.randint(0, 10, (n_samples, n_features))
X_train_mnb, X_test_mnb, y_train_mnb, y_test_mnb = train_test_split(
    X_multinomial, y, test_size=0.3, random_state=42
)

mnb = MultinomialNB(alpha=1.0)  # alpha 是拉普拉斯平滑参数
mnb.fit(X_train_mnb, y_train_mnb)
y_pred_mnb = mnb.predict(X_test_mnb)

print("多项式朴素贝叶斯:")
print(f"准确率: {accuracy_score(y_test_mnb, y_pred_mnb):.4f}")
print("-" * 50)

# 3. 伯努利朴素贝叶斯(适用于二元特征)
X_bernoulli = np.random.randint(0, 2, (n_samples, n_features))
X_train_bnb, X_test_bnb, y_train_bnb, y_test_bnb = train_test_split(
    X_bernoulli, y, test_size=0.3, random_state=42
)

bnb = BernoulliNB(alpha=1.0)
bnb.fit(X_train_bnb, y_train_bnb)
y_pred_bnb = bnb.predict(X_test_bnb)

print("伯努利朴素贝叶斯:")
print(f"准确率: {accuracy_score(y_test_bnb, y_pred_bnb):.4f}")
print("-" * 50)

# 查看类别先验概率
print("类别先验概率 (高斯NB):")
print(gnb.class_prior_)

文本分类示例

from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB

# 示例文本数据
texts = [
    "I love this movie, it's great!",
    "This film is terrible and boring.",
    "Amazing performance by the actors.",
    "Worst movie I've ever seen.",
    "I really enjoyed watching this.",
    "Complete waste of time and money.",
]
labels = [1, 0, 1, 0, 1, 0]  # 1: 正面, 0: 负面

# 构建文本分类管道
text_clf = Pipeline([
    ('vect', CountVectorizer()),  # 将文本转换为词频向量
    ('tfidf', TfidfTransformer()),  # TF-IDF转换
    ('clf', MultinomialNB(alpha=1.0)),  # 多项式朴素贝叶斯
])

# 训练模型
text_clf.fit(texts, labels)

# 预测新文本
new_texts = [
    "This is an excellent movie!",
    "I hated every minute of it.",
]
predictions = text_clf.predict(new_texts)
probs = text_clf.predict_proba(new_texts)

print("文本分类结果:")
for text, pred, prob in zip(new_texts, predictions, probs):
    sentiment = "正面" if pred == 1 else "负面"
    print(f"文本: '{text}'")
    print(f"预测: {sentiment}")
    print(f"概率: 负面={prob[0]:.4f}, 正面={prob[1]:.4f}")
    print("-" * 50)

参数估计与平滑

拉普拉斯平滑 (Laplace Smoothing)

当某个特征值在训练集中从未出现时,会导致零概率问题。拉普拉斯平滑通过给每个计数添加一个小的常数 α \alpha α 来解决:

P ( x i ∣ y = c ) = N c , i + α N c + α ⋅ n P(x_i|y = c) = \frac{N_{c,i} + \alpha}{N_c + \alpha \cdot n} P(xiy=c)=Nc+αnNc,i+α

其中:

  • α \alpha α 是平滑参数(通常为1)
  • n n n 是特征的可能取值数量

α = 1 \alpha = 1 α=1 时,称为拉普拉斯平滑;当 0 < α < 1 0 < \alpha < 1 0<α<1 时,称为Lidstone平滑

Lidstone平滑

Lidstone平滑是拉普拉斯平滑的推广,允许使用更小的平滑参数:

P ( x i ∣ y = c ) = N c , i + α N c + α ⋅ n , 0 < α ≤ 1 P(x_i|y = c) = \frac{N_{c,i} + \alpha}{N_c + \alpha \cdot n}, \quad 0 < \alpha \leq 1 P(xiy=c)=Nc+αnNc,i+α,0<α1

较小的 α \alpha α 值在数据量较大时效果更好,因为它对原始计数的干扰更小。

贝叶斯估计

贝叶斯估计使用先验分布来估计参数。对于多项式分布,常用的先验是狄利克雷先验(Dirichlet prior):

P ( x i ∣ y = c ) = N c , i + α i N c + ∑ j = 1 n α j P(x_i|y = c) = \frac{N_{c,i} + \alpha_i}{N_c + \sum_{j=1}^{n} \alpha_j} P(xiy=c)=Nc+j=1nαjNc,i+αi

其中 α = ( α 1 , α 2 , … , α n ) \alpha = (\alpha_1, \alpha_2, \ldots, \alpha_n) α=(α1,α2,,αn) 是狄利克雷先验的超参数。


总结

朴素贝叶斯是一个简单而强大的分类算法,具有以下特点:

核心要点

  1. 理论基础:基于贝叶斯定理,通过独立性假设简化联合概率计算
  2. 算法效率:训练和预测都很快,适合大规模数据
  3. 适用场景:文本分类、垃圾邮件过滤、医疗诊断等
  4. 主要变体:高斯、多项式、伯努利朴素贝叶斯
  5. 关键技巧:平滑处理解决零概率问题

选择建议

场景 推荐算法
连续型特征 高斯朴素贝叶斯
词频统计 多项式朴素贝叶斯
二元特征 伯努利朴素贝叶斯
类别不平衡 补充朴素贝叶斯

实践建议

  1. 特征预处理:根据算法类型进行适当的特征转换
  2. 平滑参数调优:通过交叉验证选择合适的 α \alpha α
  3. 概率校准:如果需要准确的后验概率,考虑使用概率校准
  4. 特征选择:去除不相关或冗余特征可以提高性能

朴素贝叶斯虽然"朴素",但在实际应用中往往能取得令人满意的效果,特别是在文本分类等高维稀疏数据场景中。它的简单性、高效性和可解释性使其成为机器学习工具箱中不可或缺的算法之一。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐