博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LSTM-航班人数预测
阅读量:6835 次
发布时间:2019-06-26

本文共 6050 字,大约阅读时间需要 20 分钟。

郑重声明,文章大部分翻译自:


本文目录:

*
*
*
*
*
*
*


数据: 1949到1960共12年,每年12个月的数据,一共 144 个数据,单位是 1000, 原文数据下载在

目标: 预测国际航班未来 1 个月的乘客数

1.导入相应库文件及数据情况

  1. #导入相应的库 

  2. import numpy 

  3. import matplotlib.pyplot as plt 

  4. from pandas import read_csv 

  5. import math 

  6. from keras.models import Sequential 

  7. from keras.layers import Dense 

  8. from keras.layers import LSTM 

  9. from keras.utils import plot_model 

  10. from sklearn.preprocessing import MinMaxScaler 

  11. from sklearn.metrics import mean_squared_error 

  12. from IPython.display import SVG 

  13. from keras.utils.vis_utils import model_to_dot 

  14.  

  15. #将数据存储为两个矩阵,一个矩阵的ind位置存储t时刻的值,另一个矩阵存储t+1时刻的值 

  16. def create_dataset(dataset, look_back=1): 

  17. dataX, dataY = [], [] 

  18. for i in range(len(dataset)-look_back-1): 

  19. a = dataset[i:(i+look_back), 0

  20. dataX.append(a) 

  21. dataY.append(dataset[i + look_back, 0]) 

  22. return numpy.array(dataX), numpy.array(dataY) 

  23.  

  24. # fix random seed for reproducibility 

  25. numpy.random.seed(7

  26.  

  27. #读取数据 

  28. dataframe = read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3

  29. dataset = dataframe.values 

  30. dataset = dataset.astype('float32'

  31.  

  32. #查看数据集 

  33. print('样本中的前面两个数据: \n',dataset[0:2]) 

  34. print('整个样本的规模: ',len(dataset)) 

  35.  

  36. plt.plot(dataset) 

  37. plt.show() 

输出:

样本中的前面两个数据:

[[112.] [118.]]
整个样本的规模: 144

数据
真实数据在月份上的分布


2.标准化数据,划分数据

  1. #LSTM对输入数据的规模很敏感,特别是在使用sigmoid(默认)或tanh激活函数时。 

  2. #将数据重新调整到0到1的范围(也称为标准化)可能是一种很好的做法。 

  3.  

  4. scaler = MinMaxScaler(feature_range=(0, 1)) 

  5. dataset = scaler.fit_transform(dataset) 

  6.  

  7. # 划分训练集与测试集,这里使用67%的原始数据作为训练数据,剩下33%作为测试数据 

  8. train_size = int(len(dataset) * 0.67

  9. test_size = len(dataset) - train_size 

  10. train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:] 

  11. print('划分数据集后的得到的训练数据和测试数据(训练数据未有标签): ',train.shape,test.shape) 

输出:

划分数据集后的得到的训练数据和测试数据(训练数据未有标签): (96, 1) (48, 1)


3.生成样本

  1. # 生成[t,t+look_back]时间间隔和t+look_back时刻的两个矩阵 

  2. look_back = 1 

  3. trainX, trainY = create_dataset(train, look_back) 

  4. testX, testY = create_dataset(test, look_back) 

  5.  

  6. print(trainX[:2], trainY[:2]) 

  7.  

  8. # 数据被Reshape成 [samples, time steps, features],这是放入LSTM的shape 

  9. trainX = numpy.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) 

  10. testX = numpy.reshape(testX, (testX.shape[0], 1, testX.shape[1])) 

  11.  

  12. print('构造得到模型的输入数据(训练数据已有标签trainY): ',trainX.shape,testX.shape) 

输出:

[[0.01544401] #第一个月份数据

[0.02702703]] #第二个月份数据
[0.02702703 0.05405405] #每个样本在模型上的应该得到的输出

构造得到模型的输入数据(训练数据已有标签trainY): (95, 1, 1) (47, 1, 1)


这里解释下数据为什么这样划分?

前面我们已经说明了,我们是基于历史数据预测下一时刻的数据,但是每次依赖多少历史数据,我们没有说.这个例子的参数look_back=1设置说明历史数据是1,也就是基于前一个月份数据预测下一个月份数据.下面我以第一年的数据说明数据划分情况.

enter description here
第一年的数据情况

当我们基于1个历史数据预测下一个值时,样本划分就像图示的蓝,红框,蓝色框表示输入模型的数据,红色表示希望模型输出的数据(当然只是希望,会有偏差,后面我们用均方根误差来衡量模型真实输出和这个值的差距).蓝,红框在所有的数据上滑动,得到类似上面的数据划分情况.

当然,你也可以改动这个look_back这个值,基于历史多少数据来预测下一个数据可以自己设定.

注意:本来训练数据和测试数据分别有96,48个,但是经过这样划分后都减少1个,分别为95,47.这是因为最后一个数据没有标签.但是测试数据没有必要这样分,因为他不需要标签,这里分的意思是利用分到的标签用于计算模型在测试数据上的均方根误差.


4.构建LSTM网络

  1. #构建LSTM网络 

  2. model = Sequential() 

  3. model.add(LSTM(4, input_shape=(1, look_back))) 

  4. model.add(Dense(1)) 

  5.  

  6. #编译训练LSTM网络 

  7. model.compile(loss='mean_squared_error', optimizer='adam'

  8. model.fit(trainX, trainY, epochs=50, batch_size=1, verbose=1

  9.  

  10. #打印模型 

  11. model.summary() 

  12.  

  13. #保存模型 

  14. SVG(model_to_dot(model,show_shapes=True).create(prog='dot', format='svg')) 

输出:

  1. Epoch 1/50 

  2. 95/95 [==============================] - 2s 18ms/step - loss: 0.0406 

  3. Epoch 2/50 

  4. 95/95 [==============================] - 1s 6ms/step - loss: 0.0199 

  5. Epoch 3/50 

  6. 95/95 [==============================] - 1s 6ms/step - loss: 0.0147 

  7. ........后面直到50次省略 

  8.  

  9. ______________________________________________________________________________________ 

  10. Layer (type) Output Shape Param #  

  11. ====================================================================================== 

  12. lstm_7 (LSTM) (None, 4) 96  

  13. ______________________________________________________________________________________ 

  14. dense_7 (Dense) (None, 1) 5  

  15. ====================================================================================== 

  16. Total params: 101 

  17. Trainable params: 101 

  18. Non-trainable params: 0 

  19. ______________________________________________________________________________________ 

enter description here
模型图示


5.查看模型效果

  1. # 使用已训练的模型进行预测 

  2. trainPredict = model.predict(trainX) 

  3. testPredict = model.predict(testX) 

  4.  

  5. # 预测的值是[0,1]这样的标准化数据,需要将该值转换回原始值 

  6. trainPredict = scaler.inverse_transform(trainPredict) 

  7. trainY = scaler.inverse_transform([trainY]) 

  8. testPredict = scaler.inverse_transform(testPredict) 

  9. testY = scaler.inverse_transform([testY]) 

  10.  

  11.  

  12. # 计算预测的均方根误差 

  13. trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0])) 

  14. print('Train Score: %.2f RMSE' % (trainScore)) 

  15. testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0])) 

  16. print('Test Score: %.2f RMSE' % (testScore)) 

  17.  

  18. # 画图:对训练数据的预测 

  19. trainPredictPlot = numpy.empty_like(dataset) 

  20. trainPredictPlot[:, :] = numpy.nan 

  21. trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict 

  22.  

  23.  

  24. # 画图:对测试数据的预测 

  25. testPredictPlot = numpy.empty_like(dataset) 

  26. testPredictPlot[:, :] = numpy.nan 

  27. #testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict 

  28. testPredictPlot[len(trainPredict)+look_back:len(dataset)-1, :] = testPredict 

  29.  

  30. # 显示图片 

  31. plt.plot(scaler.inverse_transform(dataset),color='blue',label='Raw data'

  32. plt.plot(trainPredictPlot,color='red',label='Train process'

  33. plt.plot(testPredictPlot,color='green',label='Test process'

  34.  

  35. #在折线图上显示标签 

  36. leg = plt.legend(loc='best', ncol=1, fancybox=True

  37. leg.get_frame().set_alpha(0.5

  38.  

  39. plt.show() 

输出:

Train Score: 23.39 RMSE #训练数据的均方根误差

Test Score: 46.92 RMSE #测试数据的均方根误差

enter description here
模型效果图示

蓝色线是原始数据,红色训练数据的预测情况,绿色测试数据的预测情况,红色和绿色线越靠近蓝色线,表示模型对数据拟合能力越好.


6.预测未来的数据

最后一个数据集的下一个月情况没有被预测,现把它拿到后进行预测.

  1. #测试数据的最后一个数据没有预测,这里补上 

  2. finalX = numpy.reshape(test[-1], (1, 1, testX.shape[1])) 

  3.  

  4. #预测得到标准化数据 

  5. featruePredict = model.predict(finalX) 

  6.  

  7. #将标准化数据转换为人数 

  8. featruePredict = scaler.inverse_transform(featruePredict) 

  9.  

  10. #原始数据是1949-1960年的数据,下一个月是1961年1月份 

  11. print('模型预测1961年1月份的国际航班人数是: ',featruePredict) 

输出:

模型预测1961年1月份的国际航班人数是: [[430.27188]]


7.扩展

模型有些参数可以自己手动调一下,看看模型在不同参数下的效果(虽然我估计数据量太少,可能调参带来的变化不是很大,但是可以体验调参的过程),下面我就可以调的参数说明:

(1)损失函数现在使用的是mean_squared_error,可以调成别的

(2)优化器是adam,也可以调,甚至对优化器内的参数进行调整(比如学习率)
(3)训练次数是50,可以调低点(因为我看后面模型的损失不下降了)
(4)基于历史多少数据的参数look_back可调,你可以设置为3,5.....

全部代码可以在找到.

转载于:https://www.cnblogs.com/wushaogui/p/9051958.html

你可能感兴趣的文章
我的第一天
查看>>
SGU 164.Airline(结论题)
查看>>
findlibrary returned null
查看>>
scala学习手记28 - Execute Around模式
查看>>
Filebeat的工作原理
查看>>
Elasticsearch配置文件详解
查看>>
Java虚拟机学习 - 查看JVM参数及值的命令行工具
查看>>
Ubiquitous Religions(friends变形)
查看>>
机器学习——聚类分析和主成分分析
查看>>
Win10上 visual studio设置为本地IIS运行网站时 必须以管理员身份加载项目的解决方法...
查看>>
记录常见的HTTP请求错误
查看>>
Java字符串替换函数replace、replaceFirst、replaceAll
查看>>
Ubuntu下搭建Android开发环境
查看>>
汇编指令
查看>>
yum安装mysql后root用户的临时密码
查看>>
mysql 原理~ 乐观锁和悲观锁
查看>>
策略模式
查看>>
neo4j使用
查看>>
MVC WebAPI 的基本使用
查看>>
Oracle 字符集的查看和修改
查看>>