Python 模式识别数据集分析与BP神经网络实现

本代码示例展示了使用Python进行模式识别数据集分析,包括数据预处理、特征提取、BP神经网络模型训练和评估。

导入库

import pandas as pd
from pandas import DataFrame
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
import numpy as np
import math
import random
from sklearn.model_selection import KFold
from sklearn.metrics import confusion_matrix, roc_curve, auc
import matplotlib.pyplot as plt

数据读取与处理

# 读取Excel表
data = pd.read_excel(r'C:\Users\86158\PycharmProjects\pythonProject1\2023模式识别数据集汇总.xlsx')

# 归一化函数
def maxminnorm(array):
    maxcols = array.max(axis=0)
    mincols = array.min(axis=0)
    data_shape = array.shape
    data_rows = data_shape[0]
    data_cols = data_shape[1]
    t = np.empty((data_rows, data_cols))
    for i in range(data_cols):
        t[:, i] = (array[:, i] - mincols[i]) / (maxcols[i] - mincols[i])
    return t

# 数据集读取与处理
def loadDataset(filepath):
    '''加载数据集,对数据进行预处理,并打乱数据集
        filepath: 数据集文件存放路径
    '''
    pydata = pd.read_excel(r'C:\Users\86158\PycharmProjects\pythonProject1\2023模式识别数据集汇总.xlsx')
    # 填充缺省值--用各列平均数补全
    pydata['鞋码'] = pydata['鞋码'].fillna(pydata['鞋码'].mean())
    pydata['50米成绩'] = pydata['50米成绩'].fillna(pydata['50米成绩'].mean())
    pydata['肺活量'] = pydata['肺活量'].fillna(pydata['肺活量'].mean())
    data = pydata.dropna()
    data = data.iloc[:, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]].values
    dataset = data[:, [1, 3, 4, 5, 6, 7]]
    dataset = np.array(dataset)
    dataset = maxminnorm(dataset)
    return dataset

BP神经网络实现

def fun_z(weights, inputs):
    '''计算神经元的输入:z = weight * inputs + b
    :param weights: 网络参数(权重矩阵和偏置项)
    :param inputs: 上一层神经元的输出
    :return: 当前层神经元的输入
    '''
    bias_term = weights[-1]
    z = 0
    for i in range(len(weights) - 1):
        z += weights[i] * inputs[i]
    z += bias_term
    return z

def sigmoid(z):
    '''激活函数(Sigmoid):f(z) = Sigmoid(z)
    :param z: 神经元的输入
    :return: 神经元的输出
    '''
    return 1.0 / (1.0 + math.exp(-z))

def sigmoid_derivative(output):
    '''Sigmoid激活函数求导
    :param output: 激活函数的输出值
    :return: 求导计算结果
    '''
    return output * (1.0 - output)

def forward_propagate(network, inputs):
    '''前向传播计算
    :param network: 神经网络
    :param inputs: 一个样本数据
    :return: 前向传播计算的结果
    '''
    for layer in network:  # 循环计算每一层
        new_inputs = []
        for neuron in layer:  # 循环计算每一层的每一个神经元
            z = fun_z(neuron['weights'], inputs)
            neuron['output'] = sigmoid(z)
            new_inputs.append(neuron['output'])
        inputs = new_inputs
    return inputs

def backward_propagate_error(network, actual_label):
    '''误差进行反向传播
    :param network: 神经网络
    :param actual_label: 真实的标签值
    :return:
    '''
    for i in reversed(range(len(network))):  # 从最后一层开始计算误差
        layer = network[i]
        errors = list()
        if i != len(network) - 1:  # 不是输出层
            for j in range(len(layer)):  # 计算每一个神经元的误差
                error = 0.0
                for neuron in network[i + 1]:
                    error += (neuron['weights'][j] * neuron['delta'])
                errors.append(error)
        else:  # 输出层
            for j in range(len(layer)):  # 计算每一个神经元的误差
                neuron = layer[j]
                errors.append(actual_label[j] - neuron['output'])
        # 计算误差项 delta
        for j in range(len(layer)):
            neuron = layer[j]
            neuron['delta'] = errors[j] * sigmoid_derivative(neuron['output'])

def update_parameters(network, row, l_rate):
    '''利用误差更新神经网络的参数(权重矩阵和偏置项)
    :param network: 神经网络
    :param row: 一个样本数据
    :param l_rate: 学习率
    :return:
    '''
    for i in range(len(network)):
        inputs = row[:-1]
        if i != 0:  # 获取上一层网络的输出
            inputs = [neuron['output'] for neuron in network[i - 1]]
        for neuron in network[i]:
            # 更新权重矩阵
            for j in range(len(inputs)):
                neuron['weights'][j] += l_rate * neuron['delta'] * inputs[j]
            # 更新偏置项
            neuron['weights'][-1] += l_rate * neuron['delta']

def initialize_network(n_inputs, n_hidden, n_outputs):
    '''初始化BP网络(初始化隐藏层和输出层的参数:权重矩阵和偏置项)
    :param n_inputs: 特征列数
    :param n_hidden: 隐藏层神经元个数
    :param n_outputs: 输出层神经元个数,即分类的总类别数
    :return: 初始化后的神经网络
    '''
    network = list()
    # 隐藏层
    hidden_layer = [{'weights': [random.random() for i in range(n_inputs + 1)]} for i in range(n_hidden)]
    network.append(hidden_layer)
    # 输出层
    output_layer = [{'weights': [random.random() for i in range(n_hidden + 1)]} for i in range(n_outputs)]
    network.append(output_layer)
    return network

def train(train_data, l_rate, epochs, n_hidden):
    '''训练神经网络(迭代n_epoch个回合)
    :param train_data: 训练集
    :param l_rate: 学习率
    :param epochs: 迭代的回合数
    :param n_hidden: 隐藏层神经元个数
    :param val_data: 验证集
    :return: 训练好的网络
    '''
    # 获取特征列数
    n_inputs = len(train_data[0]) - 1
    # 获取分类的总类别数
    n_outputs = len(set([row[0] for row in train_data]))
    # 初始化网络
    network = initialize_network(n_inputs, n_hidden, n_outputs)

    for epoch in range(epochs):  # 训练epochs个回合
        for row in train_data:
            # 前馈计算
            _ = forward_propagate(network, row)
            # 处理一下类标,用于计算误差
            actual_label = [0 for i in range(n_outputs)]
            row = row.tolist()
            actual_label[int(row[0])] = 1
            # 误差反向传播计算
            backward_propagate_error(network, actual_label)
            # 更新参数
            update_parameters(network, row, l_rate)
    return network

def validation(network, val_data):
    '''测试模型在验证集上的效果
    :param network: 神经网络
    :param val_data: 验证集
    :return: 模型在验证集上的准确率
    '''
    # 获取预测类标
    predicted_label = []
    for row in val_data:
        prediction = predict(network, row)
        predicted_label.append(prediction)
    # 获取真实类标
    actual_label = [row[0] for row in val_data]
    # 计算SE,SP,ACC指标
    SE, SP, ACC = accuracy_calculation(actual_label, predicted_label)
    print('SE:', SE)
    print('SP:', SP)
    print('ACC:', ACC)
    # 绘制ROC曲线
    fpr, tpr, _ = roc_curve(actual_label, predicted_label)
    roc_auc = auc(fpr, tpr)
    plt.figure(figsize=(8, 8))
    # 假正率为横坐标,真正率为纵坐标做曲线
    lw = 3
    plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve (area = %0.2f)' % roc_auc)
    plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('BP Algorithm')
    plt.legend(loc='lower right')
    plt.show()

def accuracy_calculation(actual_label, predicted_label):
    '''计算准确率
    :param actual_label: 真实类标
    :param predicted_label: 模型预测的类标
    :return: 准确率(百分制)
    '''
    correct_count = 0
    for i in range(len(actual_label)):
        if actual_label[i] == predicted_label[i]:
            correct_count += 1

    # 计算混淆矩阵
    matrix = confusion_matrix(actual_label, predicted_label)
    TP = matrix[0][0]
    FP = matrix[0][1]
    FN = matrix[1][0]
    TN = matrix[1][1]
    SE = TP / (TP + FN)
    SP = TN / (TN + FP)
    ACC = (TP + TN) / (TP + FP + TN + FN)

    return SE, SP, ACC

def predict(network, row):
    '''使用模型对当前输入的数据进行预测
    :param network: 神经网络
    :param row: 一个数据样本
    :return: 预测结果
    '''
    outputs = forward_propagate(network, row)
    return outputs.index(max(outputs))

# 主程序
if __name__ == '__main__':
    file_path = r'C:\Users\86158\PycharmProjects\pythonProject1\2023模式识别数据集汇总.xlsx'

    l_rate = 0.2  # 学习率
    epochs = 150  # 迭代训练的次数
    n_hidden = 5  # 隐藏层神经元个数

    # 加载数据并划分训练集和验证集
    dataset = loadDataset(r'C:\Users\86158\PycharmProjects\pythonProject1\2023模式识别数据集汇总.xlsx')
    # 5折交叉划分数据集
    kf = KFold(n_splits=5, shuffle=True, random_state=0)
    # 训练模型
    i = 1
    for train_index, test_index in kf.split(dataset):
        print('*********Train %d**********' % (i))
        train_data = dataset[train_index]
        val_data = dataset[test_index]
        network = train(train_data, l_rate, epochs, n_hidden)
        validation(network, val_data)
        i += 1

代码说明

  1. 数据读取与预处理: 代码首先使用pd.read_excel读取Excel数据集,然后使用fillna填充缺失值,并进行数据归一化处理。
  2. BP神经网络实现: 代码实现了BP神经网络的各个部分,包括神经元输入计算、激活函数、前向传播、误差反向传播和参数更新等。
  3. 训练和评估: 代码使用5折交叉验证进行模型训练和评估,并计算了模型的SE、SP、ACC指标,并绘制了ROC曲线。

运行说明

  1. 将数据集文件2023模式识别数据集汇总.xlsx放置在代码所在目录下。
  2. 运行代码,代码会进行5折交叉验证,并输出训练过程中的结果。

注意事项

  1. 数据集的格式需要与代码中读取的格式一致。
  2. 可以根据实际情况调整学习率、迭代次数、隐藏层神经元个数等参数。
  3. 代码示例中使用的激活函数为Sigmoid函数,可以根据需要选择其他激活函数。
  4. 可以根据需求添加其他评估指标,例如F1 score、precision等。

总结

本代码示例展示了使用Python进行模式识别数据集分析和BP神经网络实现的基本步骤,您可以参考该代码进行其他数据集的分析和模型训练。

Python 模式识别数据集分析与BP神经网络实现

原文地址: https://www.cveoy.top/t/topic/tPN 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录