Добавление информации, специфичной для контекста, в RNN/LSTM в данный момент?

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

У меня есть временной ряд значений, как показано ниже, где я рассматриваю историю продаж:

[
    # Шаг 1
    [ Магазин, День недели, Температура, Продажи],
    # Шаг 2
    [ Магазин, День недели, Температура, Продажи],
    # Шаг 3
    [ Магазин, День недели, Температура, Продажи],
    ...
] -> [Продажи с учетом Магазин, День недели, Температура]

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

Теперь, разумеется, я заранее знаю Магазин, День недели и Температуру, так как же мне это закодировать? Должен ли я пропустить историю через LSTM, а затем добавить текущие признаки (Магазин, День недели, Температура) в конец этой последовательности? Я не совсем понимаю, что делать в данном случае.

На данный момент у меня есть нечто вроде этого:

class LSTM(nn.Module):
    def __init__(
        self,
        input_size,
        day_embedding_size: int = 4,
        days: int = 7
        hidden_size=64,
        num_layers=2,
        dropout=0.2,
    ):
        super(LSTM, self).__init__()

        self.day_embeddings= nn.Embedding(
            num_embeddings=days, embedding_dim=day_embedding_size
        )

        self.hidden_size = hidden_size
        self.num_layers = num_layers

        # LSTM 
        self.lstm = nn.LSTM(
            input_size=input_size + (day_embedding_size- 1),
            hidden_size=hidden_size,
            num_layers=num_layers,
            batch_first=True,
            dropout=dropout,
        )

        # Выход LSTM
        combined_size = hidden_size + 1 + day_embedding_size
        self.combine_layer = nn.Linear(combined_size, hidden_size)

        # Выходные слои
        self.fc1 = nn.Linear(hidden_size, hidden_size // 2)
        self.fc2 = nn.Linear(hidden_size // 2, 1)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(dropout)

    def forward(self, past_sales, next_features):
        batch_size = past_sales.size(0)

        # Извлечение признаков временных рядов из LSTM
        prev_days = past_sales[:, :, 0].long()
        prev_temperatures = past_sales[:, :, 1].unsqueeze(-1)
        prev_sales = past_sales[:, :, 2].unsqueeze(-1)

        # Извлечение текущих признаков
        next_day = next_features[:, 0].long()
        next_temperature = next_features[:, 1].unsqueeze(-1)

        # Получение эмбеддингов дней
        past_day_emb = self.day_embeddings(prev_days )
        next_day_emb = self.day_embeddings(next_day )

        lstm_input = torch.cat([prev_temperatures, past_day_emb , prev_sales ], dim=2)

        # Обработка прошлых данных через LSTM
        h0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(
            past_races.device
        )
        c0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(
            past_races.device
        )

        lstm_out, _ = self.lstm(lstm_input, (h0, c0))
        lstm_last = lstm_out[:, -1, :]

        # Объединение всех признаков
        combined = torch.cat(
            [lstm_last, next_day_emb , next_temperature ],
            dim=1,
        )
        combined = self.relu(self.combine_layer(combined))
        combined = self.dropout(combined)

        # Финальные предсказания
        out = self.relu(self.fc1(combined))
        out = self.fc2(out)
        return out

Как вы можете видеть ниже, я фактически просто использую предыдущую серию через LSTM, а затем соединяю признаки, известные мне на текущем временном шаге (День недели, Температура), чтобы предсказать Продажи на их основе.

Это работает не очень хорошо, и я просто не уверен, что у меня правильная структура.
Что является “стандартным” решением в этом случае?

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

Вопрос, который вы поставили, связан с прогнозированием временных рядов на основе данных о продажах, температуре и дне недели для каждого конкретного магазина. С помощью RNN/LSTM вы стремитесь выявить закономерности, такие как повышенные продажи в выходные или в тёплую погоду, а также учитывать уникальные паттерны различных магазинов. Обратите внимание, что RNN (Recurrent Neural Network) и LSTM (Long Short-Term Memory) широко используются именно для анализа временных рядов благодаря способности учитывать зависимость данных на разных временных интервалах.

Теория

Основная идея LSTM заключается в её способности сохранять долгосрочные зависимости благодаря структуре ячейки памяти. В то время как стандартные RNN страдают от проблемы затухания и взрывного градиента, LSTM предлагает решать эти проблемы с помощью специальных управляющих «дверей» (gates), которые контролируют информационные потоки в соответствии с текущими потребностями модели.

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

Пример

Рассмотрим стандартный подход к такой задаче:

  1. Предобработка данных: Временные ряды, такие как продажи, температура, день недели, необходимо нормализовать или стандартизовать для улучшения сходимости модели. Например, температура может быть переведена в шкалу от 0 до 1.

  2. Архитектура сети: Важно правильно определить размеры скрытых слоев, количество слоев, коэффициенты убывания и т.д. В вашем примере LSTM слоям передано hidden_size=64, однако стоит попробовать увеличить не только этот параметр, но и количество слоев для более сложного моделирования.

  3. Вводной слой: Кодировка категориальных переменных, таких как магазин и день недели, с помощью эмбеддингов — это распространённый и правильный подход. Вы уже применяете векторные представления (эшелонирование) для дней недели, что является хорошей практикой.

  4. Выходной слой: После обработки данных с помощью LSTM часто полезно использовать несколько полносвязных слоев, чтобы дополнительно смешивать и преобразовывать признаки перед окончательным выводом.

Применение

  1. Улучшение кодировки дня недели и магазина: Вы можете задействовать более сложные эмбеддинги, например, объединить эмбеддинги дня недели и конкретного магазина, чтобы захватить уникальные паттерны для каждого магазина в разные дни.

  2. Использование различных архитектур: Попробуйте использовать двухголовую сеть, где одна голова – LSTM – будет работать с временными данными, а вторая голова обработает текущие переменные. Затем можно объединить их перед окончательным линейным слоем.

  3. Тюнинг гиперпараметров: Экспериментируйте с различными размерами скрытого слоя, количеством слоев, а также с различными скоростями обучения и коэффициентами убывания learning rate.

  4. Добавление дополнительных признаков: Подумайте о включении других признаков, таких как праздничные дни, специальные предложения и рекламные акции, которые также могут влиять на продажи.

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

  6. Итеративное улучшение: Постоянно проверяйте модель на новых данных и корректируйте её параметры, чтобы обеспечить адаптацию модели к меняющимся условиям и появлению новых закономерностей.

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

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

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