Модель LSTM с экзогенными факторами

Вопрос или проблема

У меня есть следующие 3 столбца в моем наборе данных: 1. месяц, 2. день недели, 3. количество.

Я хотел бы прогнозировать будущие значения количества, имея следующие переменные в качестве объясняющих:

  1. One-hot кодирование месяца (12 переменных).
  2. One-hot кодирование дня недели (7 переменных).
  3. Последние 2 лага количества (2 переменные).

Может ли такой анализ поддерживаться моделью LSTM? Я думаю, что мне удалось создать модель LSTM, которая принимает 2 лага в качестве объясняющих переменных, но я не знаю, как добавить 19 экзогенных факторов (из 2 кодировок one-hot) в качестве объясняющих переменных в модель.

Примечание: я использую библиотеку Keras для Python для своей реализации.

Входные данные RNN являются 3D тензорами, т.е.

inputs: 3D тензор с формой [batch, timesteps, feature]

Последние 2 лага означают, что вы рассматриваете timestamps=2. Но вам следует попробовать более длинные последовательности и наблюдать результат.

Вы можете создать свой набор данных как [batch, 1, 20 ] т.е. 7+12+1 [Features] для seq_len=1.

Для более длинной последовательности просто создайте последовательность соответственно т.е. так, как мы создаем обычные временные ряды, например, [0,1,2,3] = [[0,1],[1,2],[2,3]] для seq_len=2.

Игровой код

mon = pd.get_dummies(np.random.randint(0,12,(1000)))
day = pd.get_dummies(np.random.randint(0,7,(1000)))
x = pd.DataFrame(np.random.randint(0,1000,(1000)))
data = pd.concat([x,mon,day], axis=1).to_numpy().reshape(-1,1,20)#seq_len=1, features=20

y = pd.get_dummies(np.random.randint(0,2,(1000)))

model = Sequential()
model.add(layers.GRU(100, return_sequences=True, input_shape=(1, 20)))
model.add(layers.GRU(100, return_sequences=False))
model.add(layers.Dense(1000, activation='relu'))
model.add(layers.Dense(2, activation='softmax'))

model.compile(optimizer="rmsprop", loss="binary_crossentropy", metrics=['accuracy'])
history = model.fit(data, y, epochs=10)

Побочное_замечание – OHE с нейронной сетью может не дать наилучшего результата. Попробуйте добавить слои Embedding перед месяцем / днем. Или используйте другое кодирование, которое дает непрерывный вывод.

Ответ или решение

Конечно, использование модели LSTM (Long Short-Term Memory) с экзогенными факторами для прогнозирования временных рядов — это довольно распространенный подход в области машинного обучения. LSTM — это разновидность рекуррентной нейронной сети (RNN), которая особенно полезна при работе с последовательными данными благодаря своей способности запоминать долгосрочные зависимости. Рассмотрим применение этой модели более детально.

Теория

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

В вашем случае, помимо непосредственно временного ряда количества (quantity), который нужно предсказать, для модели доступны экзогенные факторы в виде one-hot кодированных переменных месяцев и дней недели. Это повышает сложность, но и дает больше информации для построения более точных прогнозов.

Пример

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

Во-первых, необходимо подготовить данные. Вам нужно будет трансформировать ваш набор данных в трехмерный тензор. Это можно сделать путем объединения лагов данных с one-hot кодированными переменными. Формат будет следующим: [batch_size, timesteps, features].

Пример кода для подготовки данных может выглядеть следующим образом:

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import LSTM, Dense
from sklearn.model_selection import train_test_split

# Генерация случайных данных
mon = pd.get_dummies(np.random.randint(1, 13, 1000))  # 12 месяцев
day = pd.get_dummies(np.random.randint(0, 7, 1000))   # 7 дней недели
quantity = np.random.randint(0, 100, 1000)            # случайное количество

# Создание датафрейма
data = pd.concat([pd.DataFrame(quantity), mon, day], axis=1)

# Выборка предыдущих двух лагов
data['prev_quantity_1'] = data[0].shift(1)
data['prev_quantity_2'] = data[0].shift(2)

# Удаление начальных строк с NaN значениями
data = data.dropna()

# Подготовка входных данных
X = data.iloc[:, 1:].values  # Все колонки, кроме первой (целевой)
y = data[0].values           # Целевая переменная

# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Изменение формы данных для LSTM
X_train = X_train.reshape((X_train.shape[0], 1, X_train.shape[1]))
X_test = X_test.reshape((X_test.shape[0], 1, X_test.shape[1]))

# Построение модели
model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')

# Обучение модели
model.fit(X_train, y_train, epochs=200, batch_size=32, verbose=0)

# Оценка модели
mse = model.evaluate(X_test, y_test, verbose=0)
print(f'Mean Squared Error: {mse}')

Применение

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

Использование one-hot кодирования, как упомянуто, является стандартным подходом для категориальных переменных. Однако, как было указано в исходном тексте, добавление слоев embedding может улучшить результаты, превращая категориальные переменные в более компактное многомерное пространство признаков.

Заключение

Использование LSTM с экзогенными факторами — это мощный метод для прогнозирования временных рядов, что особенно актуально для бизнес-задач, требующих учета различных внешних условий. Вы должны помнить, что качество модели очень сильно зависит от качества и объема входных данных, правильного выбора гиперпараметров и алгоритмов обучения. Регулярное тестирование и валидация модели на новых данных также являются неотъемлемыми частями процесса, помогая минимизировать риск переобучения и обеспечить точность прогнозов в реальных сценарах применения.

Оцените материал
Добавить комментарий

Капча загружается...