利用numpy完成波士顿房价预测任务
import numpy as np import json import matplotlib.pyplot as plt
#加载数据 def load_data(): #读入数据 datafile='data/housing.data' data=np.fromfile(datafile,sep=' ') # 每条数据包括14项,其中前面13项是影响因素,第14项是相应的房屋价格中位数 feature_names=['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE','DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] feature_num=len(feature_names) #格式化 data = data.reshape([data.shape[0] // feature_num, feature_num]) print(data.shape) # 将原数据集拆分成训练集和测试集 # 这里使用80%的数据做训练,20%的数据做测试 # 测试集和训练集必须是没有交集的 ratio=0.8 offset=int(data.shape[0]*ratio) training_data=data[:offset] #数据归一化 这样做能使原始数据值反映对总体影响程度,便于梯度下降计算 maximum,minmum,avg=training_data.max(axis=0),training_data.min(axis=0),training_data.sum(axis=0)/training_data.shape[0] for i in range(feature_num): data[:,i]=(data[:,i]-minmum[i])/(maximum[i]-minmum[i]) #重新划分数据集 training_data = data[:offset] test_data=data[offset:] return training_data,test_data #返回测试和训练数据集 class NetWork(object): #神经网络 def __init__(self,num_of_weights): #初始化权重和偏置 # 随机产生w的初始值 # 为了保持程序每次运行结果的一致性, # 此处设置固定的随机数种子 np.random.seed(0) self.w=np.random.randn(num_of_weights,1) self.b=0. def forword(self,x): #前向计算 z=np.dot(x,self.w)+self.b return z def loss(self,z,y): #损失函数 Loss=Σ(y−z)²/n error=z-y num_samples = error.shape[0] cost = error * error cost = np.sum(cost) / num_samples return cost def gradient(self, x, y): #计算梯度 z = self.forword(x) gradient_w = (z - y) * x #推导~~~~ gradient_w = np.mean(gradient_w, axis=0) #对w求和 gradient_w = gradient_w[:, np.newaxis] #[]->[[]] gradient_b = (z - y) #推导~~~~ gradient_b = np.mean(gradient_b) #对b求和 return gradient_w, gradient_b def update(self,gradient_w,gradient_b,eta=0.01):#根据步长更新参数 self.w=self.w-eta*gradient_w self.b=self.b-eta*gradient_b def train(self,training_data,epoch=50,batch_size=10,eta=0.01): #训练 #随机梯度下降,对大样本效果明显 n=len(training_data) losses=[] for epoch_id in range(epoch): # 在每轮迭代开始之前,将训练数据的顺序随机打乱 # 然后再按每次取batch_size条数据的方式取出 np.random.shuffle(training_data) # 将训练数据进行拆分,每个mini_batch包含batch_size条的数据 mini_batches = [training_data[k:k + batch_size] for k in range(0, n, batch_size)] for iter_id, mini_batch in enumerate(mini_batches):#循环batch x = mini_batch[:, :-1] y = mini_batch[:, -1:] z=self.forword(x) #前向计算 L=self.loss(z,y) #损失 gradient_w,gradient_b=self.gradient(x,y)#计算梯度 self.update(gradient_w,gradient_b,eta=eta)#更新 losses.append(L) print('Epoch {:3d} / iter {:3d}, loss = {:.4f}'. format(epoch_id, iter_id, L)) return losses #加载数据 training_data,test_data=load_data() #开始训练 network=NetWork(13) # 启动训练 losses = network.train(training_data, epoch=50, batch_size=100, eta=0.1) # 画出损失函数的变化趋势 plot_x = np.arange(len(losses)) plot_y = np.array(losses) plt.plot(plot_x, plot_y) plt.show()
学习链接 https://www.paddlepaddle.org.cn/tutorials/projectdetail/1515038#anchor-21