目录
一.朴素贝叶斯的基本原理
1.1概述
1.基本原理:
朴素贝叶斯分类器基于贝叶斯定理,利用已知的数据来进行分类预测。
贝叶斯定理描述了在给定先验概率的情况下,如何根据新的证据来更新我们对某个事件发生概率的信念。
2.朴素假设:
朴素贝叶斯算法中最重要的假设是特征之间相互独立,即给定类别的情况下,特征之间是条件独立的。
尽管这个假设在实际中很少成立,但在许多情况下,朴素贝叶斯仍然表现出良好的性能。
3.分类决策:
给定一个待分类的样本,朴素贝叶斯计算每个可能类别的后验概率。
最终选择具有最高后验概率的类别作为预测结果。
4.分类器类型:
朴素贝叶斯算法有几种变种,最常见的包括:
多项式朴素贝叶斯(Multinomial Naive Bayes):适用于文本分类等离散特征的任务。
伯努利朴素贝叶斯(Bernoulli Naive Bayes):适用于二值特征的任务,如垃圾邮件过滤。
高斯朴素贝叶斯(Gaussian Naive Bayes):适用于连续特征的任务,假设特征的分布服从正态分布。
1.2贝叶斯定理
贝叶斯定理是关于随机事件A和B的条件概率和边缘概率的。
先验概率:即基于统计的概率,是基于以往历史经验和分析得到的结果,不需要依赖当前发生的条件。
后验概率:则是从条件概率而来,由因推果,是基于当下发生了事件之后计算的概率,依赖于当前发生的条件。
贝叶斯公式为:
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朴素贝特斯算法原理
朴素贝叶斯是以贝叶斯定理为基础并且假设特征条件之间相互独立的方法。在给定的训练数据集上,朴素贝叶斯学习每个特征与每个类别的概率关系,然后使用贝叶斯定理来预测新实例的类别。
特征条件假设:假设每个特征之间没有联系,给定训练数据集,其中每个样本x都包括n维特征,即x=(x1,x2,x3,...,xn);类标记集合含有k种类别,即y=(y1,y2,...,yk)。
对于给定的新样本x,判断其属于哪个标记的类别,根据贝叶斯定理,可以得到x属于类别𝑦𝑘的概率𝑃(𝑦𝑘|𝑥):P(yk|x)=P(yk)⋅P(x|yk)/∑kP(x|yk)⋅P(yk)
后验概率最大的类别记为预测类别,即:arg𝑚𝑎𝑥𝑃(𝑦𝑘|𝑥)。
朴素贝叶斯算法对条件概率分布作出了独立性的假设,通俗地讲就是说假设各个维度的特征互相独立,在这个假设的前提上,条件概率可以转化为:
代入上面贝叶斯公式中,得到:
于是,朴素贝叶斯分类器可表示为:
因为对所有的,上式中的分母的值都是一样的,所以可以忽略分母部分,朴素贝叶斯分类器最终表示为:
二.朴素贝叶斯算法实战
如下图所示,通过色泽、根蒂、敲声的不同可以判断一个西瓜是否是好瓜
编号 | 色泽 | 根蒂 | 敲声 | 好瓜 |
---|---|---|---|---|
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.1数据集的引入
- 色泽:0表示青绿,1表示乌黑,2表示浅白。
- 根蒂:0表示蜷缩,1表示稍蜷,2表示硬挺。
- 敲声:0表示浊响,1表示沉闷。
首先直接把上面给的例子作为数据输入到data当中作为数据集
data = [[0, 0, 0, 0],
[1, 0, 1, 0],
[1, 0, 0, 0],
[0, 0, 1, 0],
[2, 0, 0, 0],
[0, 1, 0, 1],
[1, 1, 0, 1],
[1, 1, 0, 0],
[1, 1, 1, 0],
[0, 2, 2, 1],
[2, 2, 2, 0],
[2, 0, 0, 1],
[0, 1, 0, 0],
[2, 1, 1, 0],
[1, 1, 0, 1],
]
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))
输出结果为:
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
给定要测试的特征,通过朴素贝叶斯分类器计算,输出判断结果
# 测试数据
test_instance = ['乌黑', '硬挺', '浊响']
# 进行分类预测
predicted_class = nb_classifier.predict(test_instance)
print("\n特征{},预测结果: {}" .format(test_instance, predicted_class))
输出结果为:
三、总结
3.1 优点
1.简单高效:朴素贝叶斯算法具有简单的数学原理和易于实现的算法,计算效率高,尤其适用于大规模数据集。
2.适用性广泛:朴素贝叶斯分类器适用于各种类型的数据,包括文本分类、图像分类和数值数据等,因此在自然语言处理、垃圾邮件过滤等领域得到了广泛应用。
3.处理多类别问题:朴素贝叶斯分类器可以处理多类别分类问题,而且在类别之间的边界不清晰时表现良好。
4.对小规模数据表现良好:即使在数据量较小的情况下,朴素贝叶斯分类器也能表现良好,因为它不需要大量的训练数据来估计参数。
5.处理高维数据:朴素贝叶斯分类器在高维数据集上表现良好,因为它假设特征之间相互独立,可以处理大量特征的数据。
3.2 缺点
1.假设特征独立:朴素贝叶斯分类器假设特征之间相互独立,这在某些情况下可能不符合实际情况,导致分类性能下降。
2.处理不良数据影响较大:朴素贝叶斯分类器对于不良数据(例如缺失值)敏感,不良数据可能会导致模型性能下降。
3.需要平衡数据集:朴素贝叶斯分类器对数据集的类别分布敏感,如果类别之间的样本数量不平衡,可能会导致模型偏向于出现频率较高的类别。
4.不能解决特征之间的关联性:朴素贝叶斯分类器假设特征之间相互独立,因此不能捕捉特征之间的相关性,这在某些情况下可能导致分类性能下降。
5.对文本分类中的语义理解较弱:在文本分类等需要理解语义信息的任务中,朴素贝叶斯分类器可能表现不佳,因为它主要基于词频统计,而忽略了词之间的语义关系。
尽管朴素贝叶斯分类器有一些局限性,但它仍然是一个简单而强大的分类算法,特别适用于处理大规模的高维数据集和文本分类等任务。