目录
1.朴素贝叶斯的基本原理
1.1概述
-
基本原理:
- 朴素贝叶斯分类器基于贝叶斯定理,利用已知的数据来进行分类预测。
- 贝叶斯定理描述了在给定先验概率的情况下,如何根据新的证据来更新我们对某个事件发生概率的信念。
-
朴素假设:
- 朴素贝叶斯算法中最重要的假设是特征之间相互独立,即给定类别的情况下,特征之间是条件独立的。
- 尽管这个假设在实际中很少成立,但在许多情况下,朴素贝叶斯仍然表现出良好的性能。
-
分类决策:
- 给定一个待分类的样本,朴素贝叶斯计算每个可能类别的后验概率。
- 最终选择具有最高后验概率的类别作为预测结果。
-
分类器类型:
- 朴素贝叶斯算法有几种变种,最常见的包括:
- 多项式朴素贝叶斯(Multinomial Naive Bayes):适用于文本分类等离散特征的任务。
- 伯努利朴素贝叶斯(Bernoulli Naive Bayes):适用于二值特征的任务,如垃圾邮件过滤。
- 高斯朴素贝叶斯(Gaussian Naive Bayes):适用于连续特征的任务,假设特征的分布服从正态分布。
- 朴素贝叶斯算法有几种变种,最常见的包括:
1.2贝叶斯定理
先验概率:即基于统计的概率,是基于以往历史经验和分析得到的结果,不需要依赖当前发生的条件。
后验概率:则是从条件概率而来,由因推果,是基于当下发生了事件之后计算的概率,依赖于当前发生的条件。
贝叶斯公式为:
P(A)是A的先验概率,P(B)是B的先验概率。即发生A事件的概率和发生B事件的概率
P(A|B)是已知B发生后A的条件概率,被称作A的后验概率,即在已经发生B事件的情况下,发生A事件的概率
P(B|A)是已知A发生后B的条件概率,被称作B的后验概率,即在已经发生A事件的情况下,发生B事件的概率
1.3朴素贝叶斯算法原理
由于朴素贝叶斯分类器的“朴素”之处在于它假设特征之间相互独立,这使得条件概率 可以表示为特征之间的乘积即:
所以最后朴素贝叶斯算法的公式为:
根据这个公式,我们可以计算每个类别的后验概率,并选择具有最高后验概率的类别作为最终的预测结果。
1.4例子
如下图所示,通过色泽、根蒂、敲声的不同可以判断一个西瓜是否是好瓜
编号 | 色泽 | 根蒂 | 敲声 | 好瓜 |
---|---|---|---|---|
1 | 青绿 | 蜷缩 | 浊响 | 是 |
2 | 乌黑 | 蜷缩 | 沉闷 | 是 |
3 | 乌黑 | 蜷缩 | 浊响 | 是 |
4 | 青绿 | 蜷缩 | 沉闷 | 是 |
5 | 浅白 | 蜷缩 | 浊响 | 是 |
6 | 青绿 | 稍蜷 | 浊响 | 是 |
7 | 乌黑 | 稍蜷 | 浊响 | 是 |
8 | 乌黑 | 稍蜷 | 沉闷 | 是 |
9 | 乌黑 | 硬挺 | 浊响 | 否 |
10 | 青绿 | 硬挺 | 清脆 | 否 |
11 | 浅白 | 硬挺 | 清脆 | 否 |
12 | 浅白 | 蜷缩 | 浊响 | 否 |
13 | 青绿 | 稍蜷 | 浊响 | 否 |
14 | 浅白 | 稍蜷 | 沉闷 | 否 |
15 | 乌黑 | 稍蜷 | 浊响 | 否 |
如果判断色泽=青绿,根蒂=硬挺,敲声=浊响的西瓜是不是好瓜
首先计算先验概率 P(好瓜) = 8/15 P(坏瓜) =7/15
然后计算每个特征值在每个类别下的后验概率
P(色泽=青绿 | 好瓜) =3/8 P(色泽=青绿 | 坏瓜) =2/7
P(根蒂=硬挺 | 好瓜) =0/8 P(根蒂=硬挺 | 坏瓜) =3/7
P(敲声=浊响 | 好瓜) =5/8 P(敲声=浊响 | 坏瓜) =4/7
然后通过下面公式计算后验概率,选择后验概率最大的类别作为最后预测的结果
P(好瓜 | 色泽=青绿,根蒂=硬挺,敲声=浊响)=P(好瓜)* P(色泽=青绿 | 好瓜)*P(根蒂=硬挺 | 好瓜)*P(敲声=浊响 | 好瓜)=0
P(坏瓜 | 色泽=青绿,根蒂=硬挺,敲声=浊响)=P(坏瓜)* P(色泽=青绿 | 坏瓜)*P(根蒂=硬挺 | 坏瓜)*P(敲声=浊响 | 坏瓜)=168/5145
所以色泽=青绿,根蒂=硬挺,敲声=浊响的西瓜是坏瓜
2.朴素贝叶斯算法实战
2.1数据集的引入
首先直接把上面给的例子作为数据输入到data当中作为数据集
data = [
['青绿', '蜷缩', '浊响', '是'],
['乌黑', '蜷缩', '沉闷', '是'],
['乌黑', '蜷缩', '浊响', '是'],
['青绿', '蜷缩', '沉闷', '是'],
['浅白', '蜷缩', '浊响', '是'],
['青绿', '稍蜷', '浊响', '是'],
['乌黑', '稍蜷', '浊响', '是'],
['乌黑', '稍蜷', '沉闷', '是'],
['乌黑', '硬挺', '浊响', '否'],
['青绿', '硬挺', '清脆', '否'],
['浅白', '硬挺', '清脆', '否'],
['浅白', '蜷缩', '浊响', '否'],
['青绿', '稍蜷', '浊响', '否'],
['浅白', '稍蜷', '沉闷', '否'],
['乌黑', '稍蜷', '浊响', '否'],
]
2.2后验概率的计算
通过计算得出好瓜和坏瓜在全部瓜中的占比
good_count = sum(1 for instance in data if instance[-1] == '是')
bad_count = len(data) - good_count
# 计算好瓜和坏瓜的占比
good_percentage = good_count / len(data)
bad_percentage = bad_count / len(data)
# 输出结果
print("好瓜的占比: {:.4f}".format(good_percentage))
print("坏瓜的占比: {:.4f}".format(bad_percentage))
输出结果为:
通过下述的代码可以用于计算在好瓜和坏瓜为前提下,每个特征的后验概率
def train(self, data):
# 计算先验概率和条件概率
for instance in data:
# 提取特征和类别
features = instance[:-1]
label = instance[-1]
# 更新类别集合
self.classes.add(label)
# 更新先验概率
self.prior[label] += 1
# 更新条件概率
for i, feature in enumerate(features):
self.conditional_prob[label][(i, feature)] += 1
# 计算先验概率和条件概率的比例
total_samples = sum(self.prior.values())
for label in self.classes:
self.prior[label] /= total_samples
for feature, count in self.conditional_prob[label].items():
self.conditional_prob[label][feature] /= self.prior[label] * total_samples
def get_feature_probs(self, label):
return self.conditional_prob[label]
然后用下述代码对每个的后验概率进行一个输出
# 输出每个类别下每个特征的概率
for label in nb_classifier.classes:
feature_probs = nb_classifier.get_feature_probs(label)
print("\n在\"{}\"类别下每个特征的概率:".format(label))
for feature, prob in feature_probs.items():
print("特征 {} 的概率: {:.4f}".format(feature, prob))
输出结果为:
如果有的特征未输出,说明在这个类别的前提下,这个特征的概率为0
2.3给定特征判断预测结果
先通过上述计算后验概率的代码创建一个朴素贝叶斯分类器
class NaiveBayesClassifier:
def __init__(self):
self.prior = defaultdict(int)
self.conditional_prob = defaultdict(lambda: defaultdict(int))
self.classes = set()
def train(self, data):
# 计算先验概率和条件概率
for instance in data:
# 提取特征和类别
features = instance[:-1]
label = instance[-1]
# 更新类别集合
self.classes.add(label)
# 更新先验概率
self.prior[label] += 1
# 更新条件概率
for i, feature in enumerate(features):
self.conditional_prob[label][(i, feature)] += 1
# 计算先验概率和条件概率的比例
total_samples = sum(self.prior.values())
for label in self.classes:
self.prior[label] /= total_samples
for feature, count in self.conditional_prob[label].items():
self.conditional_prob[label][feature] /= self.prior[label] * total_samples
def get_feature_probs(self, label):
return self.conditional_prob[label]
def predict(self, instance):
max_prob = float('-inf')
best_label = None
# 遍历每个类别,找到具有最大后验概率的类别
for label in self.classes:
# 计算后验概率
prob = self.prior[label]
for i, feature in enumerate(instance):
prob *= self.conditional_prob[label][(i, feature)]
# 更新最大概率和对应的类别
if prob > max_prob:
max_prob = prob
best_label = label
return best_label
nb_classifier = NaiveBayesClassifier()
nb_classifier.train(data)
给定要测试的特征,通过朴素贝叶斯分类器计算,输出判断结果
# 测试数据
test_instance = ['青绿', '硬挺', '浊响']
# 进行分类预测
predicted_class = nb_classifier.predict(test_instance)
print("\n特征{},预测结果: {}" .format(test_instance, predicted_class))
输出结果为:
3.总结
朴素贝叶斯分类器是一种简单而有效的分类算法,具有以下优点和缺点:
优点:
简单高效:朴素贝叶斯分类器的原理简单,易于实现和理解。在处理小规模数据集时,具有高效的性能。
适用性广泛:朴素贝叶斯分类器在处理文本分类、垃圾邮件过滤、情感分析等领域有着广泛的应用,并且在一些实际问题中表现出色。
对小规模数据表现良好:即使在数据量较小的情况下,朴素贝叶斯分类器仍然能够产生合理的结果,不容易出现过拟合问题。
缺点:
朴素假设:朴素贝叶斯分类器假设所有特征都是相互独立的,这在实际情况中往往是不成立的,因此可能会导致分类性能下降。
处理连续特征不佳:朴素贝叶斯分类器对连续型特征的处理较为困难,通常需要对连续特征进行离散化处理。
类别偏差问题:如果训练数据中某个类别的样本数量远远大于其他类别,那么朴素贝叶斯分类器可能会出现类别偏差,导致分类结果不准确。
需要平滑处理:在处理稀疏数据时,朴素贝叶斯分类器容易出现概率为零的情况,因此需要进行平滑处理来避免这种情况。