目录
一、朴素贝叶斯简介
朴素贝叶斯(Naive Bayes)是一种基于贝叶斯定理的简单而强大的机器学习分类算法。它是基于概率和统计的方法,通常用于处理分类问题,特别是在文本分类和垃圾邮件过滤等领域表现良好。
1.1、工作原理
- 建立模型: 通过使用训练数据集,计算每个特征值对于每个类别的条件概率。
- 预测: 对于给定的新数据,使用贝叶斯定理计算每个类别的后验概率,并选择具有最高后验概率的类别作为预测结果。
1.2、先验概率
先验概率指的是在没有任何观测数据的情况下,我们对每个类别发生的概率的初始估计。在分类问题中,先验概率通常表示为 ( P(Y) ),其中 ( Y ) 表示类别标签。
1.3、条件概率
条件概率是指在已知某一事件发生的条件下,另一事件发生的概率。
条件概率公式: 这表示在B事件发生的条件下事件发生的概率
1.4、后验概率
后验概率是在考虑了某些先验信息或证据后,通过贝叶斯定理计算得到的更新后的概率。它表示在已知某些信息后,对某一事件的概率估计。在贝叶斯统计学中,后验概率通常表示为 ( P(A|B) )
公式:
二、实例
2.1、数据
# 数据
T = ['天气', '温度', '湿度', '风']
X = [
['晴', '炎热', '高', '弱'],
['晴', '炎热', '高', '强'],
['阴', '炎热', '高', '弱'],
['雨', '温和', '高', '弱'],
['雨', '凉爽', '正常', '弱'],
['雨', '凉爽', '正常', '强'],
['阴', '凉爽', '正常', '强'],
['晴', '温和', '高', '弱'],
['晴', '凉爽', '正常', '弱'],
['雨', '温和', '正常', '弱'],
['雨', '温和', '正常', '强'],
['阴', '温和', '高', '强'],
['阴', '炎热', '正常', '弱'],
['雨', '温和', '高', '强']
]
y = ['否', '否', '是', '是', '是', '否', '是', '否', '是', '是', '是', '是', '是', '否']
2.2、计算先验概率
先验概率在代码中是通过创建一个字典然后遍历给出的数据集,记录每个特征出现的频率,然后将样本总个数作为分母来计算先验概率。
# 创建 DataFrame
df = pd.DataFrame(X, columns=T)
df['label'] = y
# 计算每个特征的先验概率
prior_probabilities = {}
total_samples = len(df)
for feature in T:
feature_counts = df[feature].value_counts()
feature_probabilities = feature_counts / total_samples
prior_probabilities[feature] = feature_probabilities
# 显示每个特征的先验概率
for feature, probabilities in prior_probabilities.items():
print("特征:", feature)
print(probabilities)
print()
2.3、计算条件概率
首先,创建一个空字典,用于存储条件概率。然后,遍历特征集合T
中的每个特征。对于每个特征,获取该特征在数据集中的唯一值列表。接下来,遍历每个唯一值和目标值['是', '否']
的组合。计算满足特定特征值和目标值的样本数量,通过使用布尔索引筛选出符合条件的行并计算长度。计算目标值为特定值的样本总数,同样使用布尔索引筛选出符合条件的行并计算长度。计算条件概率,将计数除以总数得到概率值,并将结果存储在字典中,键为特征值、特征名称和目标值的元组。最后,遍历字典中的每个键值对,打印特征名称、特征值、目标值和对应的条件概率
# 计算条件概率
conditional_probabilities = {}
for feature in T:
unique_values = df[feature].unique()
for value in unique_values:
for target_value in ['是', '否']:
count = len(df[(df[feature] == value) & (df['label'] == target_value)])
total_count = len(df[df['label'] == target_value])
conditional_probabilities[(value, feature, target_value)] = count / total_count
# 显示条件概率
for key, probability in conditional_probabilities.items():
value, feature, target_value = key
print("特征:", feature, ", 值:", value, ", 目标变量为", target_value, ", 条件概率:", probability)
2.4、计算后验概率并显示测试集结果
首先,创建一个空列表,用于存储预测的标签。然后,遍历测试数据集中的每个样本。对于每个样本,初始化最大后验概率为-1,预测标签为None。接下来,遍历目标值['是', '否']
,计算每个目标值对应的后验概率。初始化后验概率为1。使用zip
函数将特征和样本值组合在一起,遍历每个特征和值的组合。根据条件概率计算后验概率,通过查找字典获取对应的概率值,如果不存在则返回0。将后验概率乘以先验概率,这里假设先验概率存储在字典中。遍历剩余的特征和值的组合,重复步骤7和8。如果计算出的后验概率大于当前的最大后验概率,更新最大后验概率和预测标签。将预测标签添加到列表中。最后,返回预测的标签列表。
# 输入测试集样本数量
num_samples = int(input("请输入测试集样本数量: "))
# 输入测试集
print('请依次输入测试集中每个样本的特征值:')
test_data = []
features = df.columns[:-1] # 特征名称列表
for _ in range(num_samples):
sample = []
for feature in features:
test = input(f"请输入 {feature} 的值: ")
sample.append(test)
test_data.append(sample)
predictions = []
for sample in test_data:
max_posterior_prob = -1
predicted_label = None
for target_value in ['是', '否']:
posterior_prob = 1 # 初始化后验概率为1
for feature, value in zip(features, sample):
# 根据条件概率计算后验概率
posterior_prob *= conditional_probabilities.get((value, feature, target_value), 0)
# 乘以先验概率
posterior_prob *= prior_probabilities[features[0]][sample[0]]
for i in range(1, len(features)):
posterior_prob *= prior_probabilities[features[i]][sample[i]]
# 更新最大后验概率和预测标签
if posterior_prob > max_posterior_prob:
max_posterior_prob = posterior_prob
predicted_label = target_value
predictions.append(predicted_label)
# 输出预测结果
for i, pred in enumerate(predictions):
print(f"样本{i+1}:{test_data[i]} 结果:{pred}")
三、实验小结
优点:
- 简单且效果稳定: 贝叶斯方法具有简单、直观的数学原理,易于理解和实现。在训练样本少或噪声较多的情况下,贝叶斯方法通常能够产生较为稳定的分类结果。
- 对小样本数据有良好的适应性: 贝叶斯方法可以通过引入先验概率,较好地处理小样本数据,降低过拟合的风险。
- 处理多类别分类问题: 贝叶斯方法天然支持多类别分类问题,不需要额外的处理。
- 能够处理缺失数据: 贝叶斯方法能够利用先验信息填充缺失的数据,提高模型的鲁棒性。
缺点:
- 对输入特征的独立性要求高: 贝叶斯方法通常假设输入特征之间相互独立,但在实际问题中,这种假设往往难以满足,导致模型性能下降。
- 需要对先验概率进行假设: 贝叶斯方法需要对先验概率进行合理的假设,这些假设的选择可能会影响最终的分类结果。
- 计算复杂度高: 贝叶斯方法在计算后验概率时需要对所有可能的情况进行求解,因此在特征空间较大或者类别较多时,计算复杂度会变得很高。
- 不适用于非线性问题: 贝叶斯方法通常假设类别的分布是高斯分布等简单形式,对于复杂的非线性问题,贝叶斯方法可能表现不佳。