Как построить входные данные для LSTM для многоступенчатого горизонта временного ряда с внешними функциями?

Я пытаюсь использовать LSTM для сохранения прогноза продаж. Вот как выглядят мои исходные данные:

|     Date   | StoreID | Sales | Temperature |  Open   | StoreType |
|------------|---------|-------|-------------|---------|-----------|
| 01/01/2016 |   1     |   0   |      36     |    0    |     1     |
| 01/02/2016 |   1     | 10100 |      42     |    1    |     1     |
| ...
| 12/31/2016 |   1     | 14300 |      39     |    1    |     1     |
| 01/01/2016 |   2     | 25000 |      46     |    1    |     3     |
| 01/02/2016 |   2     | 23700 |      43     |    1    |     3     |
| ...
| 12/31/2016 |   2     | 20600 |      37     |    1    |     3     |
| ...
| 12/31/2016 |   10    | 19800 |      52     |    1    |     2     |

Мне нужно прогнозировать следующие 10-дневные продажи. В этом примере мне нужно будет прогнозировать продажи магазина с 01-01-2017 по 01-10-2017. Я знаю, как использовать другую модель временного ряда или модель регрессии для решения этой проблемы, но я хочу знать, является ли RNN-LSTM хорошим кандидатом для этого.

Я начал с того, что проверил LSTM с помощью only storeID = 1 данных. Если мои данные имеют только дату и продажи. Я построю свой поезд и тренируюсь таким образом (пожалуйста, поправьте меня, если я ошибаюсь):

Window = 20
Horizon = 10

|         trainX                  |          trainY              |
| [Yt-10, Yt-11, Yt-12,...,Yt-29] | [Yt, Yt-1, Yt-2,...,Yt-9]    |
| [Yt-11, Yt-12, Yt-13,...,Yt-30] | [Yt-2, Yt-3, Yt-4,...,Yt-10] |
| [Yt-12, Yt-13, Yt-14,...,Yt-31] | [Yt-3, Yt-4, Yt-5,...,Yt-11] |
...

После изменения двух

trainX.shape
(300, 1, 20)
trainY.shape
(300, 10)

Question1: В этом случае [образцы, временные шаги, функции] = [300, 1, 20]. Это правильно? Или я должен построить образец как [300, 20, 1]?

Question2: Я хочу использовать другую информацию в необработанных данных, таких как Temperature, StoreType и т.д. Как мне создать свои входные данные для LSTM?

Question3: До сих пор мы обсуждали только 1 прогноз магазина, если я хочу прогнозировать для всех магазинов, как мне построить мои входные данные?

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

Ответы

Ответ 1

Недавно я решал аналогичную проблему. В вашем случае:

  • Вход должен иметь форму (300, 20, 1) - потому что у вас есть временные последовательности длины 20 с функцией 1.

  • Вы можете сделать это следующим образом:

    sequential_input = Input(shape=(20, 1))
    feature_input = Input(shape=(feature_nb,))
    lstm_layer = LSTM(lstm_units_1st_layer, return_sequences=True)(sequential_input)
    lstm_layer = LSTM(lstm_units_2nd_layer, return_sequences=True)(lstm_layer)
    ...
    lstm_layer = LSTM(lstm_units_nth_layer, return_sequences=False)(lstm_layer)
    merged = merge([lstm_layer, feature_input], mode='concat')
    blend = Dense(blending_units_1st_layer, activation='relu')(merged)
    blend = Dense(blending_units_2nd_layer, activation='relu')(blend)
    ...
    output = Dense(10)(blend)
    
  • Это самая сложная часть. Я не советую вам прогнозировать несколько магазинов, подавая их в сеть как один вектор функций. Вы можете просто пропустить эту часть и попытаться предсказать разные магазины, используя одну модель или выход постпроцесса, используя, например, некоторые графические модели или PCA на матрице, где строки являются дневными продажами.

UPDATE:

Чтобы иметь дело с несколькими последовательными функциями, вы можете сделать следующее:

    sequential_input = Input(shape=(20, nb_of_sequental_features))
    feature_input = Input(shape=(feature_nb,))
    lstm_layer = LSTM(lstm_units_1st_layer, return_sequences=True)(sequential_input)
    lstm_layer = LSTM(lstm_units_2nd_layer, return_sequences=True)(lstm_layer)
    ...
    lstm_layer = LSTM(lstm_units_nth_layer, return_sequences=False)(lstm_layer)
    merged = merge([lstm_layer, feature_input], mode='concat')
    blend = Dense(blending_units_1st_layer, activation='relu')(merged)
    blend = Dense(blending_units_2nd_layer, activation='relu')(blend)
    ...
    output = Dense(10)(blend)
    model = Model(input=[sequential_input, feature_input], output=output])

В этом случае ваш вход должен состоять из списка из двух таблиц: [sequential_data, features] где sequential_data.shape = (nb_of_examples, timesteps, sequential_features) и features.shape = (nb_of_examples, feature_nb). Поэтому sales или temperature следует хранить в sequential_features и store_type в features.