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

Прогнозирование следующей будущей стоимости с помощью Deep Learning и LSTM

Предсказание будущего с помощью Deep Learning - актуальная тема. Поэтому я хочу освоить ее.

30 января 2022
post main image
https://www.pexels.com/nl-nl/@andrew

Многие проблемы связаны со временем. Мы собрали несколько образцов и теперь хотим использовать их для предсказания следующего значения. Именно об этом и пойдет речь в этом посте. Речь не идет о предсказании множества будущих значений, это другая тема.
Как новичок в области data scientist, я просто прорабатываю некоторые примеры, которые нашел в интернете. Я меняю последовательность входных данных и смотрю, что происходит. Вы можете найти это полезным. Я нашел сайт 'Machine Learning Mastery' очень полезным. В основном я буду ссылаться на следующую статью: 'How to Develop LSTM Models for Time Series Forecasting', см. ссылки ниже.

LSTM (Длинная краткосрочная память)

LSTM используется, когда мы хотим сделать прогнозы, основанные на времени. У вас есть набор данных с образцами. Выборка может быть значением, например, ценой акции, но она также может быть ценой акции вместе с другими значениями, например, настроением в социальной сети. Это совершенно отличается от прогнозирования стоимости на основе значений, не связанных со временем, как в моем предыдущем посте "Predicting values using Deep Learning and Keras".

В LSTM мы можем включить временной компонент, но это не обязательно. LSTM - это определение последовательности во времени, а не самого времени.

Univariate против Multivariate

Существует два основных типа LSTM.

Временной ряд Univariate :

  • одномерный
    Пример1: Используется только цена закрытия фондового рынка
    Пример2: Используется только потребление энергии.

Multivariate Временной ряд:

  • многомерный
    Пример1: использовать цену закрытия фондового рынка и, например, цену открытия и настроения в социальных сетях
    Пример2: использовать потребление энергии и температуру.

Ниже я исследую как Univariate LSTM , так и Multivariate LSTM на примерах. Для меня самой сложной частью было то, как подготовить данные для модели. Как только я понял это, я наконец смог сосредоточиться на решении.

Univariate Временной ряд: наклон, используйте только y

Я проработал пример Univariate - Vanilla LSTM на странице 'How to Develop LSTM Models for Time Series Forecasting', см. ссылки ниже, и создал свой собственный пример, изменив последовательность входных данных с помощью функции:

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

Подготовьте входные данные. Используем приведенную выше функцию для генерации некоторых образцов:

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

Выбираем количество временных шагов:

n_steps = 3

Затем мы преобразуем это во входы и выходы следующим образом:

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

Для прогнозирования следующего значения мы используем последние входные данные:

[13, 16, 19] -> ?

Входы и выходы преобразуются в:

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

А X преобразуется в:

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

Обратите внимание, что здесь мы предсказываем только следующее значение. Код:

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

И результат:

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

Вы можете попробовать это с моделями Vanilla_LSTM и Stacked_LSTM .

Multivariate Временные ряды: наклон, использование X и y

Я снова проработал пример Multivariate - Multiple Input Series на странице "How to Develop LSTM Models for Time Series Forecasting", см. ссылки ниже, и создал свой собственный пример, изменив последовательность входных данных с помощью функции:

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

Подготовьте входные данные. Используем приведенную выше функцию для генерации некоторых образцов:

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

Выбираем количество временных шагов:

n_steps = 3

Затем мы преобразуем это во входы и выходы следующим образом:

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

Для прогнозирования следующего значения мы используем последние входные данные:

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

Входы и выходы преобразуются в:

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

Обратите внимание, что здесь мы предсказываем только следующее значение. Код:

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

И результат:

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

Вы можете попробовать это с моделями Vanilla_LSTM и Stacked_LSTM .

Резюме

Это был совершенно другой опыт по сравнению с тем, который был описан в предыдущем посте "Predicting values using Deep Learning and Keras". Понимание того, как подготовить данные, было очень важным, если не самым важным. Но в интернете есть отличная документация по этому поводу.
LSMT - это черный ящик, мне это нравится. Но ему может понадобиться много точек данных (образцов). Самое важное для меня на данный момент - это качество предсказания. Насколько оно хорошо? Также я могу предсказать будущее на следующую единицу времени, но я также хочу предсказывать будущее на гораздо большее количество единиц времени. Мы все этого хотим, верно? Очень многое еще предстоит узнать...

Ссылки / кредиты

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

Оставить комментарий

Комментируйте анонимно или войдите в систему, чтобы прокомментировать.

Комментарии

Оставьте ответ

Ответьте анонимно или войдите в систему, чтобы ответить.