Как справиться с изменением прогнозируемого значения

Я реализовал модель прогнозирования с использованием 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 очень сложно изучить проблему?

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

VegardKT 10.09.2018 08:50

Код @VegardKT в смысле кода модели или кода, который я использовал для тестирования.?

Sreeram TP 10.09.2018 08:52

оба желательно

VegardKT 10.09.2018 09:20

Ладно. дай мне минуту

Sreeram TP 10.09.2018 09:26

Пока все хорошо, можете ли вы показать, как вы также определяете свои x и y?

VegardKT 10.09.2018 11:56

@VegardKT Я отредактировал свой вопрос

Sreeram TP 10.09.2018 13:14
10
6
2 625
2

Ответы 2

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

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

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

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

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

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

Как я могу справиться с этой проблемой?

Sreeram TP 26.09.2018 06:18

Могут ли помочь в этом сценарии какие-либо типы преобразования или подготовки данных?

Sreeram TP 26.09.2018 07:08

@SreeramTP прогнозируемая метка должна иметь либо унивариантность (сезонность, тренд, цикличность), либо корреляцию по другим характеристикам для прогнозирования будущего; если у нее нет и того, и другого, сеть не может научиться прогнозировать, поэтому она просто следует предыдущим данным, чтобы показать прогноз. пожалуйста, очистите свои данные и выполните необходимую предварительную обработку,

Naga kiran 27.09.2018 07:58

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

Sreeram TP 27.09.2018 08:30

@SreeramTP Я подозреваю, что это неразрешимая проблема. Для LSTM недостаточно сигнала, чтобы учиться, поэтому он просто предсказывает предыдущий временной шаг. Вы можете попробовать более точные функции потерь (например, квадратичную ошибку в кубе), но я предполагаю, что они просто сделают обучение беспорядочным. Вы также можете предсказать распределение по выходам. Например, если вы спрогнозировали среднее значение / logstd для гауссианы, вы сможете увидеть, как прогнозируемые оценки неопределенности меняются с изменчивостью данных.

Alex 27.09.2018 17:11

@Alex, если я смогу собрать данные с более высоким разрешением, это поможет?

Sreeram TP 28.09.2018 11:10

@SreeramTP Поскольку есть больше сигналов, чтобы поучиться, да, но я предполагаю, что это не будет иметь большого значения.

Alex 28.09.2018 16:45

Возможно, сработает более простой метод прогнозирования, чем LSTM. Вы пробовали их? Кроме того, иногда ряд просто невозможно спрогнозировать, и наивный прогноз (то есть простой сдвиг) - лучшее, что вы можете сделать.

Alex Kinman 02.11.2018 21:23

вы просили моей помощи по адресу:

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

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

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

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

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

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

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

Sreeram TP 04.11.2018 17:09

Не могли бы вы поделиться некоторыми методами, которые я могу попытаться удалить?

Sreeram TP 04.11.2018 17:11

1) Не давайте какой-либо функции, несущей непосредственно числовую интуицию, что такое ярлык. 2) Попробуйте использовать нелинейные функции, такие как квадратные корни, квадратные разности и т. д., Вместо того, чтобы вводить непосредственно входные данные. 3) Вы можете указать отношения между функциями (будьте осторожны, чтобы часть делителя не была нулевой или слишком маленькой). 4) Вы можете попытаться предсказать разницу между метками в момент времени t и t-1, а не прогнозировать ее напрямую. Затем вы можете использовать его для создания своего лейбла, обманывая читерского регрессора. Примечание. Создаваемые вами функции должны иметь смысл, вы не можете просто попробовать случайные соотношения; подумайте о шаблонах.

Ugur MULUK 04.11.2018 23:08

Спасибо. Я постараюсь сообщить тебе

Sreeram TP 05.11.2018 11:16

@ user5803658 Я решил эту проблему на своей стороне и разбомбил здесь то, что знаю. Кто-то также дал мне знать, что он / она решил свою / свою проблему с помощью здесь. Однако я не знаю, решил ли владелец вопроса свою проблему.

Ugur MULUK 05.02.2019 18:35

Другие вопросы по теме