Python 实现BP 神经网络分类算法,根据鸢尾花的 4 个特征,实现 3 种鸢尾花的分类

简介: Python 实现BP 神经网络分类算法,根据鸢尾花的 4 个特征,实现 3 种鸢尾花的分类

iris_data_classification_bpnn_V1.py 需使用 bpnn_V1 数据集 文件夹中的数据


iris_data_classification_bpnn_V2.py 需使用 bpnn_V2 数据集 文件夹中的数据


iris_data_classification_knn.py 需使用 原始数据集 文件夹中的数据


iris_data_cluster_sklearn.py 需使用 sklearn 数据集 文件夹中的数据


不同数据集里数据都是一样的,只是为了程序使用方便而做了一些格式的变动。


2020.07.21 更新: 增加了分类结果可视化 result_visualization。

2020.07.09 更新: 完善代码中取数据部分的操作。


1.数据准备


鸢尾花数据集包含 4 种特征,萼片长度(Sepal Length)、萼片宽度(Sepal Width)、花瓣长度(Petal Length)和花瓣宽度(Petal Width),以及 3 种鸢尾花 Versicolor、Virginica 和 Setosa。


数据集共 151 行,5 列:


  • 第 1 行是数据说明,“150”表示共 150 条数据;“4”表示特征数;“setosa、versicolor、virginica”是三类花的名字
  • 第 2 行至第 151 行是 150 条数据
  • 第 1 至 4 列是 Sepal Length、Sepal Width、Petal Length、Petal Width 4 个特征


第 5 列是花的类别,用 0、1、2 表示


bd22b5c65c32f5597034c196be2bc8ee.png


为方便起见,需要对数据集稍作处理:

  1. 将 150 条数据分隔为两个文件,前 120 条另存为 iris_training.csv,即训练集;后 30 条另存为 iris_test.csv,即测试集;
  2. 训练集和测试集都删去第 1 行;


训练集和测试集都删去原来的最后 1 列,并新增加 3 列,目的是用 3 列来表示鸢尾花的分类:如果原来最后一列是 0,则新增加的 3 列为(0,0,0);如果原来最后一列是 1,则新增加的 3 列为(0,1,0);如果原来最后一列是 2,则新增加的 3 列为(0,0,1)。


aa33295bf083fda12d5c9f565f207bae.png


2.算法实现


纯 Python 实现鸢尾属植物数据集神经网络模型 这篇文章中讲解得更为详细。本人对代码做了略微的修改,并增加了评估模型准确率的 predict() 函数。

以下代码对应的是 iris_data_classification_bpnn_V2.py 文件

importpandasaspdimportnumpyasnpimportdatetimeimportmatplotlib.pyplotaspltfrompandas.plottingimportradviz'''
    构建一个具有1个隐藏层的神经网络,隐层的大小为10
    输入层为4个特征,输出层为3个分类
    (1,0,0)为第一类,(0,1,0)为第二类,(0,0,1)为第三类
'''# 1.初始化参数definitialize_parameters(n_x,n_h,n_y):np.random.seed(2)# 权重和偏置矩阵w1=np.random.randn(n_h,n_x)*0.01b1=np.zeros(shape=(n_h,1))w2=np.random.randn(n_y,n_h)*0.01b2=np.zeros(shape=(n_y,1))# 通过字典存储参数parameters={'w1':w1,'b1':b1,'w2':w2,'b2':b2}returnparameters# 2.前向传播defforward_propagation(X,parameters):w1=parameters['w1']b1=parameters['b1']w2=parameters['w2']b2=parameters['b2']# 通过前向传播来计算a2z1=np.dot(w1,X)+b1# 这个地方需注意矩阵加法:虽然(w1*X)和b1的维度不同,但可以相加a1=np.tanh(z1)# 使用tanh作为第一层的激活函数z2=np.dot(w2,a1)+b2a2=1/(1+np.exp(-z2))# 使用sigmoid作为第二层的激活函数# 通过字典存储参数cache={'z1':z1,'a1':a1,'z2':z2,'a2':a2}returna2,cache# 3.计算代价函数defcompute_cost(a2,Y,parameters):m=Y.shape[1]# Y的列数即为总的样本数# 采用交叉熵(cross-entropy)作为代价函数logprobs=np.multiply(np.log(a2),Y)+np.multiply((1-Y),np.log(1-a2))cost=-np.sum(logprobs)/mreturncost# 4.反向传播(计算代价函数的导数)defbackward_propagation(parameters,cache,X,Y):m=Y.shape[1]w2=parameters['w2']a1=cache['a1']a2=cache['a2']# 反向传播,计算dw1、db1、dw2、db2dz2=a2-Ydw2=(1/m)*np.dot(dz2,a1.T)db2=(1/m)*np.sum(dz2,axis=1,keepdims=True)dz1=np.multiply(np.dot(w2.T,dz2),1-np.power(a1,2))dw1=(1/m)*np.dot(dz1,X.T)db1=(1/m)*np.sum(dz1,axis=1,keepdims=True)grads={'dw1':dw1,'db1':db1,'dw2':dw2,'db2':db2}returngrads# 5.更新参数defupdate_parameters(parameters,grads,learning_rate=0.4):w1=parameters['w1']b1=parameters['b1']w2=parameters['w2']b2=parameters['b2']dw1=grads['dw1']db1=grads['db1']dw2=grads['dw2']db2=grads['db2']# 更新参数w1=w1-dw1*learning_rateb1=b1-db1*learning_ratew2=w2-dw2*learning_rateb2=b2-db2*learning_rateparameters={'w1':w1,'b1':b1,'w2':w2,'b2':b2}returnparameters# 6.模型评估defpredict(parameters,x_test,y_test):w1=parameters['w1']b1=parameters['b1']w2=parameters['w2']b2=parameters['b2']z1=np.dot(w1,x_test)+b1a1=np.tanh(z1)z2=np.dot(w2,a1)+b2a2=1/(1+np.exp(-z2))# 结果的维度n_rows=y_test.shape[0]n_cols=y_test.shape[1]# 预测值结果存储output=np.empty(shape=(n_rows,n_cols),dtype=int)foriinrange(n_rows):forjinrange(n_cols):ifa2[i][j]>0.5:output[i][j]=1else:output[i][j]=0print('预测结果:')print(output)print('真实结果:')print(y_test)count=0forkinrange(0,n_cols):ifoutput[0][k]==y_test[0][k]andoutput[1][k]==y_test[1][k]andoutput[2][k]==y_test[2][k]:count=count+1else:print(k)acc=count/int(y_test.shape[1])*100print('准确率:%.2f%%'%acc)returnoutput# 建立神经网络defnn_model(X,Y,n_h,n_input,n_output,num_iterations=10000,print_cost=False):np.random.seed(3)n_x=n_input# 输入层节点数n_y=n_output# 输出层节点数# 1.初始化参数parameters=initialize_parameters(n_x,n_h,n_y)# 梯度下降循环foriinrange(0,num_iterations):# 2.前向传播a2,cache=forward_propagation(X,parameters)# 3.计算代价函数cost=compute_cost(a2,Y,parameters)# 4.反向传播grads=backward_propagation(parameters,cache,X,Y)# 5.更新参数parameters=update_parameters(parameters,grads)# 每1000次迭代,输出一次代价函数ifprint_costandi%1000==0:print('迭代第%i次,代价函数为:%f'%(i,cost))returnparameters# 结果可视化# 特征有4个维度,类别有1个维度,一共5个维度,故采用了RadViz图defresult_visualization(x_test,y_test,result):cols=y_test.shape[1]y=[]pre=[]# 反转换类别的独热编码foriinrange(cols):ify_test[0][i]==0andy_test[1][i]==0andy_test[2][i]==1:y.append('setosa')elify_test[0][i]==0andy_test[1][i]==1andy_test[2][i]==0:y.append('versicolor')elify_test[0][i]==1andy_test[1][i]==0andy_test[2][i]==0:y.append('virginica')forjinrange(cols):ifresult[0][j]==0andresult[1][j]==0andresult[2][j]==1:pre.append('setosa')elifresult[0][j]==0andresult[1][j]==1andresult[2][j]==0:pre.append('versicolor')elifresult[0][j]==1andresult[1][j]==0andresult[2][j]==0:pre.append('virginica')else:pre.append('unknown')# 将特征和类别矩阵拼接起来real=np.column_stack((x_test.T,y))prediction=np.column_stack((x_test.T,pre))# 转换成DataFrame类型,并添加columnsdf_real=pd.DataFrame(real,index=None,columns=['Sepal Length','Sepal Width','Petal Length','Petal Width','Species'])df_prediction=pd.DataFrame(prediction,index=None,columns=['Sepal Length','Sepal Width','Petal Length','Petal Width','Species'])# 将特征列转换为float类型,否则radviz会报错df_real[['Sepal Length','Sepal Width','Petal Length','Petal Width']]=df_real[['Sepal Length','Sepal Width','Petal Length','Petal Width']].astype(float)df_prediction[['Sepal Length','Sepal Width','Petal Length','Petal Width']]=df_prediction[['Sepal Length','Sepal Width','Petal Length','Petal Width']].astype(float)# 绘图plt.figure('真实分类')radviz(df_real,'Species',color=['blue','green','red','yellow'])plt.figure('预测分类')radviz(df_prediction,'Species',color=['blue','green','red','yellow'])plt.show()if__name__=="__main__":# 读取数据data_set=pd.read_csv('D:\\iris_training.csv',header=None)# 第1种取数据方法:X=data_set.iloc[:,0:4].values.T# 前四列是特征,T表示转置Y=data_set.iloc[:,4:].values.T# 后三列是标签# 第2种取数据方法:# X = data_set.ix[:, 0:3].values.T# Y = data_set.ix[:, 4:6].values.T# 第3种取数据方法:# X = data_set.loc[:, 0:3].values.T# Y = data_set.loc[:, 4:6].values.T# 第4种取数据方法:# X = data_set[data_set.columns[0:4]].values.T# Y = data_set[data_set.columns[4:7]].values.TY=Y.astype('uint8')# 开始训练start_time=datetime.datetime.now()# 输入4个节点,隐层10个节点,输出3个节点,迭代10000次parameters=nn_model(X,Y,n_h=10,n_input=4,n_output=3,num_iterations=10000,print_cost=True)end_time=datetime.datetime.now()print("用时:"+str((end_time-start_time).seconds)+'s'+str(round((end_time-start_time).microseconds/1000))+'ms')# 对模型进行测试data_test=pd.read_csv('D:\\iris_test.csv',header=None)x_test=data_test.iloc[:,0:4].values.Ty_test=data_test.iloc[:,4:].values.Ty_test=y_test.astype('uint8')result=predict(parameters,x_test,y_test)# 分类结果可视化result_visualization(x_test,y_test,result)

最终结果:


69e7ce57264840b47b8a0436addfdfcd.png

分类的可视化效果,左侧为测试集的真实分类,右侧为模型的预测分类结果,采用的是 RadViz 图:

a8029847f1a9b8c3f8da66520f487651.png


每次运行时准确率可能都不一样,可以通过调整学习率、隐节点数、迭代次数等参数来改善模型的效果。


3.总结


算法的实现总共分为 6 步:

  1. 初始化参数
  2. 前向传播
  3. 计算代价函数
  4. 反向传播
  5. 更新参数
  6. 模型评估
相关文章
|
1天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
22 12
|
5天前
|
传感器 算法 物联网
基于粒子群算法的网络最优节点部署优化matlab仿真
本项目基于粒子群优化(PSO)算法,实现WSN网络节点的最优部署,以最大化节点覆盖范围。使用MATLAB2022A进行开发与测试,展示了优化后的节点分布及其覆盖范围。核心代码通过定义目标函数和约束条件,利用PSO算法迭代搜索最佳节点位置,并绘制优化结果图。PSO算法灵感源于鸟群觅食行为,适用于连续和离散空间的优化问题,在通信网络、物联网等领域有广泛应用。该算法通过模拟粒子群体智慧,高效逼近最优解,提升网络性能。
|
7天前
|
监控 算法 安全
内网桌面监控软件深度解析:基于 Python 实现的 K-Means 算法研究
内网桌面监控软件通过实时监测员工操作,保障企业信息安全并提升效率。本文深入探讨K-Means聚类算法在该软件中的应用,解析其原理与实现。K-Means通过迭代更新簇中心,将数据划分为K个簇类,适用于行为分析、异常检测、资源优化及安全威胁识别等场景。文中提供了Python代码示例,展示如何实现K-Means算法,并模拟内网监控数据进行聚类分析。
28 10
|
5天前
|
机器学习/深度学习 数据采集 算法
基于GWO灰狼优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB2022a,展示了时间序列预测算法的运行效果(无水印)。核心程序包含详细中文注释和操作视频。算法采用CNN-GRU-SAM网络,结合灰狼优化(GWO),通过卷积层提取局部特征、GRU处理长期依赖、自注意力机制捕捉全局特征,最终实现复杂非线性时间序列的高效预测。
|
25天前
|
存储 算法 安全
控制局域网上网软件之 Python 字典树算法解析
控制局域网上网软件在现代网络管理中至关重要,用于控制设备的上网行为和访问权限。本文聚焦于字典树(Trie Tree)算法的应用,详细阐述其原理、优势及实现。通过字典树,软件能高效进行关键词匹配和过滤,提升系统性能。文中还提供了Python代码示例,展示了字典树在网址过滤和关键词屏蔽中的具体应用,为局域网的安全和管理提供有力支持。
50 17
|
4天前
|
算法 数据安全/隐私保护 计算机视觉
基于FPGA的图像双线性插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
本项目展示了256×256图像通过双线性插值放大至512×512的效果,无水印展示。使用Matlab 2022a和Vivado 2019.2开发,提供完整代码及详细中文注释、操作视频。核心程序实现图像缩放,并在Matlab中验证效果。双线性插值算法通过FPGA高效实现图像缩放,确保质量。
|
1月前
|
算法 数据安全/隐私保护 计算机视觉
基于Retinex算法的图像去雾matlab仿真
本项目展示了基于Retinex算法的图像去雾技术。完整程序运行效果无水印,使用Matlab2022a开发。核心代码包含详细中文注释和操作步骤视频。Retinex理论由Edwin Land提出,旨在分离图像的光照和反射分量,增强图像对比度、颜色和细节,尤其在雾天条件下表现优异,有效解决图像去雾问题。
|
1月前
|
算法 数据可视化 安全
基于DWA优化算法的机器人路径规划matlab仿真
本项目基于DWA优化算法实现机器人路径规划的MATLAB仿真,适用于动态环境下的自主导航。使用MATLAB2022A版本运行,展示路径规划和预测结果。核心代码通过散点图和轨迹图可视化路径点及预测路径。DWA算法通过定义速度空间、采样候选动作并评估其优劣(目标方向性、障碍物距离、速度一致性),实时调整机器人运动参数,确保安全避障并接近目标。
148 68
|
3天前
|
算法
基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真
本程序基于海鸥优化算法(SOA)进行三维曲面最高点搜索的MATLAB仿真,输出收敛曲线和搜索结果。使用MATLAB2022A版本运行,核心代码实现种群初始化、适应度计算、交叉变异等操作。SOA模拟海鸥觅食行为,通过搜索飞行、跟随飞行和掠食飞行三种策略高效探索解空间,找到全局最优解。
|
1月前
|
算法 数据安全/隐私保护
室内障碍物射线追踪算法matlab模拟仿真
### 简介 本项目展示了室内障碍物射线追踪算法在无线通信中的应用。通过Matlab 2022a实现,包含完整程序运行效果(无水印),支持增加发射点和室内墙壁设置。核心代码配有详细中文注释及操作视频。该算法基于几何光学原理,模拟信号在复杂室内环境中的传播路径与强度,涵盖场景建模、射线发射、传播及接收点场强计算等步骤,为无线网络规划提供重要依据。

热门文章

最新文章

推荐镜像

更多