python基于BP实现数据分类(鸢尾花数据集)


由于最近课程过多,所以在此就不再讲解具体原理实现了,详情大家可以参考这篇文章,过程写的还是非常详细了。

鸢尾花数据集

起初笔者自己实现时,发现程序拥有大量的for循环语句,十分复杂
​​在这里插入图片描述

但细细思考发现其实神经网络的传递过程就十分像矩阵相乘,因为是全相连,所以之后便优化代码,调整为直接的矩阵乘法,速度和性能好了不少。

完整代码

import pandas as pd
import numpy as np
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn.preprocessing import MinMaxScaler
np.set_printoptions(suppress=True)


class BP:
    # b_Size隐藏层神经元个数
import pandas as pd
import numpy as np
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
from sklearn import model_selection
np.set_printoptions(suppress=True)


class BP:
    # b_Size隐藏层神经元个数
    def __init__(self, x, y,  Kinds, b_Size=10, alpha=0.1) -> None:
        self.x = np.matrix(x)  # 输入 n x m
        self.y = np.matrix(y)  # 输出 n x kinds
        self.b_size = b_Size
        self.v = np.matrix(np.random.rand(
            x.shape[1], b_Size))  # 随机生成输入层到隐藏层的权重
        self.w = np.matrix(np.random.rand(b_Size, Kinds))  # 随机生成隐藏层到输出成的权重
        self.alpha = alpha
        self.kinds = Kinds
        self.Gamma = np.matrix(np.random.rand(1, self.b_size))  # 隐藏层的阈值
        self.Theta = np.matrix(np.random.rand(1, self.kinds))  # 输出层的阈值

    def __sigmoid(x):
        return 1/(1 + np.exp(-x))

    def fit(self, N):
        pred = np.matrix(np.zeros((self.x.shape[0], self.kinds)))
        i = 0
        n = 0
        while n < N:
            # 向前传递
            # 输入层 --> 隐藏层
            Net1 = np.dot(self.x[i], self.v)
            b = BP.__sigmoid(Net1-self.Gamma)
            # 隐藏层 --> 输出层
            Net2 = np.dot(b, self.w)
            pred[i] = BP.__sigmoid(Net2 - self.Theta)

            # 反向调整
            g = np.multiply(np.multiply(
                pred[i], (1-pred[i])), self.y[i] - pred[i])
            e = np.multiply(np.multiply(b, (1-b)), (self.w*g.T).T)
            # 更新系数
            for j in range(self.x.shape[1]):
                for k in range(self.b_size):
                    self.v[j, k] = self.v[j, k] + \
                        self.alpha*e[0, k]*self.x[i, j]

            self.Gamma = self.Gamma - self.alpha*e

            for j in range(self.b_size):
                for k in range(self.y.shape[1]):
                    self.w[j, k] = self.w[j, k] + \
                        self.alpha*g[0, k]*b[0, j]

            self.Theta = self.Theta - self.alpha*g
            if i >= self.x.shape[0] - 1:
                i = 0
            else:
                i += 1
            n += 1

    def predict(self, x, pre):
        i = 0
        while i <= x.shape[0] - 1:
            pred = np.matrix(np.zeros((1, self.kinds)))
            # 输入层 --> 隐藏层
            Net1 = np.dot(x[i], self.v)
            b = BP.__sigmoid(Net1-self.Gamma)
            # 隐藏层 --> 输出层
            Net2 = np.dot(b, self.w)
            pred = BP.__sigmoid(Net2 - self.Theta)
            pre.append(np.argmax(pred[0]))
            i += 1

    def show(self, cm, labels_name, title):
        print("accuracy:{:.2%}".format(
            (cm[0][0]+cm[1][1]+cm[2][2])/(np.sum(cm))))
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]    # 归一化
        plt.imshow(cm, interpolation='nearest')    # 在特定的窗口上显示图像
        plt.title(title)    # 图像标题
        plt.colorbar()
        num_local = np.array(range(len(labels_name)))
        plt.xticks(num_local, labels_name, rotation=90)    # 将标签印在x轴坐标上
        plt.yticks(num_local, labels_name)    # 将标签印在y轴坐标上
        plt.ylabel('True label')
        plt.xlabel('Predicted label')
        plt.show()


def clear(list): 
    result = []
    label = []
    for i in list:
        if i[0] == 'Iris-setosa':
            result.append([1, 0, 0])
            label.append(0)
        elif i[0] == 'Iris-versicolor':
            result.append([0, 1, 0])
            label.append(1)
        else:
            result.append([0, 0, 1])
            label.append(2)
    result = np.array(result)
    label = np.array(label)
    return label, result


Labels_name = ['sepal_length', 'sepal_width',
               'petal_length', 'petal_width', 'species']
iris = pd.read_excel(
    '/Users/christcheng/Code/python/DataBase/iris_data.xlsx', header=1, names=Labels_name)
x = np.array(iris.iloc[:, 0:4])
y = np.array(iris.iloc[:, 4:5])
label, y = clear(y)
x_train, x_test, y_train, y_test, label_train, label_test = model_selection.train_test_split(
    x, y, label, test_size=0.4)
test = BP(x_train, y_train, 3)

test.fit(10000)
pre = []
test.predict(x_test, pre)
cm = confusion_matrix(label_test, np.array(pre))
title = "Iris Prediction"
test.show(cm, ['setosa', 'versicolor', 'virginica'], title)


  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于Python基于BP神经网络的鸢尾花分类问题,我可以给你一些参考。 首先,BP神经网络是一种常见的人工神经网络,它可以用于分类、回归等任务。而鸢尾花是一种常见的分类问题,因此可以用BP神经网络来进行分类。 在Python中,有多个库可以用来实现BP神经网络,例如TensorFlow、Keras、PyTorch等。这里以Keras为例,给出一个基于BP神经网络的鸢尾花分类的代码: ```python from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from keras.models import Sequential from keras.layers.core import Dense, Activation from keras.optimizers import SGD # 加载数据 iris = load_iris() X = iris.data y = iris.target # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # 构建BP神经网络 model = Sequential() model.add(Dense(10, input_dim=4)) model.add(Activation('sigmoid')) model.add(Dense(3)) model.add(Activation('softmax')) # 设置优化器和损失函数 sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy']) # 训练模型 model.fit(X_train, y_train, epochs=200, batch_size=10) # 在测试集上评估模型 loss, accuracy = model.evaluate(X_test, y_test) print("Test loss:", loss) print("Test accuracy:", accuracy) ``` 这段代码中,先用`load_iris()`方法加载鸢尾花数据集,然后将数据集划分为训练集和测试集。接着,用Keras的`Sequential()`方法构建BP神经网络,并设置优化器和损失函数。最后,用`fit()`方法对模型进行训练,用`evaluate()`方法在测试集上评估模型的性能。 需要注意的是,鸢尾花数据集的输出有3个类别,因此需要使用softmax作为最后一层的激活函数,并使用交叉熵损失函数。此外,还需要将输出进行one-hot编码,以便进行训练和评估。 希望这个例子能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值