目录
一、贝叶斯分类
(一)、贝叶斯公式
由于各个特征相互独立,故简化后可得
(二)、贝叶斯分类基本思路
贝叶斯分类是一种基于贝叶斯定理的统计分类方法。其基本思路可以概括为以下几个步骤:
1.建立模型:首先,需要建立一个分类模型,该模型描述了特征与类别之间的关系。通常,这个模型会基于训练数据集来学习,学习的过程就是确定特征对于每个类别的条件概率分布。
2.计算先验概率:在贝叶斯分类中,先验概率指的是在没有任何其他信息的情况下,某个样本属于每个类别的概率。计算先验概率通常是通过训练数据集中每个类别的样本数量来估计得到的。
3.计算条件概率:条件概率指的是在给定特征条件下,样本属于某个类别的概率。对于每个类别,需要计算每个特征值对应的条件概率。这一步需要利用训练数据集中每个特征值在不同类别下的出现频率来计算。
4.应用贝叶斯定理:在得到先验概率和条件概率之后,就可以利用贝叶斯定理来计算后验概率,即给定特征条件下,样本属于每个类别的概率。根据后验概率,可以选择具有最大后验概率的类别作为样本的预测类别。
5.预测:对于新的未知样本,利用已经建立好的模型,计算其在每个类别下的后验概率,然后选择具有最大后验概率的类别作为预测结果。
二、实验内容
本次实验内容为根据样本的性别、年龄、职业、收入四个特征,判断该样本人物是否能买得起房
(一)、其训练集如下:
(二)、所需判断的测试集如下:
三、实验步骤
(一)、定义实验训练集
ybnum所存储的是每个类别的样本数量,tznum所存储的是每个预测类别的样本所对应的特征的数量,classes所存储的则是预测样本的类别,即‘是’或‘否’
# 存储每个类别的样本数量
ybnum = defaultdict(int)
# 存储每个预测类别的样本对应的特征的数量
tznum = defaultdict(lambda: defaultdict(int))
# 存储预测类别
classes = set()
(二)、训练集样本的获取与与处理
x和y分别表示训练集样本的特征和训练集样本的分类结果。该函数作用是将训练集中的每个类别的样本数量用ybnum进行统计,每个预测类别的样本对应的特征数量用tznum进行统计,最后将ybnum中所存储的内容修改为该结果的先验概率
def getnum(X, y):
# 统计训练集中各个类别的样本数量以及特征值的数量
num = len(y) # 获取样本总数
for i in range(num):
features = X[i] # 获取当前样本的特征值列表
label = y[i] # 获取当前样本的类别标签
classes.add(label) # 将类别标签加入到类别集合中
ybnum[label] += 1 # 统计当前类别的样本数量
for j in features:
tznum[label][j] += 1 # 统计当前类别下每个特征值的数量
# 计算每个类别的样本占比
for label in classes:
ybnum[label] /= num
得到先验概率结果如下:
(三)、预测测试集
主要思路为利用贝叶斯公式,通过其鲜艳概率计算其后验概率,每次计算时更行其最大后验概率,最后选取最大的后验概率作为实验结果
def predict(X):
predictions = []
# 对测试集中的每个样本进行预测
for features in X:
maxp = -1 # 最大概率初始化为负数
ans = None # 最终预测结果初始化为空
# 遍历每个类别,计算其概率并找出最大概率对应的类别
for label in classes:
p = ybnum[label] # 初始化概率为该类别的先验概率
for j in features:
# 计算条件概率,乘以各特征值的条件概率
p *= tznum[label][j] / sum(tznum[label].values())
if p > maxp: # 若当前概率大于最大概率,则更新最大概率及预测结果
maxp = p
ans = label
predictions.append(ans) # 将预测结果添加到预测列表中
return predictions
得到两个测试样本的是否买得起房的后验概率如下:
(四)、总体代码以及实验结果
from collections import defaultdict
# 存储每个类别的样本数量
ybnum = defaultdict(int)
# 存储每个预测类别的样本对应的特征的数量
tznum = defaultdict(lambda: defaultdict(int))
# 存储预测类别
classes = set()
def getnum(X, y):
# 统计训练集中各个类别的样本数量以及特征值的数量
num = len(y) # 获取样本总数
for i in range(num):
features = X[i] # 获取当前样本的特征值列表
label = y[i] # 获取当前样本的类别标签
classes.add(label) # 将类别标签加入到类别集合中
ybnum[label] += 1 # 统计当前类别的样本数量
for j in features:
tznum[label][j] += 1 # 统计当前类别下每个特征值的数量
# 计算每个类别的样本占比
#for label in classes:
# ybnum[label] /= num
# print(ybnum[label])
def predict(X):
predictions = []
# 对测试集中的每个样本进行预测
for features in X:
maxp = -1 # 最大概率初始化为负数
ans = None # 最终预测结果初始化为空
# 遍历每个类别,计算其概率并找出最大概率对应的类别
for label in classes:
p = ybnum[label] # 初始化概率为该类别的先验概率
for j in features:
# 计算条件概率,乘以各特征值的条件概率
p *= tznum[label][j] / sum(tznum[label].values())
if p > maxp: # 若当前概率大于最大概率,则更新最大概率及预测结果
maxp = p
ans = label
predictions.append(ans) # 将预测结果添加到预测列表中
return predictions
# 特征名称列表
T = ['性别', '年龄', '职业', '收入水平']
# 训练集数据
X = [
['男','中年','工人','低'],
['女','青年','学生','低'],
['男','老年','教师','中'],
['女','中年','医生','高'],
['女','青年','工人','高'],
['男','青年','学生','低']
]
# 训练集标签
Y = ['否', '否', '是', '是', '否', '否']
# 统计类别和对应特征值的数量
getnum(X, Y)
# 测试集数据
test_data = [
['女','老年','教师','高'],
['男','中年','工人','低']
]
# 对测试集进行预测
predictions = predict(test_data)
# 输出预测结果
for i in range(len(predictions)):
print(f"测试样本{i+1}:", test_data[i], "预测其是否买得起房:", predictions[i])
实验结果:
四、实验总结
(一)、实验中遇到的问题
实验时,通过该方法进行分类时,不是每次都能得到理想的结果,与理想中的结果存在一定误差,需要通过不断完善训练集来提高分类准确性。
其次,使用该分类器时注意各个特征需相互独立,否则难以得到准确结果
(二)、实验小结
贝叶斯分类优缺点分析
优点:
1.简单有效: 贝叶斯分类方法简单易懂,易于实现,特别适用于小规模数据集的分类问题。
2.对小样本数据效果好: 在样本量较小的情况下,贝叶斯分类器仍然能够表现出良好的分类性能,因为它不需要大量的样本来进行训练。
3.处理多分类问题: 贝叶斯分类器天然支持多分类任务,不需要额外的修改或者复杂的处理。
缺点:
1.假设特征条件独立性: 贝叶斯分类器假设各个特征之间相互独立,这在实际数据中往往是不成立的,可能会导致分类性能下降。
2.需要大量内存: 贝叶斯分类器需要存储各个类别下每个特征值的条件概率,如果特征空间较大,可能会占用大量内存。
3.对输入数据的分布假设较强: 贝叶斯分类器对输入数据的分布有一定的假设,例如高斯朴素贝叶斯假设特征值服从高斯分布,如果数据的实际分布与假设不符,可能导致分类性能下降。
综上所述,贝叶斯分类器在简单、有效、处理小样本数据等方面具有优势,但在对特征独立性的假设、内存消耗、对输入数据分布的假设等方面存