说明: 1、请按照实验分组完成实验,实验采取线上方式验收,需在1月9 日前完成验收! 2、各小组需在验收之前将实验报告、程序等压缩为一个文件发给 助教!(助教信息会在群里公布) 3、验收之后,各组组长将最终实验报告等发给各班课代表,由各 班课代表在1月12日前统一提交给助教!
文件压缩包命名方式:计科*班+组长+成员名单
公路运量主要包括公路客运量和公路货运量两个方面。据研究,某地区的公
路运量主要与该地区的人口数量、机动车数量和公路面积有关。下面数据表中给出
了某地区公路运量相关数据。
根据相关部门数据,该地区 2010 年和 2011 年的人口数量分别为 73.39 和
75.55 万人,机动车数量分别为 3.9635 和 4.0975 万辆,公路面积将分别为 0.9880
和 1.0268 万平方千米
(1)请利用 BP 神经网络预测该地区 2010 年和 2011 年的公路客运量和公
路货运量。
(2)请利用其他方法预测该地区 2010 年和 2011 年的公路客运量和公路货
运量,并比较神经网络和其他方法的优缺点。
数
#!/usr/bin/python
# coding=utf-8
from numpy import *
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
import time
import xlrd
import sys
from pylab import *
importlib.reload(sys)
matplotlib.rcParams['font.sans-serif']=['Droid Sans Fallback']
def read_xls_file(filename): #读取训练数据
data = xlrd.open_workbook(filename)
sheet1 = data.sheet_by_index(0)
m = sheet1.nrows
n = sheet1.ncols
pop = []
veh = []
roa = []
pas = []
fre = []
for i in range(m):
row_data = sheet1.row_values(i)
if i > 0:
pop.append(row_data[1])
veh.append(row_data[2])
roa.append(row_data[3])
pas.append(row_data[4])
fre.append(row_data[5])
dataMat = np.mat([pop,veh,roa])
labels = np.mat([pas,fre])
dataMat_old = dataMat
labels_old = labels
return dataMat,labels,dataMat_old,labels_old
def read_xls_testfile(filename): #读取测试数据
data = xlrd.open_workbook(filename)
sheet1 = data.sheet_by_index(0)
m = sheet1.nrows
n = sheet1.ncols
pop = []
veh = []
roa = []
for i in range(m):
row_data = sheet1.row_values(i)
if i > 0:
pop.append(row_data[1])
veh.append(row_data[2])
roa.append(row_data[3])
dataMat = np.mat([pop,veh,roa])
return dataMat
def Norm(dataMat,labels): #归一化数据
dataMat_minmax = np.array([dataMat.min(axis=1).T.tolist()[0],dataMat.max(axis=1).T.tolist()[0]]).transpose()
dataMat_Norm = ((np.array(dataMat.T)-dataMat_minmax.transpose()[0])/
(dataMat_minmax.transpose()[1]-dataMat_minmax.transpose()[0])).transpose()
labels_minmax = np.array([labels.min(axis=1).T.tolist()[0],labels.max(axis=1).T.tolist()[0]]).transpose()
labels_Norm = ((np.array(labels.T).astype(float)-labels_minmax.transpose()[0])/
(labels_minmax.transpose()[1]-labels_minmax.transpose()[0])).transpose()
return dataMat_Norm,labels_Norm,dataMat_minmax,labels_minmax
def f(x): #激励函数
return 1/(1+np.exp(-x))
#return (np.exp(x)- np.exp(-x))/(np.exp(x)+np.exp(-x))
def BP(sampleinnorm, sampleoutnorm): #BP算法
maxepochs = 60000 #训练次数
learnrate = 0.030 #学习率
errorfinal = 0.65*10**(-3) #误差
samnum = 20 #样本数目
indim = 3 #输入层神经元个数
outdim = 2 #输出层神经元个数
hiddenunitnum = 3 #隐含层神经元个数
n,m = shape(sampleinnorm)#随机产生权重和偏置
w1 = 0.5*np.random.rand(hiddenunitnum,indim)-0.1
b1 = 0.5*np.random.rand(hiddenunitnum,1)-0.1
w2 = 0.5*np.random.rand(outdim,hiddenunitnum)-0.1
b2 = 0.5*np.random.rand(outdim,1)-0.1
errhistory = []
for i in range(maxepochs):
hiddenout = f((np.dot(w1,sampleinnorm).transpose()+b1.transpose())).transpose()#隐藏层输出
networkout = (np.dot(w2,hiddenout).transpose()+b2.transpose()).transpose()#输出层输出
err = sampleoutnorm - networkout
sse = sum(sum(err**2))/m
errhistory.append(sse)
if sse < errorfinal:
break
delta2 = err
delta1 = np.dot(w2.transpose(),delta2)*hiddenout*(1-hiddenout)
dw2 = np.dot(delta2,hiddenout.transpose())
db2 = np.dot(delta2,np.ones((samnum,1)))
dw1 = np.dot(delta1,sampleinnorm.transpose())
db1 = np.dot(delta1,np.ones((samnum,1)))
w2 += learnrate*dw2
b2 += learnrate*db2
w1 += learnrate*dw1
b1 += learnrate*db1
return errhistory,b1,b2,w1,w2,maxepochs
def show(sampleinnorm,sampleoutminmax,sampleout,errhistory,maxepochs): #图形显示
hiddenout = f((np.dot(w1,sampleinnorm).transpose()+b1.transpose())).transpose()
networkout = (np.dot(w2,hiddenout).transpose()+b2.transpose()).transpose()
diff = sampleoutminmax[:,1]-sampleoutminmax[:,0]
networkout2 = networkout
networkout2[0] = networkout2[0]*diff[0]+sampleoutminmax[0][0]
networkout2[1] = networkout2[1]*diff[1]+sampleoutminmax[1][0]
sampleout = np.array(sampleout)
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
fig,axes = plt.subplots(nrows=2,ncols=1,figsize=(12,10))
line1, = axes[0].plot(networkout2[0],'k',markeredgecolor='b',marker = 'o',markersize=9)
line2, = axes[0].plot(sampleout[0],'g',markeredgecolor='g',marker = 'X',markersize=9)
line3, = axes[0].plot(networkout2[1],'r',markeredgecolor='g',marker = 'o',markersize=9)
line4, = axes[0].plot(sampleout[1],'y',markeredgecolor='b',marker = 'X',markersize=9)
axes[0].legend((line1,line2,line3,line4),(u'客运量预测值',u'客运量真实值',u'货运量预测值',u'货运量真实值'),loc = 'upper left')
axes[0].set_ylabel(u'公路客运量及货运量')
xticks = range(0,22,1)
xtickslabel = range(1990,2012,1)
axes[0].set_xticks(xticks)
axes[0].set_xticklabels(xtickslabel)
axes[0].set_xlabel(u'年份')
axes[0].set_title(u'BP神经网络')
errhistory10 = np.log10(errhistory)
minerr = min(errhistory10)
plt.plot(errhistory10)
axes[1]=plt.gca()
axes[1].set_yticks([-2,-1,0,1,2,minerr])
axes[1].set_yticklabels([u'$10^{-2}$',u'$10^{-1}$',u'$1$',u'$10^{1}$',u'$10^{2}$',str(('%.4f'%np.power(10,minerr)))])
axes[1].set_xlabel(u'训练次数')
axes[1].set_ylabel(u'误差')
axes[1].set_title(u'误差曲线')
plt.show()
plt.close()
return diff, sampleoutminmax
def pre(dataMat,dataMat_minmax,diff,sampleoutminmax,w1,b1,w2,b2): #数值预测
dataMat_test = ((np.array(dataMat.T)-dataMat_minmax.transpose()[0])/
(dataMat_minmax.transpose()[1]-dataMat_minmax.transpose()[0])).transpose()
hiddenout = f((np.dot(w1,dataMat_test).transpose()+b1.transpose())).transpose()
networkout1 = (np.dot(w2,hiddenout).transpose()+b2.transpose()).transpose()
networkout = networkout1
networkout[0] = networkout[0]*diff[0] + sampleoutminmax[0][0]
networkout[1] = networkout[1]*diff[1] + sampleoutminmax[1][0]
print ("2010年预测的公路客运量为:", int(networkout[0][0]),"(万人)")
print ("2010年预测的公路货运量为:", int(networkout[1][0]),"(万吨)")
print ("2011年预测的公路客运量为:", int(networkout[0][1]),"(万人)")
print ("2011年预测的公路货运量为:", int(networkout[1][1]),"(万吨)")
dataMat,labels,dataMat_old,labels_old = read_xls_file('data.xlsx')
dataMat_Norm,labels_Norm, dataMat_minmax, labels_minmax = Norm(dataMat,labels)
err, b1, b2, w1, w2,maxepochs = BP(dataMat_Norm,labels_Norm)
dataMat_test = read_xls_testfile('data_test.xlsx')
diff, sampleoutminmax = show(dataMat_Norm,labels_minmax,labels,err,maxepochs)
pre(dataMat_test,dataMat_minmax,diff, sampleoutminmax ,w1,b1,w2,b2)
import numpy as np
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from pylab import *
def LoadFile(filename):
data = np.loadtxt(filename, delimiter=',', unpack=True, usecols=(0, 1, 2, 3, 4, 5))
x1 = np.transpose(np.array(data[1]))
x2 = np.transpose(np.array(data[2]))
x3 = np.transpose(np.array(data[3]))
y1 = np.transpose(np.array(data[4]))
y2 = np.transpose(np.array(data[5]))
return x1, x2, x3, y1, y2
if __name__ == '__main__':
x1, x2, x3, y1, y2 = LoadFile('data.txt')
num=len(x1) #样本数量
xx0=np.ones(num)
#归一化处理,这里使用线性归一化
xx1=(x1-x1.min())/(x1.max()-x1.min())
xx2=(x2-x2.min())/(x2.max()-x2.min())
xx3=(x3-x3.min())/(x3.max()-x3.min())
#堆叠属性数组,构造属性矩阵
#从(16,)到(16,3),因为新出现的轴是第二个轴所以axis为1
X=np.stack((xx0,xx1,xx2,xx3),axis=1)
#得到形状为一列的数组
Y1=y1.reshape(-1,1)
Y2=y2.reshape(-1,1)
learn_rate=0.001 #设置超参数
iter=1500 #迭代次数
display_step=50 #每50次迭代显示一下效果
#设置模型参数初始值
W1=[[0],
[0],
[0],
[0]]
W2=[[0],
[0],
[0],
[0]]
#训练模型
mse=[]
for i in range(0,iter+1):
#求偏导
dL_dW1=np.matmul(np.transpose(X),np.matmul(X,W1)-Y1) #XT(XW-Y)
#更新模型参数
W1=W1-learn_rate*dL_dW1
#得到估计值
PRED1=np.matmul(X,W1)
#计算损失(均方误差)
Loss1=np.mean(np.square(Y1-PRED1))/2
mse.append(Loss1)
dL_dW2=np.matmul(np.transpose(X),np.matmul(X,W2)-Y2) #XT(XW-Y)
W2=W2-learn_rate*dL_dW2
PRED2=np.matmul(X,W2)
Loss2=np.mean(np.square(Y2-PRED2))/2
mse.append(Loss2)
xxx0=np.ones(1)
xxx1=(73.39-x1.min())/(x1.max()-x1.min())
xxx2=(3.9635-x2.min())/(x2.max()-x2.min())
xxx3=(0.988-x3.min())/(x3.max()-x3.min())
XXX=[1,xxx1,xxx2,xxx3]
print("2010年预测的公路客运量为:%d"%np.round(np.matmul(XXX,W1)),"(万人)")
print("2010年预测的公路货运量为:%d"%np.round(np.matmul(XXX,W2)),"(万吨)")
xxx0=np.ones(1)
xxx1=(75.55-x1.min())/(x1.max()-x1.min())
xxx2=(4.0975-x2.min())/(x2.max()-x2.min())
xxx3=(1.0268-x3.min())/(x3.max()-x3.min())
XXX=[1,xxx1,xxx2,xxx3]
print("2011年预测的公路客运量为:%d"%np.round(np.matmul(XXX,W1)),"(万人)")
print("2011年预测的公路货运量为:%d"%np.round(np.matmul(XXX,W2)),"(万吨)")
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
fig,axes = plt.subplots(nrows=1,ncols=1,figsize=(15,3))
line1, = axes.plot(PRED1,'k',markeredgecolor='b',marker = 'o',markersize=9)
line2, = axes.plot(y1,'g',markeredgecolor='g',marker = 'X',markersize=9)
line3, = axes.plot(PRED2,'r',markeredgecolor='g',marker = 'o',markersize=9)
line4, = axes.plot(y2,'y',markeredgecolor='b',marker = 'X',markersize=9)
axes.legend((line1,line2,line3,line4),(u'客运量预测值',u'客运量真实值',u'货运量预测值',u'货运量真实值'),loc = 'upper left')
axes.set_ylabel(u'公路客运量及货运量')
xticks = range(0,22,1)
xtickslabel = range(1990,2012,1)
axes.set_xticks(xticks)
axes.set_xticklabels(xtickslabel)
axes.set_xlabel(u'年份')
axes.set_title(u'线性回归')
plt.show()
代码细节自己看喔
也可以下载实验报告
工程链接