Serie storica - Modello LSTM

Ora, abbiamo familiarità con la modellazione statistica sulle serie temporali, ma l'apprendimento automatico è di gran moda in questo momento, quindi è essenziale avere familiarità anche con alcuni modelli di apprendimento automatico. Inizieremo con il modello più popolare nel dominio delle serie temporali: il modello di memoria a lungo termine.

LSTM è una classe di reti neurali ricorrenti. Quindi, prima di poter passare a LSTM, è essenziale comprendere le reti neurali e le reti neurali ricorrenti.

Reti neurali

Una rete neurale artificiale è una struttura a strati di neuroni connessi, ispirata alle reti neurali biologiche. Non è un algoritmo ma combinazioni di vari algoritmi che ci consente di eseguire operazioni complesse sui dati.

Reti neurali ricorrenti

È una classe di reti neurali su misura per gestire i dati temporali. I neuroni di RNN hanno uno stato / memoria cellulare e l'input viene elaborato in base a questo stato interno, che si ottiene con l'aiuto di loop nella rete neurale. Ci sono moduli ricorrenti di strati "tanh" negli RNN che consentono loro di conservare le informazioni. Tuttavia, non per molto tempo, motivo per cui abbiamo bisogno dei modelli LSTM.

LSTM

È un tipo speciale di rete neurale ricorrente in grado di apprendere le dipendenze a lungo termine nei dati. Ciò si ottiene perché il modulo ricorrente del modello ha una combinazione di quattro strati che interagiscono tra loro.

L'immagine sopra mostra quattro livelli di rete neurale in riquadri gialli, operatori puntuali in cerchi verdi, input in cerchi gialli e stato della cella in cerchi blu. Un modulo LSTM ha uno stato cella e tre porte che forniscono loro il potere di apprendere, disimparare o conservare selettivamente le informazioni da ciascuna delle unità. Lo stato della cella in LSTM aiuta le informazioni a fluire attraverso le unità senza essere alterate, consentendo solo poche interazioni lineari. Ogni unità ha un ingresso, un'uscita e una porta dimentica che può aggiungere o rimuovere le informazioni dallo stato della cella. La porta dimentica decide quali informazioni dallo stato della cella precedente devono essere dimenticate per le quali utilizza una funzione sigmoide. La porta di ingresso controlla il flusso di informazioni allo stato corrente della cella utilizzando un'operazione di moltiplicazione puntiforme di "sigmoide" e "tanh" rispettivamente. Infine, il gate di output decide quali informazioni devono essere passate al successivo stato nascosto

Ora che abbiamo compreso il funzionamento interno del modello LSTM, implementiamolo. Per comprendere l'implementazione di LSTM, inizieremo con un semplice esempio: una linea retta. Vediamo se LSTM può apprendere la relazione di una linea retta e prevederla.

Per prima cosa creiamo il set di dati raffigurante una linea retta.

In [402]:

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

Fuori [402]:

[<matplotlib.lines.Line2D at 0x1eab9d3ee10>]

In [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)))

Ora che i dati sono stati creati e suddivisi in training e test. Convertiamo i dati delle serie temporali nella forma di dati di apprendimento supervisionato in base al valore del periodo di ricerca, che è essenzialmente il numero di ritardi visti per prevedere il valore al tempo "t".

Quindi una serie temporale come questa -

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

Quando il periodo di ricerca è 1, viene convertito in -

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

In [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)

In [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))

Ora addestreremo il nostro modello.

Piccoli batch di dati di addestramento vengono mostrati in rete, un'esecuzione di quando i dati di addestramento interi vengono mostrati al modello in batch e viene calcolato l'errore viene chiamata epoca. Le epoche devono essere eseguite finché l'errore non si riduce.

In [ ]:

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')

In [407]:

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

Ora vediamo come sono le nostre previsioni.

In [408]:

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

Fuori [408]:

[<matplotlib.lines.Line2D at 0x1eac792f048>]

Ora, dovremmo provare a modellare un'onda seno o coseno in modo simile. Puoi eseguire il codice indicato di seguito e giocare con i parametri del modello per vedere come cambiano i risultati.

In [409]:

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

Fuori [409]:

[<matplotlib.lines.Line2D at 0x1eac7a0b3c8>]

In [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)))

In [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))

In [ ]:

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')

In [413]:

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

In [415]:

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

Fuori [415]:

[<matplotlib.lines.Line2D at 0x1eac7a1f550>]

Ora sei pronto per passare a qualsiasi set di dati.