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

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.

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

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

Einen Kommentar hinterlassen

Kommentieren Sie anonym oder melden Sie sich zum Kommentieren an.

Kommentare

Eine Antwort hinterlassen

Antworten Sie anonym oder melden Sie sich an, um zu antworten.