📜  时间序列-LSTM模型

📅  最后修改于: 2020-12-10 06:28:06             🧑  作者: Mango


现在,我们已经很熟悉时间序列的统计建模,但是机器学习现在非常流行,因此也必须熟悉某些机器学习模型。我们将从时间序列域中最流行的模型开始-长短期记忆模型。

LSTM是一类递归神经网络。因此,在进入LSTM之前,必须了解神经网络和递归神经网络。

神经网络

人工神经网络是受生物神经网络启发的连接神经元的分层结构。它不是一种算法,而是多种算法的组合,使我们能够对数据进行复杂的操作。

递归神经网络

它是为处理时间数据而量身定制的一类神经网络。 RNN的神经元具有细胞状态/内存,并根据此内部状态处理输入,这是借助神经网络中的循环来实现的。 RNN中有“ tanh”层的重复模块,可让它们保留信息。但是,不是很长一段时间,这就是为什么我们需要LSTM模型。

LSTM

它是一种特殊的循环神经网络,能够学习数据的长期依赖性。之所以能够实现这一目标,是因为模型的重复模块具有相互交互的四层组合。

神经网络

上图显示了黄色方框中的四个神经网络层,绿色圆圈中的点智能运算符,黄色圆圈中的输入,蓝色圆圈中的单元状态。 LSTM模块具有单元状态和三个门,这三个门为它们提供了从每个单元中选择性地学习,取消学习或保留信息的能力。 LSTM中的单元状态仅允许一些线性交互作用,从而使信息流经这些单元而不会被更改。每个单元都有一个输入,输出和一个忘记门,可以将信息添加或删除到单元状态。遗忘门使用S型函数决定应该忘记来自先前电池状态的信息。输入门分别使用“ Sigmoid”和“ tanh”的逐点乘法运算将信息流控制为当前单元状态。最后,输出门决定应将哪些信息传递到下一个隐藏状态

现在我们已经了解了LSTM模型的内部工作原理,让我们实现它。为了理解LSTM的实现,我们将从一个简单的示例开始-一条直线。让我们看看,LSTM是否可以学习直线的关系并对其进行预测。

首先,让我们创建描述直线的数据集。

在[402]中:

x = numpy.arange (1,500,1)
y = 0.4 * x + 30
plt.plot(x,y)

出[402]:

[]

代码段19

在[403]中:

trainx, testx = x[0:int(0.8*(len(x)))], x[int(0.8*(len(x))):]
trainy, testy = y[0:int(0.8*(len(y)))], y[int(0.8*(len(y))):]
train = numpy.array(list(zip(trainx,trainy)))
test = numpy.array(list(zip(trainx,trainy)))

现在已经创建了数据,并将其拆分为训练和测试。让我们根据回溯期的值将时间序列数据转换为监督学习数据的形式,回溯期的值本质上是指可以预测时间“ t”时的滞后次数。

所以这样的时间序列-

time variable_x
t1  x1
t2  x2
 :   :
 :   :
T   xT

当回溯期为1时,转换为-

x1   x2
x2   x3
 :    :
 :    :
xT-1 xT

在[404]中:

def create_dataset(n_X, look_back):
   dataX, dataY = [], []
   for i in range(len(n_X)-look_back):
      a = n_X[i:(i+look_back), ]
      dataX.append(a)
      dataY.append(n_X[i + look_back, ])
   return numpy.array(dataX), numpy.array(dataY)

在[405]中:

look_back = 1
trainx,trainy = create_dataset(train, look_back)
testx,testy = create_dataset(test, look_back)

trainx = numpy.reshape(trainx, (trainx.shape[0], 1, 2))
testx = numpy.reshape(testx, (testx.shape[0], 1, 2))

现在,我们将训练模型。

将小批量的训练数据显示给网络,一次将整个训练数据分批显示给模型并且计算出误差时的一次运行称为时期。直到错误减少的时间段为止。

在[]中:

from keras.models import Sequential
from keras.layers import LSTM, Dense

model = Sequential()
model.add(LSTM(256, return_sequences = True, input_shape = (trainx.shape[1], 2)))
model.add(LSTM(128,input_shape = (trainx.shape[1], 2)))
model.add(Dense(2))
model.compile(loss = 'mean_squared_error', optimizer = 'adam')
model.fit(trainx, trainy, epochs = 2000, batch_size = 10, verbose = 2, shuffle = False)
model.save_weights('LSTMBasic1.h5')

在[407]中:

model.load_weights('LSTMBasic1.h5')
predict = model.predict(testx)

现在,让我们看看我们的预测是什么样的。

在[408]中:

plt.plot(testx.reshape(398,2)[:,0:1], testx.reshape(398,2)[:,1:2])
plt.plot(predict[:,0:1], predict[:,1:2])

出[408]:

[]

代码段22

现在,我们应该尝试以类似方式对正弦波或余弦波建模。您可以运行下面给出的代码,并使用模型参数来查看结果如何变化。

在[409]中:

x = numpy.arange (1,500,1)
y = numpy.sin(x)
plt.plot(x,y)

出[409]:

[]

代码段23

在[410]中:

trainx, testx = x[0:int(0.8*(len(x)))], x[int(0.8*(len(x))):]
trainy, testy = y[0:int(0.8*(len(y)))], y[int(0.8*(len(y))):]
train = numpy.array(list(zip(trainx,trainy)))
test = numpy.array(list(zip(trainx,trainy)))

在[411]中:

look_back = 1
trainx,trainy = create_dataset(train, look_back)
testx,testy = create_dataset(test, look_back)
trainx = numpy.reshape(trainx, (trainx.shape[0], 1, 2))
testx = numpy.reshape(testx, (testx.shape[0], 1, 2))

在[]中:

model = Sequential()
model.add(LSTM(512, return_sequences = True, input_shape = (trainx.shape[1], 2)))
model.add(LSTM(256,input_shape = (trainx.shape[1], 2)))
model.add(Dense(2))
model.compile(loss = 'mean_squared_error', optimizer = 'adam')
model.fit(trainx, trainy, epochs = 2000, batch_size = 10, verbose = 2, shuffle = False)
model.save_weights('LSTMBasic2.h5')

在[413]中:

model.load_weights('LSTMBasic2.h5')
predict = model.predict(testx)

在[415]中:

plt.plot(trainx.reshape(398,2)[:,0:1], trainx.reshape(398,2)[:,1:2])
plt.plot(predict[:,0:1], predict[:,1:2])

出[415]:

[]

代码段23

现在您可以继续使用任何数据集了。