LSTM-航班人数预测
郑重声明,文章大部分翻译自: Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras
本文目录:
* 1.导入相应库文件及数据情况
* 2.标准化数据,划分数据
* 3.生成样本
* 4.构建LSTM网络
* 5.查看模型效果
* 6.预测未来的数据
* 7.扩展
数据: 1949到1960共12年,每年12个月的数据,一共 144 个数据,单位是 1000, 原文数据下载在这里
目标: 预测国际航班未来 1 个月的乘客数
1.导入相应库文件及数据情况
- #导入相应的库
- import numpy
- import matplotlib.pyplot as plt
- from pandas import read_csv
- import math
- from keras.models import Sequential
- from keras.layers import Dense
- from keras.layers import LSTM
- from keras.utils import plot_model
- from sklearn.preprocessing import MinMaxScaler
- from sklearn.metrics import mean_squared_error
- from IPython.display import SVG
- from keras.utils.vis_utils import model_to_dot
- #将数据存储为两个矩阵,一个矩阵的ind位置存储t时刻的值,另一个矩阵存储t+1时刻的值
- def create_dataset(dataset, look_back=1):
- dataX, dataY = [], []
- for i in range(len(dataset)-look_back-1):
- a = dataset[i:(i+look_back), 0]
- dataX.append(a)
- dataY.append(dataset[i + look_back, 0])
- return numpy.array(dataX), numpy.array(dataY)
- # fix random seed for reproducibility
- numpy.random.seed(7)
- #读取数据
- dataframe = read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3)
- dataset = dataframe.values
- dataset = dataset.astype('float32')
- #查看数据集
- print('样本中的前面两个数据: \n',dataset[0:2])
- print('整个样本的规模: ',len(dataset))
- plt.plot(dataset)
- plt.show()
输出:
样本中的前面两个数据:
[[112.] [118.]]
整个样本的规模: 144
2.标准化数据,划分数据
- #LSTM对输入数据的规模很敏感,特别是在使用sigmoid(默认)或tanh激活函数时。
- #将数据重新调整到0到1的范围(也称为标准化)可能是一种很好的做法。
- scaler = MinMaxScaler(feature_range=(0, 1))
- dataset = scaler.fit_transform(dataset)
- # 划分训练集与测试集,这里使用67%的原始数据作为训练数据,剩下33%作为测试数据
- train_size = int(len(dataset) * 0.67)
- test_size = len(dataset) - train_size
- train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
- print('划分数据集后的得到的训练数据和测试数据(训练数据未有标签): ',train.shape,test.shape)
输出:
划分数据集后的得到的训练数据和测试数据(训练数据未有标签): (96, 1) (48, 1)
3.生成样本
- # 生成[t,t+look_back]时间间隔和t+look_back时刻的两个矩阵
- look_back = 1
- trainX, trainY = create_dataset(train, look_back)
- testX, testY = create_dataset(test, look_back)
- print(trainX[:2], trainY[:2])
- # 数据被Reshape成 [samples, time steps, features],这是放入LSTM的shape
- trainX = numpy.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
- testX = numpy.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
- 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,也就是基于前一个月份数据预测下一个月份数据.下面我以第一年的数据说明数据划分情况.
当我们基于1个历史数据预测下一个值时,样本划分就像图示的蓝,红框,蓝色框表示输入模型的数据,红色表示希望
模型输出的数据(当然只是希望,会有偏差,后面我们用均方根误差来衡量模型真实输出和这个值的差距).蓝,红框在所有的数据上滑动,得到类似上面的数据划分情况.
当然,你也可以改动这个look_back
这个值,基于历史多少数据来预测下一个数据可以自己设定.
注意:本来训练数据和测试数据分别有96,48个,但是经过这样划分后都减少1个,分别为95,47.这是因为最后一个数据没有标签.但是测试数据没有必要这样分,因为他不需要标签,这里分的意思是利用分到的标签用于计算模型在测试数据上的均方根误差.
4.构建LSTM网络
- #构建LSTM网络
- model = Sequential()
- model.add(LSTM(4, input_shape=(1, look_back)))
- model.add(Dense(1))
- #编译训练LSTM网络
- model.compile(loss='mean_squared_error', optimizer='adam')
- model.fit(trainX, trainY, epochs=50, batch_size=1, verbose=1)
- #打印模型
- model.summary()
- #保存模型
- SVG(model_to_dot(model,show_shapes=True).create(prog='dot', format='svg'))
输出:
- Epoch 1/50
- 95/95 [==============================] - 2s 18ms/step - loss: 0.0406
- Epoch 2/50
- 95/95 [==============================] - 1s 6ms/step - loss: 0.0199
- Epoch 3/50
- 95/95 [==============================] - 1s 6ms/step - loss: 0.0147
- ........后面直到50次省略
- ______________________________________________________________________________________
- Layer (type) Output Shape Param #
- ======================================================================================
- lstm_7 (LSTM) (None, 4) 96
- ______________________________________________________________________________________
- dense_7 (Dense) (None, 1) 5
- ======================================================================================
- Total params: 101
- Trainable params: 101
- Non-trainable params: 0
- ______________________________________________________________________________________
5.查看模型效果
- # 使用已训练的模型进行预测
- trainPredict = model.predict(trainX)
- testPredict = model.predict(testX)
- # 预测的值是[0,1]这样的标准化数据,需要将该值转换回原始值
- trainPredict = scaler.inverse_transform(trainPredict)
- trainY = scaler.inverse_transform([trainY])
- testPredict = scaler.inverse_transform(testPredict)
- testY = scaler.inverse_transform([testY])
- # 计算预测的均方根误差
- trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
- print('Train Score: %.2f RMSE' % (trainScore))
- testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
- print('Test Score: %.2f RMSE' % (testScore))
- # 画图:对训练数据的预测
- trainPredictPlot = numpy.empty_like(dataset)
- trainPredictPlot[:, :] = numpy.nan
- trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
- # 画图:对测试数据的预测
- testPredictPlot = numpy.empty_like(dataset)
- testPredictPlot[:, :] = numpy.nan
- #testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
- testPredictPlot[len(trainPredict)+look_back:len(dataset)-1, :] = testPredict
- # 显示图片
- plt.plot(scaler.inverse_transform(dataset),color='blue',label='Raw data')
- plt.plot(trainPredictPlot,color='red',label='Train process')
- plt.plot(testPredictPlot,color='green',label='Test process')
- #在折线图上显示标签
- leg = plt.legend(loc='best', ncol=1, fancybox=True)
- leg.get_frame().set_alpha(0.5)
- plt.show()
输出:
Train Score: 23.39 RMSE #训练数据的均方根误差
Test Score: 46.92 RMSE #测试数据的均方根误差
蓝色线是原始数据
,红色是训练数据的预测情况
,绿色是测试数据的预测情况
,红色和绿色线越靠近蓝色线,表示模型对数据拟合能力越好.
6.预测未来的数据
最后一个数据集的下一个月情况没有被预测,现把它拿到后进行预测.
- #测试数据的最后一个数据没有预测,这里补上
- finalX = numpy.reshape(test[-1], (1, 1, testX.shape[1]))
- #预测得到标准化数据
- featruePredict = model.predict(finalX)
- #将标准化数据转换为人数
- featruePredict = scaler.inverse_transform(featruePredict)
- #原始数据是1949-1960年的数据,下一个月是1961年1月份
- print('模型预测1961年1月份的国际航班人数是: ',featruePredict)
输出:
模型预测1961年1月份的国际航班人数是: [[430.27188]]
7.扩展
模型有些参数可以自己手动调一下,看看模型在不同参数下的效果(虽然我估计数据量太少,可能调参带来的变化不是很大,但是可以体验调参的过程),下面我就可以调的参数说明:
(1)损失函数现在使用的是
mean_squared_error
,可以调成别的
(2)优化器是adam
,也可以调,甚至对优化器内的参数进行调整(比如学习率)
(3)训练次数是50,可以调低点(因为我看后面模型的损失不下降了)
(4)基于历史多少数据的参数look_back
可调,你可以设置为3,5.....
全部代码可以在这里找到.
LSTM-航班人数预测的更多相关文章
- 用 LSTM 做时间序列预测的一个小例子(转自简书)
问题:航班乘客预测 数据:1949 到 1960 一共 12 年,每年 12 个月的数据,一共 144 个数据,单位是 1000 下载地址 目标:预测国际航班未来 1 个月的乘客数 import nu ...
- 86、使用Tensorflow实现,LSTM的时间序列预测,预测正弦函数
''' Created on 2017年5月21日 @author: weizhen ''' # 以下程序为预测离散化之后的sin函数 import numpy as np import tensor ...
- 矩池云 | 利用LSTM框架实时预测比特币价格
温馨提示:本案例只作为学习研究用途,不构成投资建议. 比特币的价格数据是基于时间序列的,因此比特币的价格预测大多采用LSTM模型来实现. 长期短期记忆(LSTM)是一种特别适用于时间序列数据(或具有时 ...
- Python中利用LSTM模型进行时间序列预测分析
时间序列模型 时间序列预测分析就是利用过去一段时间内某事件时间的特征来预测未来一段时间内该事件的特征.这是一类相对比较复杂的预测建模问题,和回归分析模型的预测不同,时间序列模型是依赖于事件发生的先后顺 ...
- 基于 Keras 用 LSTM 网络做时间序列预测
目录 基于 Keras 用 LSTM 网络做时间序列预测 问题描述 长短记忆网络 LSTM 网络回归 LSTM 网络回归结合窗口法 基于时间步的 LSTM 网络回归 在批量训练之间保持 LSTM 的记 ...
- Tensorflow实例:利用LSTM预测股票每日最高价(一)
RNN与LSTM 这一部分主要涉及循环神经网络的理论,讲的可能会比较简略. 什么是RNN RNN全称循环神经网络(Recurrent Neural Networks),是用来处理序列数据的.在传统的神 ...
- 时间序列深度学习:状态 LSTM 模型预测太阳黑子
目录 时间序列深度学习:状态 LSTM 模型预测太阳黑子 教程概览 商业应用 长短期记忆(LSTM)模型 太阳黑子数据集 构建 LSTM 模型预测太阳黑子 1 若干相关包 2 数据 3 探索性数据分析 ...
- (数据科学学习手札40)tensorflow实现LSTM时间序列预测
一.简介 上一篇中我们较为详细地铺垫了关于RNN及其变种LSTM的一些基本知识,也提到了LSTM在时间序列预测上优越的性能,本篇就将对如何利用tensorflow,在实际时间序列预测任务中搭建模型来完 ...
- 基于 lstm 的股票收盘价预测 -- python
开始导入 MinMaxScaler 时会报错 “from . import _arpack ImportError: DLL load failed: 找不到指定的程序.” (把sklearn更新下) ...
随机推荐
- JAVA堆,栈的区别,用AarrayList、LinkedList自定义栈
大家都知道java模拟机在运行时要开辟空间所以它有特定的五个内存划分: 1.寄存器: 2.本地方法区: 3.方法区: 4.栈内存: 5.堆内存: 但是我们今天来注重讲一下栈和堆 ...
- service mc_start.sh does not support chkconfig
在构建docker镜像时,编写Dockerfile构建镜像时,配置自启动脚本报错,service mc_start.sh does not support chkconfig 添加下面两句到 #!/b ...
- 调用WebService时加入身份验证,以拒绝未授权的访问
众所周知,WebService是为企业需求提供的在线应用服务,其他公司或应用软件能够通过Internet来访问并使用这项在线服务.但在有些时候的某些应用服务不希望被未授权访问,那么此时我们可以一下几种 ...
- linux的scp命令可以在linux服务器之间复制文件和目录
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...
- visualSVN server 安装成功,但是无法连接,url打不开
转自:https://www.oschina.net/question/878142_91825 点击开始–>程序->VisualSVN–>VisuaSVN Server Manag ...
- volatile和锁
让编译器不要将变量缓存到寄存器,而是每次去访问主板上的内存 可见性 对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入 原子性 对任意单个volatile变量的 ...
- nginx日志文件的配置
文章来源 运维公会: nginx日志文件的配置 1.日志介绍 nginx有两种日志,一种是访问日志,一种是错误日志. 访问日志中记录的是客户端对服务器的所有请求. 错误日志中记录的是在访问过程中,因为 ...
- TLS1.3 握手过程特性的整理
1.密码协商 TLS协议中,密码协商的过程中Client在ClientHello中提供四种option 第一:client 支持的加密套件列表,密码套件里面中能出现Client支持的AEAD算法或者H ...
- asp.net 页面按回车就会触发button按钮事件
转载于 https://www.cnblogs.com/anz130/articles/2445830.html 转自:http://space.itpub.net/12639172/viewspac ...
- 使用DateTimeFormatter替换线程不安全的SimpleDateFormat
原文:https://blog.csdn.net/baofeidyz/article/details/81307478 如何让SimpleDateFormat保持安全运行? 方案一 每次都去new这种 ...