Vorhersage des nächsten zukünftigen Wertes mit Deep Learning und LSTM
Die Vorhersage der Zukunft mit Deep Learning ist ein heißes Thema. Deshalb möchte ich dieses Thema beherrschen.
Viele Probleme sind zeitabhängig. Wir haben einige Stichproben gesammelt und wollen sie nun verwenden, um den nächsten Wert vorherzusagen. Genau darum geht es in diesem Beitrag. Es geht nicht um die Vorhersage vieler zukünftiger Werte, das ist ein anderes Thema.
Als Anfänger in der Datenwissenschaft arbeite ich einfach einige Beispiele durch, die ich im Internet gefunden habe. Ich ändere die Eingabesequenz und sehe, was passiert. Vielleicht ist das für Sie nützlich. Ich fand die Website 'Machine Learning Mastery' sehr hilfreich. Ich werde mich hauptsächlich auf den folgenden Artikel beziehen: 'How to Develop LSTM Models for Time Series Forecasting', siehe Links unten.
LSTM (Langfristiges Kurzzeitgedächtnis)
LSTM wird verwendet, wenn wir Vorhersagen machen wollen, die zeitbasiert sind. Sie haben einen Datensatz mit Stichproben. Eine Stichprobe kann ein Wert wie der Preis einer Aktie sein, sie kann aber auch der Preis einer Aktie zusammen mit anderen Werten wie der Stimmung in sozialen Netzwerken sein. Das ist etwas völlig anderes als die Vorhersage eines Wertes auf der Grundlage nicht zeitbezogener Werte wie in meinem vorherigen Beitrag "Predicting values using Deep Learning and Keras".
Bei LSTM können wir die Zeitkomponente einbeziehen, aber es ist nicht notwendig. Bei LSTM geht es um die Definition einer zeitlichen Abfolge, nicht um die Zeit selbst.
Univariate vs Multivariate
Es gibt zwei Grundtypen von LSTM.
Univariate Zeitreihen:
- eindimensional
Beispiel1: Verwendung nur des Börsenschlusskurses
Beispiel2: Verwendung nur des Energieverbrauchs
Multivariate Zeitreihen:
- mehrdimensional
Beispiel1: Verwendung des Börsenschlusskurses und z.B. des Eröffnungskurses und der Stimmung in den sozialen Medien
Beispiel2: Verwendung des Energieverbrauchs und der Temperatur
Im Folgenden werde ich sowohl Univariate LSTM als auch Multivariate LSTM anhand von Beispielen untersuchen. Der schwierigste Teil war für mich die Vorbereitung der Daten für das Modell. Als ich das verstanden hatte, konnte ich mich endlich auf die Lösung konzentrieren.
Univariate Zeitreihen: Steigung, nur y verwenden
Ich habe das Beispiel Univariate - Vanilla LSTM auf der Seite 'How to Develop LSTM Models for Time Series Forecasting' (siehe Links unten) durchgearbeitet und mein eigenes Beispiel erstellt, indem ich die Eingabesequenz mithilfe einer Funktion geändert habe:
# 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)
Bereiten Sie die Eingabedaten vor. Wir verwenden die obige Funktion, um einige Stichproben zu erzeugen:
raw_seq = [4, 7, 10, 13, 16, 19]
Wählen Sie die Anzahl der Zeitschritte:
n_steps = 3
Dann wandeln wir diese in Eingaben und Ausgaben um, wie folgt:
[ 4, 7, 10] -> 13
[ 7, 10, 13] -> 16
[10, 13, 16] -> 19
Um den nächsten Wert vorherzusagen, verwenden wir die letzten Eingaben:
[13, 16, 19] -> ?
Die Eingänge und Ausgänge werden umgewandelt in:
X = [
[ 4 7 10]
[ 7 10 13]
[10 13 16]
]
y = [13 16 19]
Und X wird umgeformt in:
reshaped X = [
[ [ 4] [ 7] [10] ]
[ [ 7] [10] [13] ]
[ [10] [13] [16] ]
]
Beachten Sie, dass wir hier nur den nächsten Wert vorhersagen. Der 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))
Und das Ergebnis:
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
Sie können es mit den Modellen Vanilla_LSTM und Stacked_LSTM ausprobieren.
Multivariate Zeitreihen: Steigung, Verwendung von X und y
Auch hier habe ich das Beispiel Multivariate - Multiple Input Series auf der Seite 'How to Develop LSTM Models for Time Series Forecasting' (siehe Links unten) durchgearbeitet und mein eigenes Beispiel erstellt, indem ich die Eingabesequenz mithilfe einer Funktion geändert habe:
# 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)
Bereiten Sie die Eingabedaten vor. Wir verwenden die obige Funktion, um einige Stichproben zu erzeugen:
in_seq = [0 1 2 3 4 5]
out_seq = [ 4 7 10 13 16 19]
Wählen Sie die Anzahl der Zeitschritte:
n_steps = 3
Dann wandeln wir diese in Eingaben und Ausgaben um, wie folgt:
[ [0] [1] [2] ] -> 10
[ [1] [2] [3] ] -> 13
[ [2] [3] [4] ] -> 16
[ [3] [4] [5] ] -> 19
Um den nächsten Wert vorherzusagen, verwenden wir die letzten Eingaben:
[ [ 4] [ 5] [ 6] ] -> ?
Die Eingaben und Ausgaben werden umgewandelt in:
X = [
[ [0] [1] [2] ]
[ [1] [2] [3] ]
[ [2] [3] [4] ]
[ [3] [4] [5] ]
]
y = [10 13 16 19]
Beachten Sie, dass wir hier nur den nächsten Wert vorhersagen. Der 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))
Und das Ergebnis:
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
Sie können es mit den Modellen Vanilla_LSTM und Stacked_LSTM ausprobieren.
Zusammenfassung
Dies war eine völlig andere Erfahrung als die, die im vorherigen Beitrag "Predicting values using Deep Learning and Keras" beschrieben wurde. Es war sehr wichtig, wenn nicht sogar das Wichtigste, zu verstehen, wie man die Daten vorbereitet. Aber dazu gibt es eine hervorragende Dokumentation im Internet.
LSMT ist eine Blackbox, das gefällt mir. Aber es kann eine Menge Datenpunkte (Stichproben) benötigen. Das Wichtigste für mich ist im Moment die Qualität der Vorhersage. Auch ich kann die Zukunft für die nächste Zeiteinheit vorhersagen, aber ich möchte auch die Zukunft für viele weitere Zeiteinheiten vorhersagen. Das wollen wir doch alle, oder? Ich muss noch sehr viel lernen ...
Links / Impressum
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
Mehr erfahren
Deep Learning Machine Learning
Neueste
- Ausblenden der Primärschlüssel der Datenbank UUID Ihrer Webanwendung
- Don't Repeat Yourself (DRY) mit Jinja2
- SQLAlchemy, PostgreSQL, maximale Anzahl von Zeilen pro user
- Anzeige der Werte in den dynamischen Filtern SQLAlchemy
- Sichere Datenübertragung mit Public Key Verschlüsselung und pyNaCl
- rqlite: eine hochverfügbare und distverteilte SQLite -Alternative
Meistgesehen
- Verwendung von Pythons pyOpenSSL zur Überprüfung von SSL-Zertifikaten, die von einem Host heruntergeladen wurden
- Verwendung von UUIDs anstelle von Integer Autoincrement Primary Keys mit SQLAlchemy und MariaDb
- Verbindung zu einem Dienst auf einem Docker -Host von einem Docker -Container aus
- PyInstaller und Cython verwenden, um eine ausführbare Python-Datei zu erstellen
- SQLAlchemy: Verwendung von Cascade Deletes zum Löschen verwandter Objekte
- Flask RESTful API Validierung von Anfrageparametern mit Marshmallow-Schemas