python,现在临近毕业也逐渐意识到这门语言的重要性,后悔不能当初把它学好(悔不当初)!!!
本文原来是matlab的,编写过常用的机器学习代码,现在转型python,希望大家看了我写的新手代码,不要嘲笑!!
学了一段时间python,自己尝试编写的第一个算法——BP神经网络,并将应用到鸢尾花数据集上,数据集连接如下:
鸢尾花数据集iris0.txt
数据集集已经进行了处理,属于纯纯的0-1问题分类(二分类问题),
先说一说在编写过程中遇到的问题,程序已经附在最后了
1、程序的模块化
在写程序的程序的时候,应当尽可能的将程序进行模块分割,一方面看起来简洁,另一方面,也会提高程序的可阅读。通常情况下,将固定功能的程序和高频重复调用次数,进行封装成单个函数。个人感觉程序模块分割可能需要考虑如下几点:
1、模块的功能是否固定,
2、封装的函数的通用性,不可能每个程序都需要重新修改封装好的函数
3、调用的次数,个人感觉对于大型程序的话,这一点比较重要
2、函数包的导入,如numpy random
对于初次接触python的来说,函数包真的是很头疼的问题,很多包都不知道什么意思,也不知道自己需要的在那个包中,
我常用的方式:
1、将光标放在报错的位置
2、同时按下快捷键:alt+enter,系统会进行提示,点击第一个选项,系统会自动导入工具包
导入前:
操作后:
3、文件的打开方式和读取方式
1、打开方式
file=open(‘filename.txt’,‘type’)
filename:代表文件的名字,注意需要加上文件的类型,如.txt,.dat 等等
type:代表的是对文件进行的操作,如 r:只读,w:只写,r+:可读可写等等,目前,我还用不到o(╥﹏╥)o
2、读取方式
file.read():默认读取文件中的每一行元素,并单独输出,这有点像readlines
file.readline():表示,支队数据的第一行读取,并将第一行中的每个元素单独进行保存,空格也不放过。
file.readlines():表示对数据进行按行读取,并将每一行进行保存成列表
4 错误:TypeError: slice indices must be integers or None or have an index method
这边表示列表在切片时的索引必须是整数才行,如,在训练集和测试集的分配过程,矩阵的数据获取,进行经常性忽略列表中数据的类型。
#按比例划分训练集和测试集
trainset = dataset_temp[: int(len(dataset_temp)*ratio)]
testset = dataset_temp[int(len(dataset_temp)*ratio) + 1:]
5 随机数的参数方式
随机数在网络参数初始化过程中,会经常使用,需要注意的是,需要导入random和numpy包
import random
import numpy as np
如下:
np.random.uniform(lower, upper, (size)):产生随机数,类型为浮点型,可指定上下界,指定产生随机数的大小
input_hidden_weight = np.random.uniform(lower, upper, [num_input, num_hidden])
hidden_bais = np.random.uniform(lower, upper, [1, num_hidden])
hidden_output_weight = np.random.uniform(lower, upper, [num_output, num_hidden])
output_bais = np.random.uniform(lower, upper, [1, num_output])
np.random.randint(lower, upper, (size)):产生指定范围的整数
5 np.mat 函数
该函数的功能主要是将列表,转化成矩阵,方便后面的计算
6 列表之间的乘运算
np.dot(sample1, sample2):将两个列表或者矩阵相乘,并将计算后的结果求和。该方法遵循矩阵之间运算法则
hidden_input = np.dot(input_data, input_hidden_weight).astype(np.float)
np.multiply(sample1, sample2):两个向量或者矩阵之间,进行点对点的相乘,返回相同大小的矩阵或者列表。
temp3 = np.multiply(error, device_sigmoid).astype(np.float)
7 错误:TypeError: Cannot cast array data from dtype(‘float64’) to dtype(’<U32’) according to the rule ‘safe’
主要是说的计算类型或者赋值类型错误,此时需要进行数据类型转化
也就是再出现错误的位置后面添加:.astype(np.float),根据自己的需要,改变数据类型
为方便阅读和验证,手写推导图敬上:
python之BP神经网络代码
'''
BP 神经网络分为如下几个部分:
1 数据读取预处理部分
2 网络参数预处理部分
3 激活函数部分
4 参数训练部分
5 模型性能测试部分
6 主函数部分
'''
import random
import numpy as np
# 1 数据读取预处理部分
def dataset_open(address, ratio):
#读取样本数据
dataset = open(address)
# dataset = random.shuffle
#建立空的列表用于存放,训练集特征和标签,测试集特征和标签
train_feature = []
train_label = []
test_feature = []
test_label = []
dataset_temp = []
#将数据集进行随机打乱
for i in dataset.readlines():
temp1 = i.strip().split()
dataset_temp.append([temp1[j] for j in range(len(temp1))])
random.shuffle(dataset_temp)
#按比例划分训练集和测试集
trainset = dataset_temp[: int(len(dataset_temp)*ratio)]
testset = dataset_temp[int(len(dataset_temp)*ratio) + 1:]
#将训练集和测试集存放到相应的列表中
for i in trainset:
train_feature.append([i[j] for j in range(len(i) - 1)])
train_label.append(i[-1])
for i in testset:
test_feature.append([i[j] for j in range(len(i) - 1)])
test_label.append(i[-1])
# data_feature.append([temp[j] for j in range(len(temp)-1)]) #同上
return train_feature, train_label, test_feature, test_label
# 2 网络参数预处理部分
def parameter_proprocess(num_input, num_hidden, num_output, lower, upper):
#初始化产生相应大小的权重和偏置
input_hidden_weight = np.random.uniform(lower, upper, [num_input, num_hidden])
hidden_bais = np.random.uniform(lower, upper, [1, num_hidden])
hidden_output_weight = np.random.uniform(lower, upper, [num_output, num_hidden])
output_bais = np.random.uniform(lower, upper, [1, num_output])
return input_hidden_weight, hidden_bais, hidden_output_weight, output_bais
# 3 激活函数部分
def sigmoid(input):
result = 1 / (1 + np.exp(input))
return result
# 4 参数训练部分
def training(train_set, train_label, input_hidden_weight, hidden_bais, hidden_output_weight, output_bais, num_iter, step_size):
for k in range(num_iter):
for i in range(len(train_set)):
#将输入的数据从训练集中单独提取出来
input_data = np.mat(train_set[i]).astype(np.float)
#计算相应的隐层输入,隐层输出,输出层输入,输出层输出
hidden_input = np.dot(input_data, input_hidden_weight).astype(np.float)
hidden_output = sigmoid(hidden_input + hidden_bais).astype(np.float)
output_input = np.dot(hidden_output, np.transpose(hidden_output_weight)).astype(np.float)
output = sigmoid(output_input + output_bais).astype(np.float)
#参数更新
device_sigmoid = np.dot(output, 1-output).astype(np.float)
error = float(output) - float(train_label[i])
temp3 = np.multiply(error, device_sigmoid).astype(np.float)
#输出层权重
delta_beta = np.multiply(temp3, hidden_output).astype(np.float)
#输出层阈值
delta_b2 = temp3
#隐层阈值
temp4 = np.multiply(hidden_output, np.array(1-hidden_output)).astype(np.float)
temp5 = np.multiply(temp4, hidden_output_weight).astype(np.float)
delta_b1 = np.multiply(temp5, temp3).astype(np.float)
# 隐层权重
delta_w = np.multiply(np.transpose(input_data), delta_b1).astype(np.float)
#加入步长,更新策略
input_hidden_weight += delta_w * float(step_size)
hidden_bais += delta_b1 * float(step_size)
hidden_output_weight += delta_beta * float(step_size)
output_bais += delta_b2 * float(step_size)
return input_hidden_weight, hidden_bais, hidden_output_weight, output_bais
#测试集编程
def testing(test_set, test_label, input_hidden_weight, hidden_bais, hidden_output_weight, output_bais):
count = 0
for i in range(len(test_set)):
#测试集数据输入
input_data = np.mat(test_set[i]).astype(np.float)
#模型在测试集上的计算结果
hidden_input = np.dot(input_data, input_hidden_weight).astype(np.float)
hidden_output = sigmoid(hidden_input + hidden_bais).astype(np.float)
output_input = np.dot(hidden_output, np.transpose(hidden_output_weight)).astype(np.float)
output = sigmoid(output_input + output_bais).astype(np.float)
# 二分类问题,取0.5作为类别分界线,考虑到不平衡问题的同学,可自行设计
if output > 0.5:
output = 1
else:
output = 0
#统计预测正确的数量
if output == int(test_label[i]):
count += 1
#计算预测正确的比例
accuracy = count / len(test_set)
return accuracy
#模型超参数设置
num_input=4
num_hidden=100
num_output=1
lower=-1
upper=1
num_iter=100
step_size = 0.01
ratio = 0.8
#函数的调用
train_feature, train_label, test_feature, test_label = dataset_open('iris0.txt', ratio)
input_hidden_weight, hidden_bais, hidden_output_weight, output_bais = parameter_proprocess(num_input, num_hidden, num_output, lower, upper)
training(train_feature, train_label, input_hidden_weight, hidden_bais, hidden_output_weight, output_bais, num_iter, step_size)
accuracy = testing(test_feature, test_label, input_hidden_weight, hidden_bais, hidden_output_weight, output_bais)
print(accuracy)