题目 基于朴素贝叶斯模式识别系统的设计与实现
1.1 题目的主要研究内容
(1)本系统利用朴素贝叶斯贝叶斯分类器对鸢尾花进行分类。数据集由训练集和测试集组成,通过对数据进行特征提取与特征选择,对鸢尾花类型做出一个分类结果。朴素贝叶斯算法结合先验概率与后验概率,避免了先验概率的主观性和单独使用样本信息的过拟合现象,并且保持目标值属性之间相互条件独立。朴素贝叶斯简化了贝叶斯算法,具有较好的分类效果,同时在实际场景中大大降低了算法复杂性。
(2)系统流程图
1.2 题目研究的工作基础或实验条件
(1)硬件环境
CPU: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.71 GHz
机带RAM:8GB
显卡:NVIDIA GeForce MX150
(2)软件环境
开发语言:Python
1.3 数据集描述
本系统所用的数据集为鸢尾花数据集。其中包含3类分别为山鸢尾(Iris-setosa)、变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica),共 150 条记录,每类各 50 个数据,每条记录都有 4 项特征:花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)。鸢尾花数据形式:
5.3,3.7,1.5,0.2,Iris-setosa
6.5,3.0,5.2,2.0,Iris-virginica
5.0,3.3,1.4,0.2,Iris-setosa
1.4 特征提取过程描述
鸢尾花数据集中有4个特征,分别为鸢尾花的花萼长度、花萼宽度、花瓣长度、 花瓣宽度。在训练数据集上,我们首先计算不同种类的各个特征的和,然后计算样本在各个属性上取值的均值,最后在计算各类样本在每个属性上的方差。通过特征提取过程中得到的均值和方差,我们能够计算出鸢尾花的每个种类上的各个特征属性的条件概率和后验概率。
1.5 分类过程描述
1.首先估计类先验概率,这里每个类别所占比例相同。
2.根据在特征提取部分中得到的均值和方差设置概率密度函数计算测试数据集上各个属性在每个类上的条件概率。
3.根据前两步计算的先验概率和条件概率,计算后验概率。即:后验概率=先验概率*条件概率
4.计算每个种类上的后验概率
5.比较每个种类上的后验概率,后验概率最大的类别为分类结果。
1.6 主要程序代码(要求必须有注释)
1.数据集的读取:
#读取训练数据集,这里将每种花取前45条数据,剩下的5条数据另外存入测试数据集
def read_train_data(filename):
f=open(filename,'r')
all_lines=f.readlines()
for line in all_lines[0:45]:
line=line.strip().split(',')
Iris_setosa_data.append(line[0:4])
#Iris_setosa_label+=1
for line in all_lines[51:95]:
line=line.strip().split(',')
Iris_versicolor_data.append(line[0:4])
#Iris_versicolor_label+=1
for line in all_lines[101:145]:
line=line.strip().split(',')
Iris_virginica_data.append(line[0:4])
#Iris_virginica_label+=1
return Iris_setosa_data,Iris_versicolor_data,Iris_virginica_data
test_data=[]
#读取测试数据集
def read_test_data(testname):
f=open(testname,'r')
all_lines=f.readlines()
for line in all_lines[0:]:
line=line.strip().split(',') # 以逗号为分割符拆分列表
test_data.append(line)
return test_data
2.计算均值和方差:
def calculate_junzhi_and_fangcha(train_data):
x1_sum=0.0
x2_sum=0.0
x3_sum=0.0
x4_sum=0.0
for x in train_data: #计算各个特征的和
x1_sum+=float(x[0])
x2_sum+=float(x[1])
x3_sum+=float(x[2])
x4_sum+=float(x[3])
#print(x[0],x[1],x[2],x[3])
# print(x1_sum)
# print(x2_sum)
# print(x3_sum)
# print(x4_sum)
#计算样本在各个属性上取值的均值
u_x1=x1_sum/45
u_x2=x2_sum/45
u_x3=x3_sum/45
u_x4=x4_sum/45
k1=0.0
k2=0.0
k3=0.0
k4=0.0
#计算各类样本在第i个属性上的方差
for x in train_data:
k1+=(float(x[0])-u_x1)**2
k2+=(float(x[1])-u_x2)**2
k3+=(float(x[2])-u_x3)**2
k4+=(float(x[3])-u_x4)**2
variance_x1=k1/45
variance_x2=k2/45
variance_x3=k3/45
variance_x4=k4/45
return u_x1,u_x2,u_x3,u_x4,variance_x1,variance_x2,variance_x3,variance_x4
计算每个属性估计条件概率:
def calculate_P_xi_c(u_x1,u_x2,u_x3,u_x4,variance_x1,variance_x2,variance_x3,variance_x4,line_data):
p_x1_c=(1/math.sqrt(2*math.pi))*math.exp(-(float(line_data[0])-u_x1)**2/(2*variance_x1))
p_x2_c=(1/math.sqrt(2*math.pi))*math.exp(-(float(line_data[1])-u_x2)**2/(2*variance_x2))
p_x3_c=(1/math.sqrt(2*math.pi))*math.exp(-(float(line_data[2])-u_x3)**2/(2*variance_x3))
p_x4_c=(1/math.sqrt(2*math.pi))*math.exp(-(float(line_data[3])-u_x4)**2/(2*variance_x4))
return p_x1_c,p_x2_c,p_x3_c,p_x4_c
分类:
if __name__ == '__main__':
filename = 'iris_data.txt' # 训练集
testname = 'iris_test_data.txt' # 测试集
Iris_setosa_data,Iris_versicolor_data,Iris_virginica_data = read_train_data(filename)
#Iris_setosa种类的各个特征属性上的均值和方差
Iris_setosa_u_x1,Iris_setosa_u_x2,Iris_setosa_u_x3,Iris_setosa_u_x4,\
Iris_setosa_variance_x1,Iris_setosa_variance_x2,Iris_setosa_variance_x3,\
Iris_setosa_variance_x4=calculate_junzhi_and_fangcha(Iris_setosa_data)
#Iris_versicolor种类的各个特征属性上的均值和方差
Iris_versicolor_u_x1,Iris_versicolor_u_x2,Iris_versicolor_u_x3,Iris_versicolor_u_x4,\
Iris_versicolor_variance_x1,Iris_versicolor_variance_x2,Iris_versicolor_variance_x3,\
Iris_versicolor_variance_x4=calculate_junzhi_and_fangcha(Iris_versicolor_data)
#Iris_virginica种类的各个特征属性上的均值和方差
Iris_virginica_u_x1,Iris_virginica_u_x2,Iris_virginica_u_x3,Iris_virginica_u_x4,\
Iris_virginica_variance_x1,Iris_virginica_variance_x2,Iris_virginica_variance_x3,\
Iris_virginica_variance_x4=calculate_junzhi_and_fangcha(Iris_virginica_data)
'''开始测试'''
test_data=read_test_data(testname)
#print ('test_data',test_data)
#估计类先验概率
p1=len(Iris_setosa_data)/(len(Iris_versicolor_data)+len(Iris_virginica_data)+len(Iris_setosa_data))
p2=len(Iris_versicolor_data)/(len(Iris_versicolor_data)+len(Iris_virginica_data)+len(Iris_setosa_data))
p3=len(Iris_virginica_data)/(len(Iris_versicolor_data)+len(Iris_virginica_data)+len(Iris_setosa_data))
for x in test_data:
#在Iris_setosa种类上的各个特征属性的条件概率
P_x1_Iris_setosa,P_x2_Iris_setosa,P_x3_Iris_setosa,P_x4_Iris_setosa = calculate_P_xi_c(Iris_setosa_u_x1,Iris_setosa_u_x2,Iris_setosa_u_x3,Iris_setosa_u_x4,\
Iris_setosa_variance_x1,Iris_setosa_variance_x2,Iris_setosa_variance_x3,Iris_setosa_variance_x4,x)
#print(P_x1_Iris_setosa,P_x2_Iris_setosa,P_x3_Iris_setosa,P_x4_Iris_setosa)
#在Iris_versicolor种类上的各个特征属性的条件概率
P_x1_Iris_versicolor,P_x2_Iris_versicolor,P_x3_Iris_versicolor,P_x4_Iris_versicolor = calculate_P_xi_c(Iris_versicolor_u_x1,Iris_versicolor_u_x2,Iris_versicolor_u_x3,Iris_versicolor_u_x4,\
Iris_versicolor_variance_x1,Iris_versicolor_variance_x2,Iris_versicolor_variance_x3,Iris_versicolor_variance_x4,x)
#print(P_x1_Iris_versicolor,P_x2_Iris_versicolor,P_x3_Iris_versicolor)
#在Iris_virginica种类上的各个特征属性的条件概率
P_x1_Iris_virginica,P_x2_Iris_virginica,P_x3_Iris_virginica,P_x4_Iris_virginica = calculate_P_xi_c(Iris_virginica_u_x1,Iris_virginica_u_x2,Iris_virginica_u_x3,Iris_virginica_u_x4,\
Iris_virginica_variance_x1,Iris_virginica_variance_x2,Iris_virginica_variance_x3,Iris_virginica_variance_x4,x)
#print(P_x1_Iris_virginica,P_x2_Iris_virginica,P_x3_Iris_virginica,P_x4_Iris_virginica)
#计算各个种类上的后验概率
P_Iris_setosa = p1*P_x1_Iris_setosa*P_x2_Iris_setosa*P_x3_Iris_setosa*P_x4_Iris_setosa
#print( P_Iris_setosa)
P_Iris_versicolor = p2*P_x1_Iris_versicolor*P_x2_Iris_versicolor*P_x3_Iris_versicolor*P_x4_Iris_versicolor
#print( P_Iris_versicolor)
P_Iris_virginica = p3*P_x1_Iris_virginica*P_x2_Iris_virginica*P_x3_Iris_virginica*P_x4_Iris_virginica
#print( P_Iris_virginica)
if P_Iris_setosa>P_Iris_versicolor and P_Iris_setosa>P_Iris_virginica:
print(x[0],x[1],x[2],x[3],":这行数据属于Iris_setosa类")
if P_Iris_versicolor>P_Iris_setosa and P_Iris_versicolor>P_Iris_virginica:
print(x[0],x[1],x[2],x[3],":这行数据属于Iris_versicolor类")
if P_Iris_virginica>P_Iris_setosa and P_Iris_virginica>P_Iris_versicolor:
print(x[0],x[1],x[2],x[3],":这行数据属于Iris_virginica类")
1.7 运行结果及分析
类先验概率:
在每个种类上的各个特征属性的条件概率:
各个种类上的后验概率:
分类结果:
真实结果:
结果分析:
使用朴素贝叶斯分类器对鸢尾花数据集进行分类,结果显示,真实结果与我们的分类结果完全正确。因为朴素贝叶斯算法假设了属性之间的独立性,算法逻辑简单且比较稳定,因此朴素贝叶斯算法健壮性好,并且具有很好的分类效果。