贝叶斯算法学习
贝叶斯算法学习
- 贝叶斯算法基础与原理
- 应用场景
- 主要分类
- 优缺点
- 简单示例
- 代码实现
贝叶斯算法是基于贝叶斯定理的一种统计学习方法,在机器学习、数据挖掘、自然语言处理等领域有广泛应用。以下是其原理、应用和示例的详细介绍:
贝叶斯算法基础与原理
贝叶斯定理公式为:
P ( A ∣ B ) = P ( B ∣ A ) ⋅ P ( A ) P ( B ) P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} P(A∣B)=P(B)P(B∣A)⋅P(A)
其中:
P(A|B) 是后验概率(在观测到B后A的概率);
P(B|A) 是似然概率(在A下B的观测概率);
P(A) 是先验概率(A的初始概率)。
贝叶斯算法基于贝叶斯定理,通过已知的先验概率和条件概率来计算后验概率。在分类问题中,将数据的特征看作事件B,类别看作事件A,利用训练数据计算出先验概率(P(A))和条件概率(P(B|A)),然后对于新的数据,根据贝叶斯定理计算其属于各个类别的后验概率(P(A|B)),将其分类到后验概率最大的类别中。
应用场景
垃圾邮件过滤:根据邮件中出现的词语来判断邮件是否为垃圾邮件。先统计大量垃圾邮件和正常邮件中每个词语出现的概率,作为先验概率和条件概率。对于新收到的邮件,计算其属于垃圾邮件和正常邮件的后验概率,根据概率大小判断邮件类别。
文本分类:对文本进行分类,如将新闻文本分为政治、经济、体育等类别。通过统计不同类别文本中词语的出现频率,计算先验概率和条件概率,然后对新的文本计算其属于各个类别的后验概率,实现分类。
医疗诊断:根据患者的症状、检查结果等特征来判断患者是否患有某种疾病。利用以往病例数据计算出疾病的先验概率以及症状在患病和未患病情况下出现的条件概率,然后对新患者的症状计算其患病的后验概率,辅助医生进行诊断。
主要分类
朴素贝叶斯(Naïve Bayes):假设特征之间相互独立,计算简单高效,适用于文本分类(如垃圾邮件过滤)。
TAN算法(Tree Augmented Bayes Network):通过引入属性间的依赖关系改进朴素贝叶斯的独立性假设。
贝叶斯网络:用有向图表示变量间的概率依赖关系,适用于复杂推理(如医疗诊断、基因分析)
优缺点
- 优点
- 小样本下表现良好,能融合先验知识;
- 计算效率高,适合高维数据。
- 缺点:
- 独立性假设可能不成立(朴素贝叶斯);
- 先验概率选择对结果敏感。
简单示例
假设有两个盒子,盒子A1中有3个红球和2个白球,盒子A2中有2个红球和3个白球。随机选择一个盒子,然后从该盒子中随机取出一个球,结果是红球。现在要判断这个球是从盒子A1中取出的概率。
设事件A表示 “球是从盒子A中取出的”,事件B表示 “取出的球是红球”。
先计算先验概率 P ( A ) = 1 2 P(A)=\frac{1}{2} P(A)=21, P ( A ‾ ) = 1 2 P(\overline{A})=\frac{1}{2} P(A)=21。
条件概率 P ( B ∣ A ) = 3 5 P(B|A)=\frac{3}{5} P(B∣A)=53, P ( B ∣ A ‾ ) = 2 5 P(B|\overline{A})=\frac{2}{5} P(B∣A)=52。
根据贝叶斯定理, P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ∣ A ) P ( A ) + P ( B ∣ A ‾ ) P ( A ‾ ) = 3 5 × 1 2 3 5 × 1 2 + 2 5 × 1 2 = 3 5 P(A|B)=\frac{P(B|A)P(A)}{P(B|A)P(A)+P(B|\overline{A})P(\overline{A})}=\frac{\frac{3}{5}\times\frac{1}{2}}{\frac{3}{5}\times\frac{1}{2}+\frac{2}{5}\times\frac{1}{2}}=\frac{3}{5} P(A∣B)=P(B∣A)P(A)+P(B∣A)P(A)P(B∣A)P(A)=53×21+52×2153×21=53。
所以,在已知取出的球是红球的情况下,这个球是从盒子A中取出的概率为 3 5 \frac{3}{5} 53。
代码实现
下面是一个使用 Python 实现简单的基于朴素贝叶斯算法的文本分类器的示例代码,这里以判断文本是属于积极情绪还是消极情绪的简单情感分类为例。在这个示例中,我们将使用朴素贝叶斯的基本原理,通过统计单词在不同类别(积极、消极)中出现的频率来进行分类预测。
# 假设的训练数据,每个元组的第一个元素是文本,第二个元素是情感标签(1 表示积极,0 表示消极)
train_data = [("我今天很开心", 1),("这部电影太棒了", 1),("我感觉很糟糕", 0),("这顿饭真难吃", 0)
]# 用于存储每个单词在积极和消极类别中出现的次数
positive_word_count = {}
negative_word_count = {}# 用于存储积极和消极类别的文本总数
positive_doc_count = 0
negative_doc_count = 0# 处理训练数据,统计单词出现次数和类别文本总数
for text, label in train_data:words = text.split()if label == 1:positive_doc_count += 1for word in words:positive_word_count[word] = positive_word_count.get(word, 0) + 1else:negative_doc_count += 1for word in words:negative_word_count[word] = negative_word_count.get(word, 0) + 1# 计算先验概率
total_doc_count = positive_doc_count + negative_doc_count
p_positive = positive_doc_count / total_doc_count
p_negative = negative_doc_count / total_doc_count# 定义分类函数
def classify(text):words = text.split()p_text_given_positive = 1p_text_given_negative = 1for word in words:# 计算在积极类别下,单词出现的概率p_word_given_positive = (positive_word_count.get(word, 0) + 1) / (sum(positive_word_count.values()) + len(positive_word_count))p_text_given_positive *= p_word_given_positive# 计算在消极类别下,单词出现的概率p_word_given_negative = (negative_word_count.get(word, 0) + 1) / (sum(negative_word_count.values()) + len(negative_word_count))p_text_given_negative *= p_word_given_negative# 计算后验概率p_positive_given_text = p_text_given_positive * p_positivep_negative_given_text = p_text_given_negative * p_negative# 根据后验概率判断类别if p_positive_given_text > p_negative_given_text:return 1else:return 0
上面的代码用到了贝叶斯平滑,即分母是sum(positive_word_count.values()) + len(positive_word_count)。
朴素贝叶斯中条件概率的计算朴素贝叶斯分类器在进行分类时,需要计算在某个类别 C 下,某个特征 (x_i) 出现的条件概率 P ( x i ∣ C ) P(x_i|C) P(xi∣C)。在文本分类的场景里,特征 x i x_i xi 通常是一个单词,类别 C 可以是积极、消极等情感类别。条件概率 P ( x i ∣ C ) P(x_i|C) P(xi∣C) 一般使用最大似然估计来计算,公式为:
P ( x i ∣ C ) = 文本类别为 C 时单词 x i 出现的次数 文本类别为 C 时所有单词出现的总次数 P(x_i|C)=\frac{文本类别为 C 时单词 x_i 出现的次数}{文本类别为 C 时所有单词出现的总次数} P(xi∣C)=文本类别为C时所有单词出现的总次数文本类别为C时单词xi出现的次数
零概率问题当训练数据有限时,可能会出现某个单词在某个类别中从未出现过的情况。若按照上述公式计算,此时 P ( x i ∣ C ) = 0 P(x_i|C) = 0 P(xi∣C)=0。在计算后验概率 P ( C ∣ x ) P(C|x) P(C∣x) 时,由于后验概率是多个条件概率的乘积,一旦有一个条件概率为 0,整个后验概率就会变为 0,这会严重影响分类的准确性,因为它会忽略掉其他有价值的特征信息。拉普拉斯平滑为了解决零概率问题,引入了拉普拉斯平滑。其基本思想是在分子上加 1,在分母上加一个与特征数量相关的值,通常是特征的种类数。在文本分类中,特征就是单词,所以分母加上单词的种类数。具体公式如下:
P ( x i ∣ C ) = 文本类别为 C 时单词 x i 出现的次数 + 1 文本类别为 C 时所有单词出现的总次数 + 单词的种类数 P(x_i|C)=\frac{文本类别为 C 时单词 x_i 出现的次数 + 1}{文本类别为 C 时所有单词出现的总次数 + 单词的种类数} P(xi∣C)=文本类别为C时所有单词出现的总次数+单词的种类数文本类别为C时单词xi出现的次数+1
在代码里,sum(positive_word_count.values()) 表示文本类别为积极时所有单词出现的总次数,len(positive_word_count) 表示积极类别中文本出现的单词的种类数。这样,即使某个单词在积极类别中从未出现过,其条件概率也不会为 0,而是一个较小的非零值,从而避免了零概率问题,使分类器更加健壮。
示例说明
假设在积极类别中,总共有 100 个单词出现,其中单词 “开心” 出现了 5 次,单词 “愉快” 从未出现过。若不使用拉普拉斯平滑, P ( 开心 ∣ 积极 ) = 5 100 = 0.05 P(开心|积极)=\frac{5}{100}=0.05 P(开心∣积极)=1005=0.05, P ( 愉快 ∣ 积极 ) = 0 100 = 0 P(愉快|积极)=\frac{0}{100}=0 P(愉快∣积极)=1000=0。使用拉普拉斯平滑后,假设积极类别中不同单词的种类数是 20,那么 P ( 开心 ∣ 积极 ) = 5 + 1 100 + 20 = 0.05 P(开心|积极)=\frac{5 + 1}{100 + 20}=0.05 P(开心∣积极)=100+205+1=0.05, P ( 愉快 ∣ 积极 ) = 0 + 1 100 + 20 ≈ 0.0083 P(愉快|积极)=\frac{0 + 1}{100 + 20}\approx0.0083 P(愉快∣积极)=100+200+1≈0.0083,“愉快” 的条件概率不再是 0。