【机器学习】循环神经网络(二)-LSTM示例(keras)国际航空乘客问题的回归问题...

使用 Keras 在 Python 中使用 LSTM 循环神经网络进行时间序列预测

国际航空乘客问题的回归问题

这个文件是一个CSV格式的数据集,它包含了从1949年1月到1960年12月的每个月的国际航空乘客的总数(以千为单位)。第一行是列名,分别是"Month"和"International airline passengers: monthly totals in thousands. Jan 49 ? Dec 60"。第一列是每个月的日期,格式是"年份-月份"。第二列是每个月的乘客总数,单位是千人。这个数据集可以用来训练一个LSTM模型,来预测未来的乘客数量。LSTM是一种循环神经网络,它可以利用长期的时间序列信息来进行预测。

"Month","International airline passengers: monthly totals in thousands. Jan 49 ? Dec 60"
"1949-01",112
"1949-02",118
"1949-03",132
"1949-04",129
"1949-05",121
"1949-06",135
"1949-07",148
"1949-08",148
"1949-09",136
"1949-10",119
"1949-11",104
"1949-12",118
"1950-01",115
"1950-02",126
"1950-03",141
"1950-04",135
"1950-05",125
"1950-06",149
"1950-07",170
"1950-08",170
"1950-09",158
"1950-10",133
"1950-11",114
"1950-12",140
"1951-01",145
"1951-02",150
"1951-03",178
"1951-04",163
"1951-05",172
"1951-06",178
"1951-07",199
"1951-08",199
"1951-09",184
"1951-10",162
"1951-11",146
"1951-12",166
"1952-01",171
"1952-02",180
"1952-03",193
"1952-04",181
"1952-05",183
"1952-06",218
"1952-07",230
"1952-08",242
"1952-09",209
"1952-10",191
"1952-11",172
"1952-12",194
"1953-01",196
"1953-02",196
"1953-03",236
"1953-04",235
"1953-05",229
"1953-06",243
"1953-07",264
"1953-08",272
"1953-09",237
"1953-10",211
"1953-11",180
"1953-12",201
"1954-01",204
"1954-02",188
"1954-03",235
"1954-04",227
"1954-05",234
"1954-06",264
"1954-07",302
"1954-08",293
"1954-09",259
"1954-10",229
"1954-11",203
"1954-12",229
"1955-01",242
"1955-02",233
"1955-03",267
"1955-04",269
"1955-05",270
"1955-06",315
"1955-07",364
"1955-08",347
"1955-09",312
"1955-10",274
"1955-11",237
"1955-12",278
"1956-01",284
"1956-02",277
"1956-03",317
"1956-04",313
"1956-05",318
"1956-06",374
"1956-07",413
"1956-08",405
"1956-09",355
"1956-10",306
"1956-11",271
"1956-12",306
"1957-01",315
"1957-02",301
"1957-03",356
"1957-04",348
"1957-05",355
"1957-06",422
"1957-07",465
"1957-08",467
"1957-09",404
"1957-10",347
"1957-11",305
"1957-12",336
"1958-01",340
"1958-02",318
"1958-03",362
"1958-04",348
"1958-05",363
"1958-06",435
"1958-07",491
"1958-08",505
"1958-09",404
"1958-10",359
"1958-11",310
"1958-12",337
"1959-01",360
"1959-02",342
"1959-03",406
"1959-04",396
"1959-05",420
"1959-06",472
"1959-07",548
"1959-08",559
"1959-09",463
"1959-10",407
"1959-11",362
"1959-12",405
"1960-01",417
"1960-02",391
"1960-03",419
"1960-04",461
"1960-05",472
"1960-06",535
"1960-07",622
"1960-08",606
"1960-09",508
"1960-10",461
"1960-11",390
"1960-12",432


International airline passengers: monthly totals in thousands. Jan 49 ? Dec 60

长短时记忆网络(LSTM)

长短时记忆网络(Long Short-Term Memory network,LSTM网络)是使用通过时间反向传播进行训练的循环神经网络,它克服了梯度消失问题。

因此,它可用于创建大型循环网络,进而可用于解决机器学习中的困难序列问题,并取得最先进的结果。

与神经元不同,LSTM网络通过层连接的记忆块。

一个块具有使其比经典神经元更智能的组件以及用于最近序列的记忆。一个块包含管理块状态和输出的门。块对输入序列进行操作,块内的每个门使用Sigmoid激活单元来控制它是否被触发,从而使块的状态变化和通过块的信息添加成为有条件的。

在一个单元内有三种类型的门:

  • 遗忘门(Forget Gate): 有条件地决定从块中丢弃哪些信息

  • 输入门(Input Gate): 有条件地决定从输入中更新内存状态的哪些值

  • 输出门(Output Gate): 有条件地决定基于输入和块的记忆输出什么

每个单元都像一个小型状态机,其中单元的门具有在训练过程中学到的权重。

您可以看到如何通过LSTM层实现复杂的学习和记忆,并且不难想象如何通过多个这样的层堆叠多层高阶抽象。

1. LSTM网络用于回归 用一个步长预测一个,监督学习数据类型1->1

您可以将问题表述为回归问题。

也就是说,给定本月的乘客数(以千为单位),下个月的乘客数是多少?

您可以编写一个简单的函数将单列数据转换为两列数据集:第一列包含本月(t)的乘客数,第二列包含要预测的下个月(t+1)的乘客数。

用 Python 和 Keras 实现的长短期记忆网络(LSTM)的源代码,用于解决国际航空乘客问题的回归问题。

# 导入所需的模块
import numpy # 用于进行科学计算
import matplotlib.pyplot as plt # 用于进行数据可视化
from pandas import read_csv # 用于读取 CSV 文件
import math # 用于进行数学运算
from keras.models import Sequential # 用于构建顺序模型
from keras.layers import Dense # 用于构建全连接层
from keras.layers import LSTM # 用于构建长短期记忆网络层
from sklearn.preprocessing import MinMaxScaler # 用于进行数据缩放
from sklearn.metrics import mean_squared_error # 用于计算均方误差


"""
用一个步长预测一个,监督学习数据类型1->1
X        Y
112    118
118    132
132    129
129    121
121    135
"""
# 定义一个函数,将数据截取成1->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) # 将输入和输出列表转换为 numpy 数组,并返回


# 定义随机种子,以便重现结果
numpy.random.seed(7)
# 加载数据
dataframe = read_csv('LSTM\\LSTM_Fly\\airline-passengers.csv', usecols=[1], engine='python') # 读取 CSV 文件,只使用第二列(乘客数)的数据
dataset = dataframe.values # 将数据框转换为 numpy 数组
dataset = dataset.astype('float32') # 将数据类型转换为浮点数
# 缩放数据
scaler = MinMaxScaler(feature_range=(0, 1)) # 创建一个数据缩放器,将数据缩放到 0 到 1 的范围
dataset = scaler.fit_transform(dataset) # 对数据集进行缩放,并返回缩放后的数据集
# 分割2/3数据作为训练集,剩余的作为测试集
train_size = int(len(dataset) * 0.67) # 计算训练集的大小,为数据集长度的 2/3
test_size = len(dataset) - train_size # 计算测试集的大小,为数据集长度减去训练集的大小
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:] # 将数据集分割为训练集和测试集,分别为前 2/3 和后 1/3 的数据
# 预测数据步长为1,一个预测一个,1->1
look_back = 1 # 定义预测数据的步长为 1,即用一个数据预测下一个数据
trainX, trainY = create_dataset(train, look_back) # 调用 create_dataset 函数,将训练集转换为 1->1 的监督学习格式,得到训练集的输入和输出
testX, testY = create_dataset(test, look_back) # 调用 create_dataset 函数,将测试集转换为 1->1 的监督学习格式,得到测试集的输入和输出
# 重构输入数据格式 [samples, time steps, features] = [95,1,1]
trainX = numpy.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) # 将训练集的输入重构为三维数组,第一维为样本数,第二维为时间步数,第三维为特征数,分别为 95,1,1
testX = numpy.reshape(testX, (testX.shape[0], 1, testX.shape[1])) # 将测试集的输入重构为三维数组,第一维为样本数,第二维为时间步数,第三维为特征数,分别为 46,1,1
# 构建 LSTM 网络
model = Sequential() # 创建一个顺序模型
model.add(LSTM(4, input_shape=(1, look_back))) # 向模型中添加一个 LSTM 层,设置 LSTM 单元的数量为 4,输入的形状为 (1, 1),即一个时间步,一个特征
model.add(Dense(1)) # 向模型中添加一个全连接层,设置输出的维度为 1,即一个预测值
model.compile(loss='mean_squared_error', optimizer='adam') # 编译模型,设置损失函数为均方误差,优化器为 adam
model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2) # 训练模型,设置迭代次数为 100,批量大小为 1,显示训练过程
# 对训练数据的Y进行预测
trainPredict = model.predict(trainX) # 调用模型的 predict 方法,对训练集的输入进行预测,得到训练集的预测值
# 对测试数据的Y进行预测
testPredict = model.predict(testX) # 调用模型的 predict 方法,对测试集的输入进行预测,得到测试集的预测值
# 对数据进行逆缩放
trainPredict = scaler.inverse_transform(trainPredict) # 调用数据缩放器的 inverse_transform 方法,对训练集的预测值进行逆缩放,得到原始的乘客数
trainY = scaler.inverse_transform([trainY]) # 调用数据缩放器的 inverse_transform 方法,对训练集的输出进行逆缩放,得到原始的乘客数
testPredict = scaler.inverse_transform(testPredict) # 调用数据缩放器的 inverse_transform 方法,对测试集的预测值进行逆缩放,得到原始的乘客数
testY = scaler.inverse_transform([testY]) # 调用数据缩放器的 inverse_transform 方法,对测试集的输出进行逆缩放,得到原始的乘客数
# 计算RMSE误差
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0])) # 调用 sklearn 的 mean_squared_error 函数,计算训练集的真实值和预测值之间的均方误差,然后开平方,得到训练集的均方根误差
print('Train Score: %.2f RMSE' % (trainScore)) # 打印训练集的均方根误差
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0])) # 调用 sklearn 的 mean_squared_error 函数,计算测试集的真实值和预测值之间的均方误差,然后开平方,得到测试集的均方根误差
print('Test Score: %.2f RMSE' % (testScore)) # 打印测试集的均方根误差


# 构造一个和dataset格式相同的数组,共145行,dataset为总数据集,把预测的93行训练数据存进去
trainPredictPlot = numpy.empty_like(dataset) # 创建一个和数据集形状相同的空数组,用于存放训练集的预测值
# 用nan填充数组
trainPredictPlot[:, :] = numpy.nan # 将数组的所有元素填充为 nan
# 将训练集预测的Y添加进数组,从第1位到第95+1位,共95行
trai
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值