angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Prédire la prochaine valeur future en utilisant Deep Learning et LSTM

Prédire l'avenir avec Deep Learning est un sujet brûlant. C'est pourquoi je veux le maîtriser.

30 janvier 2022
post main image
https://www.pexels.com/nl-nl/@andrew

De nombreux problèmes sont liés au temps. Nous avons collecté quelques échantillons et voulons maintenant les utiliser pour prédire la prochaine valeur. C'est le sujet de cet article. Il ne s'agit pas de prédire de nombreuses valeurs futures, c'est un autre sujet.
En tant que scientifique novice en matière de données, je me contente de travailler sur des exemples trouvés sur Internet. Je change la séquence d'entrée et je vois ce qui se passe. Vous trouverez peut-être cela utile. J'ai trouvé le site Web "Machine Learning Mastery" très utile. Je me référerai principalement à l'article suivant : Comment développer des modèles LSTM pour la prévision des séries chronologiques ", voir les liens ci-dessous.

LSTM (Mémoire à long terme)

LSTM est utilisé lorsque nous voulons faire des prédictions basées sur le temps. Vous avez un ensemble de données avec des échantillons. Un échantillon peut être une valeur comme le prix d'une action, mais il peut aussi être le prix d'une action associé à d'autres valeurs comme le sentiment d'un réseau social. C'est totalement différent de la prédiction d'une valeur basée sur des valeurs non liées au temps, comme dans mon précédent post 'Predicting values using Deep Learning and Keras'.

Avec LSTM , nous pouvons inclure la composante temporelle mais ce n'est pas nécessaire. LSTM a pour but de définir une séquence dans le temps, et non le temps lui-même.

Univariate vs Multivariate

Il existe deux types fondamentaux de LSTM.

Série chronologique Univariate :

  • unidimensionnelle
    Exemple1 : Utiliser uniquement le cours de clôture de la bourse
    Exemple2 : Utiliser uniquement la consommation d'énergie

Multivariate Série chronologique :

  • multidimensionnelle
    Exemple1 : utiliser le cours de clôture de la bourse et par exemple le cours d'ouverture et le sentiment des médias sociaux
    Exemple2 : utiliser la consommation d'énergie et la température

Je vais étudier ci-dessous les deux séries temporelles Univariate LSTM et Multivariate LSTM en utilisant des exemples. Pour moi, la partie la plus difficile était de savoir comment préparer les données pour le modèle. Une fois que j'ai compris cela, j'ai enfin pu me concentrer sur la solution.

Univariate Séries temporelles : pente, utiliser seulement y

J'ai travaillé sur l'exemple Univariate - Vanilla LSTM sur la page 'Comment développer des modèles LSTM pour la prévision des séries temporelles', voir les liens ci-dessous, et j'ai créé mon propre exemple en modifiant la séquence d'entrée à l'aide d'une fonction :

# define input sequence
def fx(x):
    y = 4 + 3*x
    return y

x_end = 6
raw_seq = []
for x in range(0, x_end):
    y = fx(x)
    raw_seq.append(y)

Préparer les données d'entrée. Nous utilisons la fonction ci-dessus pour générer quelques échantillons :

raw_seq = [4, 7, 10, 13, 16, 19]

Choisir le nombre de pas de temps :

n_steps = 3

Puis nous transformons cela en entrées et sorties comme ceci :

[ 4,  7, 10] -> 13
[ 7, 10, 13] -> 16
[10, 13, 16] -> 19

Pour prédire la prochaine valeur, nous utilisons les dernières entrées :

[13, 16, 19] -> ?

Les entrées et les sorties sont converties en :

X = [
  [ 4  7 10]
  [ 7 10 13]
  [10 13 16]
]
y = [13 16 19]

Et X est transformé en :

reshaped X = [
  [ [ 4] [ 7] [10] ]
  [ [ 7] [10] [13] ]
  [ [10] [13] [16] ]
]

Notez que nous ne prédisons que la prochaine valeur ici. Le code :

# Based on the Univariate Vanilla LSTM example from this page:
# How to Develop LSTM Models for Time Series Forecasting
# https://machinelearningmastery.com/how-to-develop-lstm-models-for-time-series-forecasting
#
# input sequence is a slope:
# - y = 4 + 3*x 
# - we are using only y
#
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, LSTM

# split a univariate sequence into samples
def split_sequence(sequence, n_steps):
    X, y = list(), list()
    for i in range(len(sequence)):
        # find the end of this pattern
        end_ix = i + n_steps
        # check if we are beyond the sequence
        if end_ix > len(sequence)-1:
            break
        # gather input and output parts of the pattern
        seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
        X.append(seq_x)
        y.append(seq_y)
    return np.array(X), np.array(y)

# choose a number of time steps
n_steps = 3

# define input sequence
def fx(x):
    y = 4 + 3*x
    return y

x_end = 6
raw_seq = []
for x in range(0, x_end):
    y = fx(x)
    raw_seq.append(y)
print('raw_seq = {}'.format(raw_seq))

# predict data
x_input = raw_seq[-1*n_steps:]
print('x_input = {}'.format(x_input))
y_expected = fx(x_end)
print('y_expected = {}'.format(y_expected))

# split into samples
X, y = split_sequence(raw_seq, n_steps)
print('X = {}'.format(X))
print('y = {}'.format(y))

# reshape from [samples, timesteps] into [samples, timesteps, features]
n_features = 1
print('X.shape[0] = {}'.format(X.shape[0]))
print('X.shape[1] = {}'.format(X.shape[1]))
X = X.reshape((X.shape[0], X.shape[1], n_features))
print('reshaped X = {}'.format(X))

# define model
def get_model(m):
    if m == 'Vanilla_LSTM':
        model = Sequential(name=m)
        model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features)))
        model.add(Dense(1))
        model.compile(optimizer='adam', loss='mse')
    elif m == 'Stacked_LSTM':
        model = Sequential(name=m)
        model.add(LSTM(50, activation='relu', return_sequences=True, input_shape=(n_steps, n_features)))
        model.add(LSTM(50, activation='relu'))
        model.add(Dense(1))
        model.compile(optimizer='adam', loss='mse')
    model.summary()
    return model
#model = get_model('Vanilla_LSTM')
model = get_model('Stacked_LSTM')

# fit model
model.fit(X, y, epochs=200, verbose=0)

# show prediction
x_input = np.array(x_input)
x_input = x_input.reshape((1, n_steps, n_features))
yhat = model.predict(x_input, verbose=0)
print('prediction: for x_input = {}, yhat = {}, y_expected = {}'.format(x_input, yhat, y_expected))

Et le résultat :

raw_seq = [4, 7, 10, 13, 16, 19]
x_input = [13, 16, 19]
y_expected = 22
X = [[ 4  7 10]
 [ 7 10 13]
 [10 13 16]]
y = [13 16 19]
X.shape[0] = 3
X.shape[1] = 3
reshaped X = [[[ 4]
  [ 7]
  [10]]

 [[ 7]
  [10]
  [13]]

 [[10]
  [13]
  [16]]]
Model: "Stacked_LSTM"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 lstm (LSTM)                 (None, 3, 50)             10400     
                                                                 
 lstm_1 (LSTM)               (None, 50)                20200     
                                                                 
 dense (Dense)               (None, 1)                 51        
                                                                 
=================================================================
Total params: 30,651
Trainable params: 30,651
Non-trainable params: 0
_________________________________________________________________
prediction: for x_input = [[[13]
  [16]
  [19]]], yhat = [[21.4401]], y_expected = 22

Vous pouvez l'essayer avec les modèles Vanilla_LSTM et Stacked_LSTM .

Série chronologique Multivariate : pente, utilisation de X et y

J'ai à nouveau travaillé sur l'exemple Multivariate - Séries à entrées multiples sur la page 'Comment développer des modèles LSTM pour la prévision des séries temporelles', voir les liens ci-dessous, et j'ai créé mon propre exemple en modifiant la séquence d'entrée à l'aide d'une fonction :

# define input sequence
def fx(x):
    y = 4 + 3*x
    return y

x_end = 6
in_seq = []
out_seq = []
for x in range(0, x_end):
    y = fx(x)
    in_seq.append(x)
    out_seq.append(y)
in_seq = np.array(in_seq)
out_seq = np.array(out_seq)

Préparer les données d'entrée. Nous utilisons la fonction ci-dessus pour générer quelques échantillons :

in_seq = [0 1 2 3 4 5]
out_seq = [ 4  7 10 13 16 19]

Choisir le nombre de pas de temps :

n_steps = 3

Puis nous transformons cela en entrées et sorties comme ceci :

[ [0] [1] [2] ] -> 10
[ [1] [2] [3] ] -> 13
[ [2] [3] [4] ] -> 16
[ [3] [4] [5] ] -> 19

Pour prédire la prochaine valeur, nous utilisons les dernières entrées :

[ [ 4] [ 5] [ 6] ] -> ?

Les entrées et les sorties sont converties en :

X = [
  [ [0] [1] [2] ]
  [ [1] [2] [3] ]
  [ [2] [3] [4] ]
  [ [3] [4] [5] ]
]
y = [10 13 16 19]

Notez que nous ne prédisons que la prochaine valeur ici. Le code :

# Based on the multivariate LSTM Multiple Input Series example from this page:
# How to Develop LSTM Models for Time Series Forecasting
# https://machinelearningmastery.com/how-to-develop-lstm-models-for-time-series-forecasting
#
# input sequence is a slope:
# - y = 4 + 3*x 
# - we are using both x and y
#
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, LSTM
 
# split a multivariate sequence into samples
def split_sequences(sequences, n_steps):
	X, y = list(), list()
	for i in range(len(sequences)):
		# find the end of this pattern
		end_ix = i + n_steps
		# check if we are beyond the dataset
		if end_ix > len(sequences):
			break
		# gather input and output parts of the pattern
		seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1]
		X.append(seq_x)
		y.append(seq_y)
	return np.array(X), np.array(y)

# choose a number of time steps
n_steps = 4

# define input sequence
def fx(x):
    y = 4 + 3*x
    return y

x_end = 12
in_seq = []
out_seq = []
for x in range(0, x_end):
    y = fx(x)
    in_seq.append(x)
    out_seq.append(y)
in_seq = np.array(in_seq)
out_seq = np.array(out_seq)
print('in_seq = {}'.format(in_seq))
print('out_seq = {}'.format(out_seq))

# convert to [rows, columns] structure
in_seq = in_seq.reshape((len(in_seq), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
print('after convert to [rows, columns]:')
print('in_seq = {}'.format(in_seq))
print('out_seq = {}'.format(out_seq))

# horizontally stack columns
dataset = np.hstack((in_seq, out_seq))
print('dataset = {}'.format(dataset))

# convert into input/output
X, y = split_sequences(dataset, n_steps)
print('X = {}'.format(X))
print('y = {}'.format(y))

# prediction data = last row of dataset
x_input = X[-1]
y_expected = y[-1]

# remove prediction data from dataset
X = X[:-1]
y = y[:-1]
print('X = {}'.format(X))
print('y = {}'.format(y))

# the dataset knows the number of features, e.g. 2
n_features = X.shape[2]
print('n_features = {}'.format(n_features))

# define model
def get_model(m):
    if m == 'Vanilla_LSTM':
        model = Sequential(name=m)
        model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features)))
        model.add(Dense(1))
        model.compile(optimizer='adam', loss='mse')
    elif m == 'Stacked_LSTM':
        model = Sequential(name=m)
        model.add(LSTM(50, activation='relu', return_sequences=True, input_shape=(n_steps, n_features)))
        model.add(LSTM(50, activation='relu'))
        model.add(Dense(1))
        model.compile(optimizer='adam', loss='mse')
    model.summary()
    return model
model = get_model('Vanilla_LSTM')
#model = get_model('Stacked_LSTM')

# fit model
model.fit(X, y, epochs=200, verbose=0)

# show prediction
x_input = x_input.reshape((1, n_steps, n_features))
yhat = model.predict(x_input, verbose=0)
print('prediction: for x_input = {}, yhat = {}, y_expected = {}'.format(x_input, yhat, y_expected))

Et le résultat :

in_seq = [ 0  1  2  3  4  5  6  7  8  9 10 11]
out_seq = [ 4  7 10 13 16 19 22 25 28 31 34 37]
after convert to [rows, columns]:
in_seq = [[ 0]
 [ 1]
 [ 2]
 [ 3]
 [ 4]
 [ 5]
 [ 6]
 [ 7]
 [ 8]
 [ 9]
 [10]
 [11]]
out_seq = [[ 4]
 [ 7]
 [10]
 [13]
 [16]
 [19]
 [22]
 [25]
 [28]
 [31]
 [34]
 [37]]
dataset = [[ 0  4]
 [ 1  7]
 [ 2 10]
 [ 3 13]
 [ 4 16]
 [ 5 19]
 [ 6 22]
 [ 7 25]
 [ 8 28]
 [ 9 31]
 [10 34]
 [11 37]]
X = [[[ 0]
  [ 1]
  [ 2]
  [ 3]]

 [[ 1]
  [ 2]
  [ 3]
  [ 4]]

 [[ 2]
  [ 3]
  [ 4]
  [ 5]]

 [[ 3]
  [ 4]
  [ 5]
  [ 6]]

 [[ 4]
  [ 5]
  [ 6]
  [ 7]]

 [[ 5]
  [ 6]
  [ 7]
  [ 8]]

 [[ 6]
  [ 7]
  [ 8]
  [ 9]]

 [[ 7]
  [ 8]
  [ 9]
  [10]]

 [[ 8]
  [ 9]
  [10]
  [11]]]
y = [13 16 19 22 25 28 31 34 37]
X = [[[ 0]
  [ 1]
  [ 2]
  [ 3]]

 [[ 1]
  [ 2]
  [ 3]
  [ 4]]

 [[ 2]
  [ 3]
  [ 4]
  [ 5]]

 [[ 3]
  [ 4]
  [ 5]
  [ 6]]

 [[ 4]
  [ 5]
  [ 6]
  [ 7]]

 [[ 5]
  [ 6]
  [ 7]
  [ 8]]

 [[ 6]
  [ 7]
  [ 8]
  [ 9]]

 [[ 7]
  [ 8]
  [ 9]
  [10]]]
y = [13 16 19 22 25 28 31 34]
n_features = 1
Model: "Vanilla_LSTM"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 lstm (LSTM)                 (None, 50)                10400     
                                                                 
 dense (Dense)               (None, 1)                 51        
                                                                 
=================================================================
Total params: 10,451
Trainable params: 10,451
Non-trainable params: 0
_________________________________________________________________
prediction: for x_input = [[[ 8]
  [ 9]
  [10]
  [11]]], yhat = [[35.79921]], y_expected = 37

Vous pouvez l'essayer avec les modèles Vanilla_LSTM et Stacked_LSTM .

Résumé

Cette expérience a été totalement différente de celle décrite dans le post précédent 'Predicting values using Deep Learning and Keras'. Comprendre comment préparer les données était très important, si ce n'est le plus important. Mais il existe une excellente documentation sur Internet à ce sujet.
LSMT est une boîte noire, j'aime ça. Mais il peut avoir besoin de beaucoup de points de données (échantillons). La chose la plus importante pour moi à l'heure actuelle est la qualité de la prédiction. Je peux aussi prédire l'avenir pour la prochaine unité de temps, mais je veux aussi prédire l'avenir pour beaucoup plus d'unités de temps. C'est ce que nous voulons tous, n'est-ce pas ? J'ai encore beaucoup à apprendre ...

Liens / crédits

How to Convert a Time Series to a Supervised Learning Problem in Python
https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python

How to Develop LSTM Models for Time Series Forecasting
https://machinelearningmastery.com/how-to-develop-lstm-models-for-time-series-forecasting

How to Use the TimeseriesGenerator for Time Series Forecasting in Keras
https://machinelearningmastery.com/how-to-use-the-timeseriesgenerator-for-time-series-forecasting-in-keras

Understand Keras's RNN behind the scenes with a sin wave example - Stateful and Stateless prediction
https://fairyonice.github.io/Understand-Keras's-RNN-behind-the-scenes-with-a-sin-wave-example.html

Laissez un commentaire

Commentez anonymement ou connectez-vous pour commenter.

Commentaires

Laissez une réponse

Répondez de manière anonyme ou connectez-vous pour répondre.