Série Temporal - Modelo LSTM
Agora, estamos familiarizados com a modelagem estatística em séries temporais, mas o aprendizado de máquina está na moda agora, por isso é essencial estar familiarizado com alguns modelos de aprendizado de máquina também. Começaremos com o modelo mais popular no domínio das séries temporais - o modelo de Memória de Longo Prazo.
LSTM é uma classe de rede neural recorrente. Portanto, antes de passarmos para o LSTM, é essencial entender as redes neurais e as redes neurais recorrentes.
Redes neurais
Uma rede neural artificial é uma estrutura em camadas de neurônios conectados, inspirada por redes neurais biológicas. Não é um algoritmo, mas combinações de vários algoritmos que nos permitem fazer operações complexas nos dados.
Redes Neurais Recorrentes
É uma classe de redes neurais adaptadas para lidar com dados temporais. Os neurônios do RNN possuem um estado / memória celular, e a entrada é processada de acordo com esse estado interno, que é conseguido com a ajuda de loops na rede neural. Existem módulos recorrentes de camadas 'tanh' nos RNNs que permitem reter informações. No entanto, não por muito tempo, e é por isso que precisamos de modelos LSTM.
LSTM
É um tipo especial de rede neural recorrente, capaz de aprender dependências de dados de longo prazo. Isso é obtido porque o módulo recorrente do modelo possui uma combinação de quatro camadas interagindo entre si.
A imagem acima mostra quatro camadas de rede neural em caixas amarelas, operadores pontuais em círculos verdes, entrada em círculos amarelos e o estado da célula em círculos azuis. Um módulo LSTM tem um estado de célula e três portas que fornecem o poder de aprender, desaprender ou reter seletivamente as informações de cada uma das unidades. O estado da célula em LSTM ajuda a informação a fluir através das unidades sem ser alterada, permitindo apenas algumas interações lineares. Cada unidade tem uma entrada, uma saída e uma porta de esquecimento que pode adicionar ou remover as informações do estado da célula. A porta de esquecimento decide quais informações do estado anterior da célula devem ser esquecidas, pois usa uma função sigmóide. A porta de entrada controla o fluxo de informações para o estado atual da célula usando uma operação de multiplicação pontual de 'sigmóide' e 'tanh', respectivamente. Finalmente, a porta de saída decide quais informações devem ser passadas para o próximo estado oculto
Agora que entendemos o funcionamento interno do modelo LSTM, vamos implementá-lo. Para entender a implementação do LSTM, começaremos com um exemplo simples - uma linha reta. Vejamos se o LSTM pode aprender a relação de uma linha reta e predizê-la.
Primeiro, vamos criar o conjunto de dados que descreve uma linha reta.
Em [402]:
x = numpy.arange (1,500,1)
y = 0.4 * x + 30
plt.plot(x,y)
Fora [402]:
[<matplotlib.lines.Line2D at 0x1eab9d3ee10>]
Em [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)))
Agora que os dados foram criados e divididos em treinar e testar. Vamos converter os dados da série temporal na forma de dados de aprendizagem supervisionada de acordo com o valor do período de lookback, que é essencialmente o número de defasagens que são vistas para prever o valor no tempo 't'.
Então, uma série temporal como esta -
time variable_x
t1 x1
t2 x2
: :
: :
T xT
Quando o período de lookback é 1, é convertido em -
x1 x2
x2 x3
: :
: :
xT-1 xT
Em [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)
Em [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))
Agora vamos treinar nosso modelo.
Pequenos lotes de dados de treinamento são mostrados para a rede, uma execução de quando todos os dados de treinamento são mostrados ao modelo em lotes e o erro é calculado é chamada de época. As épocas devem ser executadas até o momento em que o erro estiver reduzindo.
Dentro [ ]:
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')
Em [407]:
model.load_weights('LSTMBasic1.h5')
predict = model.predict(testx)
Agora vamos ver como são nossas previsões.
Em [408]:
plt.plot(testx.reshape(398,2)[:,0:1], testx.reshape(398,2)[:,1:2])
plt.plot(predict[:,0:1], predict[:,1:2])
Fora [408]:
[<matplotlib.lines.Line2D at 0x1eac792f048>]
Agora, devemos tentar modelar uma onda seno ou cosseno de maneira semelhante. Você pode executar o código fornecido abaixo e brincar com os parâmetros do modelo para ver como os resultados mudam.
Em [409]:
x = numpy.arange (1,500,1)
y = numpy.sin(x)
plt.plot(x,y)
Fora [409]:
[<matplotlib.lines.Line2D at 0x1eac7a0b3c8>]
Em [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)))
Em [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))
Dentro [ ]:
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')
Em [413]:
model.load_weights('LSTMBasic2.h5')
predict = model.predict(testx)
Em [415]:
plt.plot(trainx.reshape(398,2)[:,0:1], trainx.reshape(398,2)[:,1:2])
plt.plot(predict[:,0:1], predict[:,1:2])
Fora [415]:
[<matplotlib.lines.Line2D at 0x1eac7a1f550>]
Agora você está pronto para avançar para qualquer conjunto de dados.