本文用Python实现了BP神经网络分类算法,根据鸢尾花的4个特征,实现3种鸢尾花的分类。
算法参考文章:纯Python实现鸢尾属植物数据集神经网络模型

2020.07.21更新: 增加了分类结果可视化result_visualization
2020.07.09更新: 完善代码中取数据部分的操作。


代码及鸢尾花数据集可从GitHub上获取:点这里

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表示
    为方便起见,需要对数据集稍作处理:
  1. 将150条数据分隔为两个文件,前120条另存为iris_training.csv,即训练集;后30条另存为iris_test.csv,即测试集;
  2. 训练集和测试集都删去第1行;
  3. 训练集和测试集都删去原来的最后1列,并新增加3列,目的是用3列来表示鸢尾花的分类:如果原来最后一列是0,则新增加的3列为(0,0,0);如果原来最后一列是1,则新增加的3列为(0,1,0);如果原来最后一列是2,则新增加的3列为(0,0,1)。

2.算法实现

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

import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
from pandas.plotting import radviz
'''构建一个具有1个隐藏层的神经网络,隐层的大小为10输入层为4个特征,输出层为3个分类(1,0,0)为第一类,(0,1,0)为第二类,(0,0,1)为第三类
'''# 1.初始化参数
def initialize_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}return parameters# 2.前向传播
def forward_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}return a2, cache# 3.计算代价函数
def compute_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) / mreturn cost# 4.反向传播(计算代价函数的导数)
def backward_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}return grads# 5.更新参数
def update_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}return parameters# 6.模型评估
def predict(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)for i in range(n_rows):for j in range(n_cols):if a2[i][j] > 0.5:output[i][j] = 1else:output[i][j] = 0print('预测结果:')print(output)print('真实结果:')print(y_test)count = 0for k in range(0, n_cols):if output[0][k] == y_test[0][k] and output[1][k] == y_test[1][k] and output[2][k] == y_test[2][k]:count = count + 1else:print(k)acc = count / int(y_test.shape[1]) * 100print('准确率:%.2f%%' % acc)return output# 建立神经网络
def nn_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)# 梯度下降循环for i in range(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次迭代,输出一次代价函数if print_cost and i % 1000 == 0:print('迭代第%i次,代价函数为:%f' % (i, cost))return parameters# 结果可视化
# 特征有4个维度,类别有1个维度,一共5个维度,故采用了RadViz图
def result_visualization(x_test, y_test, result):cols = y_test.shape[1]y = []pre = []# 反转换类别的独热编码for i in range(cols):if y_test[0][i] == 0 and y_test[1][i] == 0 and y_test[2][i] == 1:y.append('setosa')elif y_test[0][i] == 0 and y_test[1][i] == 1 and y_test[2][i] == 0:y.append('versicolor')elif y_test[0][i] == 1 and y_test[1][i] == 0 and y_test[2][i] == 0:y.append('virginica')for j in range(cols):if result[0][j] == 0 and result[1][j] == 0 and result[2][j] == 1:pre.append('setosa')elif result[0][j] == 0 and result[1][j] == 1 and result[2][j] == 0:pre.append('versicolor')elif result[0][j] == 1 and result[1][j] == 0 and result[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)

最终结果:

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

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

3.总结

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

  1. 初始化参数
  2. 前向传播
  3. 计算代价函数
  4. 反向传播
  5. 更新参数
  6. 模型评估

欢迎关注我的微信公众号:

Python 基于BP神经网络的鸢尾花分类相关推荐

  1. python构建bp神经网络_鸢尾花分类(一个隐藏层)__1.数据集

    IDE:jupyter 目前我知道的数据集来源有两个,一个是csv数据集文件另一个是从sklearn.datasets导入 1.1 csv格式的数据集(下载地址已上传到博客园----数据集.rar) ...

  2. 【树叶分类】基于BP神经网络植物叶片分类Matlab代码

    1 简介 本文以树叶为实验对象,针对传统分类问题耗时长,效率低的不足,提出了一个基于BP神经网络植物智能分类系统.这个计算机辅助分类系统不仅能够帮助提高植物分类的准确率同时也能缩减工作人员的工作量. ...

  3. 猿创征文|深度学习基于前馈神经网络完成鸢尾花分类

    大家我是猿童学!这次给大家带来的是基于前馈神经网络完成鸢尾花分类! 在本实验中,我们使用的损失函数为交叉熵损失:优化器为随机梯度下降法:评价指标为准确率. 一.小批量梯度下降法 在梯度下降法中,目标函 ...

  4. 【项目实战】Python基于BP神经网络算法实现家用热水器用户行为分析与事件识别

    说明:这是一个机器学习实战项目(附带数据+代码+文档+视频讲解),如需数据+代码+文档+视频讲解可以直接到文章最后获取. 1.项目背景 居民在使用家用热水器的过程中,会因为地区气候.不同区域和用户年龄 ...

  5. BP神经网络对鸢尾花进行分类

    题目:BP神经网络分类器 一.实验项目: BP神经网络对鸢尾花进行分类 二.实验目的: 掌握BP神经网络学习算法,利用BP神经网络进行数据分类 三.实验内容: 1.编程实现BP神经网络算法 2.建立三 ...

  6. 机器学习应用篇(八)——基于BP神经网络的预测

    机器学习应用篇(八)--基于BP神经网络的预测 文章目录 机器学习应用篇(八)--基于BP神经网络的预测 一.Introduction 1 BP神经网络的优点 2 BP神经网络的缺点 二.实现过程 1 ...

  7. [python] 深度学习基础------人工神经网络实现鸢尾花分类(一)

    ​​​​​​​人工神经网络实现鸢尾花分类(一) 人工神经网络实现鸢尾花分类(二) 人工神经网络实现鸢尾花分类(三) 人工神经网络实现鸢尾花分类(四) 人工神经网络实现鸢尾花分类(五) 目录 人工智能主 ...

  8. 【Matlab】基于多层前馈网络BP神经网络实现多分类预测(Excel可直接替换数据)

    [Matlab]基于多层前馈网络BP神经网络实现多分类预测(Excel可直接替换数据) 1.算法简介 1.1 算法原理 1.2 算法流程 2.测试数据集 3.替换数据 4.混淆矩阵 5.对比结果 6. ...

  9. Tensorflow2.x框架-神经网络实现鸢尾花分类

    神经网络实现鸢尾花分类 一.数据准备     1.数据集读入 2.数据集乱序 3.生成训练集和测试集(即 x_train / y_train,x_test / y_test) 4.配成(输入特征,标签 ...

最新文章

  1. makefile 常用函数
  2. cmd 关闭进程及查看本机端口
  3. 【详解!思路清晰】1095 解码PAT准考证 (25分)
  4. Unsafe使用技巧之数组操作
  5. 浅谈关于nil和 null区别及相关问题
  6. TFS版本管理(八)
  7. Android应用分析进阶教程之一- 初识JEBAPI
  8. 谭浩强c语言图文,c语言谭浩强(图文教程).ppt
  9. 【PS】PS改变字体大小的方法
  10. 普度大学计算机科学博士,Top15普渡大学计算机博士全奖录取
  11. rpc error: code = Unavailable desc = connection error: desc = “transport: Error while dialing readin
  12. duilib入门简明教程(1)
  13. 【vim环境配置】详细实录
  14. 白银之手服务器 不稳定,截止TBC CWOW服务器及公会PVE实力排行榜
  15. 应急管理大屏可视化决策系统产品白皮书
  16. 微信小程序文字两边添加横线
  17. Yii实战开发大型商城项目视频教程
  18. 罗振宇跨年2022演讲金句品读
  19. 汇编jmp指令的一些用法(王爽)
  20. 华硕飞行堡垒系列无线网经常显示“无法连接网络” || 一打开游戏就断网

热门文章

  1. 关于微信群、QQ群和其他发布平台
  2. Excel2Latex 实操步骤(1)
  3. Java生成文件的md5文件方法的代码
  4. 相机ISO是什么 ISO是什么意思?
  5. 2023最新苹果CMS10魔加主题1.1.6去授权版+支持全部版本
  6. yolo+ocr集装箱字符识别(pytorch版本)
  7. 【学习日记】使用百度深度学习平台进行深度学习
  8. 算法系列15天速成——第四天 五大经典查找【上】
  9. AM5728调试经历
  10. Latex(1.1)——符号表