Как обрабатывать сдвиг в прогнозируемой стоимости - PullRequest
0 голосов
/ 10 сентября 2018

Я реализовал модель прогнозирования, используя LSTM в Керасе. Набор данных разделен на 15 минут, и я прогнозирую на 12 будущих шагов.

Модель хорошо справляется с этой задачей. Но есть небольшая проблема с сделанным прогнозом. Это показывает небольшой эффект сдвига. Чтобы получить более четкую картину, см. Прикрепленный ниже рисунок.

enter image description here

Как справиться с этой проблемой.? Как данные должны быть преобразованы для решения такого рода проблем .?

Модель, которую я использовал, приведена ниже

init_lstm = RandomUniform(minval=-.05, maxval=.05)
init_dense_1 = RandomUniform(minval=-.03, maxval=.06)

model = Sequential()

model.add(LSTM(15, input_shape=(X.shape[1], X.shape[2]), kernel_initializer=init_lstm, recurrent_dropout=0.33))

model.add(Dense(1, kernel_initializer=init_dense_1, activation='linear'))

model.compile(loss='mae', optimizer=Adam(lr=1e-4))

history = model.fit(X, y, epochs=1000, batch_size=16, validation_data=(X_valid, y_valid), verbose=1, shuffle=False)

Я сделал такие прогнозы

my_forecasts = model.predict(X_valid, batch_size=16)

Данные временных рядов преобразуются в контролируемые для подачи в LSTM с помощью этой функции

# convert time series into supervised learning problem
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg

super_data = series_to_supervised(data, 12, 1)

Мой временной ряд многовариантный. var2 это то, что мне нужно прогнозировать. Я бросил будущее var1 как

del super_data['var1(t)']

Раздельный поезд и действительный как этот

features = super_data[feat_names]
values = super_data[val_name]

ntest = 3444

train_feats, test_feats = features[0:-n_test], features[-n_test:]
train_vals, test_vals = values [0:-n_test], values [-n_test:]

X, y = train_feats.values, train_vals.values
X = X.reshape(X.shape[0], 1, X.shape[1])

X_valid, y_valid = test_feats .values, test_vals .values
X_valid = X_valid.reshape(X_valid.shape[0], 1, X_valid.shape[1])

Я не сделал данные стационарными для этого прогноза. Я также пытался взять разницу и сделать модель как можно более стационарной, но проблема осталась прежней.

Я также пробовал разные диапазоны масштабирования для скейлера min-max, надеясь, что это может помочь модели. Но прогнозы ухудшаются.

Other Things I have tried

=> Tried other optimizers
=> Tried mse loss and custom log-mae loss functions
=> Tried varying batch_size
=> Tried adding more past timesteps
=> Tried training with sliding window and TimeSeriesSplit

Я понимаю, что модель копирует на нее последнее известное значение, тем самым сводя к минимуму потери настолько хорошо, насколько это возможно

Проверка и потери при обучении остаются достаточно низкими в течение всего процесса обучения. Это заставляет меня задуматься, нужно ли мне придумать новую функцию потерь для этой цели.

Это необходимо? Если да, то на какую функцию потерь я должен идти ??

Я перепробовал все методы, на которые наткнулся. Я не могу найти какой-либо ресурс, который указывает на такого рода проблемы. Это проблема данных.? Это потому, что LSTM очень трудно понять эту проблему?

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Вы попросили мою помощь по адресу:

прогноз акций: модель GRU прогнозирует те же заданные значения вместо будущей цены акций

Надеюсь, не поздно. Что вы можете попробовать, так это то, что вы можете изменить числовую четкость ваших функций . Позвольте мне объяснить:

Аналогично моему ответу в предыдущей теме; алгоритм регрессии будет использовать значение из временного окна, которое вы даете в качестве образца, чтобы минимизировать ошибку. Предположим, вы пытаетесь предсказать цену закрытия BTC в момент времени t. Одна из ваших функций состоит из предыдущих цен закрытия, и вы предоставляете окно временного ряда из последних 20 входных данных от t-20 до t-1. Регрессор, вероятно, научится выбирать значение закрытия на шаге времени t-1 или t-2 или значение закрытия , в этом случае обман. Подумайте так: если цена закрытия составляла 6340 долл. В момент t-1, прогноз 6340 долл. Или что-то близкое в момент времени t + 1 минимизировало бы ошибку при сильнейшем. Но на самом деле алгоритм не изучал никаких шаблонов; он просто копируется, поэтому он в основном ничего не делает, кроме как выполняет свои обязанности по оптимизации.

Подумайте аналогично из моего примера: отклоняя явность, я имею в виду следующее: не указывайте цены закрытия напрямую, а масштабируйте их или не используйте явные цены вообще. Не используйте какие-либо функции, явно показывающие цены закрытия для алгоритма, не используйте open, high, low и т. Д. Для каждого временного шага. Здесь вам нужно проявить творческий подход, спроектировать функции, чтобы избавиться от явных; Вы можете дать квадрат близких различий (регрессор все еще может украсть из прошлого с линейными различиями, с опытом), его отношение к объему. Или, может сделать функции категориальными, оцифровав их таким образом, который имеет смысл использовать. Смысл в том, чтобы не давать прямой интуиции к тому, что она должна предсказывать, а только предоставлять шаблоны для алгоритма, над которым нужно работать.

В зависимости от вашей задачи может быть предложен более быстрый подход. Вы можете выполнить мультиклассовую классификацию, если прогнозируете, какой процент изменений для ваших меток вам достаточно, просто будьте осторожны с ситуациями дисбаланса классов. Если вам достаточно даже колебаний вверх / вниз, вы можете напрямую перейти к бинарной классификации. Проблемы с репликацией или смещением наблюдаются только в регрессионных задачах , если вы не пропускаете данные из обучения в тестовый набор. Если возможно, избавьтесь от регрессии для оконных приложений временных рядов.

Если что-то будет неправильно понято или отсутствует, я буду рядом. Надеюсь, я смогу помочь. Удачи.

0 голосов
/ 26 сентября 2018

Скорее всего, ваш LSTM учится угадывать, какое было его предыдущее входное значение (немного модулированное). Вот почему вы видите «сдвиг».

Допустим, ваши данные выглядят так:

x = [1, 1, 1, 4, 5, 4, 1, 1]

И ваш LSTM научился просто выводить предыдущий ввод для текущего временного шага. Тогда ваш вывод будет выглядеть так:

y = [?, 1, 1, 1, 4, 5, 4, 1]

Поскольку ваша сеть имеет несколько сложных механизмов, она не так проста, но в принципе "сдвиг", который вы видите, вызван этим явлением.

...