Работая в компании, которая занимается автоматизацией складских процессов, мы столкнулись с задачей прогнозирования нагрузки на склад. Это классическая задача предсказания временных рядов, в которой, имея достаточно большой объем исторических данных (минимум 1-2 года), нужно спрогнозировать, как эти данные будут меняться в будущем.

Для прогнозирования на короткие промежутки времени (1-3 дня) мы использовали градиентный бустинг (CatBoost), а для предсказания на месяц – статистическую модель SARIMAX. На фоне развития нейросетевых технологий и нейросетей с архитектурой Transformer, мы решили, в качестве эксперимента, попробовать новый подход к решению поставленной задачи. На сегодняшний день существует несколько трансформеров для предсказания временных рядов: Chronos от Amazon, TimesFM от Google, TimeGPT от Nixtla и др. Наш выбор пал на первую модель благодаря возможности запуска на CPU и наличию дополнительных библиотек для более многогранной настройки.

Chronos

Chronos – это нейросетевая модель с архитектурой Trancformer, основанная на другой LLM (T5). Только токеном для предсказания является не слово, а действительное число.Chronos разработали Amazon Science и выложили в открытый доступ в 2024 году. Я не буду вдаваться в подробности архитектуры и детали обучения этой модели. Любопытный читатель может открыть документацию или прочитать ее перевод в этой статье.

В данной статье будет использоваться модель Chronos-bolt, так как это оптимизированная версия базовой модели Chronos, которую можно запускать на центральном процессоре (в отличие от Chronos, который запускается только при наличии GPU).

AutoGluon-TimeSeries

AutoGluon – библиотека AutoML, разработанная AWS AI (Amazon), которая позволяет автоматизировать процесс обучения и выбора модели. В библиотеке есть три крупных модуля: Tabular (табличные данные), Multimodal (документы, изображения) и TimeSeries (временные ряды). В этой статье речь пойдет про третий модуль.

Пройдемся подробно по всем этапам установки и использования библиотеки AutoGluon. Первым шагом нам потребуется установить ее:

pip install autogluon.timeseries

Для прогнозирования временных рядов импортируем нужные модули:

from autogluon.timeseries import TimeSeriesDataFrame, TimeSeriesPredictor

Можно обойтись без TimeSeriesDataFrame, но его удобно использовать для конвертации данных из csv или pd.DataFrame в подходящий под библиотеку формат. Дело в том, что класс TimeSeriesPredictor принимает на вход данные определенного формата. Вот пример "хороших" данных из документации AutoGluon:

Рис. 1. Подходящий формат данных
Рис. 1. Подходящий формат данных
Рис. 2. Подходящий формат данных
Рис. 2. Подходящий формат данных

В документации рассмотрены и другие подходящие форматы исходных данных. Обращаю внимание читателей, что названия столбцов item_id и timestamp обязаны быть именно такими, их нельзя заменить на index, date и др. В свою очередь, название столбца target может быть и другим, но тогда это нужно будет указать при создании объекта TimeSeriesPredictor. В TimeSeriesPredictor на вход можно подавать как данные типа TimeSeriesDataFrame, так и обычный pd.DataFrame, приведенный к одному из форматов, указанных в документации (внутри при обработке данных они все равно будут приведены к типу TimeSeriesDataFrame). Чтобы привести данные типа pd.DataFrame из таблицы на рис. 2 к виду таблицы на рис. 1, удобно воспользоваться функцией pd.melt().

Такой формат данных позволяет предсказывать сразу несколько временных рядов, что очень удобно, если данные собраны в одну таблицу, item_id – это название или категория предсказываемой переменной.

Далее я рассмотрю два способа прогнозирования данных с помощью модели Chronos:

  1. Так называемый zero-shot – просто предсказание без настройки параметров и дообучения.

  2. Chronos with regressor – в библиотеке AutoGluon к модели можно добавить ковариационный регрессор. Это дополнительная регрессионная модель (линейная регрессия, случайный лес или градиентный бустинг), которая на основе каких-то дополнительных признаков может "помочь" уловить основной модели дополнительные зависимости в данных.

Метрики качества

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

  • MAPE – Mean Absolute Percentage Error (средняя абсолютная ошибка в процентах)

  • WQL – Weighted Quantile Loss (взвешенная квантильная метрика)

Метрика MAPE довольно популярна в задачах машинного обучения и, в частности, в задачах прогнозирования временных рядов. Однако часто она не отражает реального соответствия прогноза истинным значениям. Можно подобрать пример, где лучшим прогнозом с точки зрения MAPE будет просто среднее всех значений, но такое предсказание лишено смысла. Поэтому было принято решение рассмотреть и метрику WQL (которая, кстати, автоматически считается в библиотеке AutoGluon). WQL показывает не только ошибку в самих предсказаниях, но и ошибку на уровне квантильного распределения. Иными словами, метрика WQL показывает как хорошо наша модель предсказала распределение исходных данных. Как именно она рассчитывается и почему эффективна, можно почитать здесь.

Построение прогнозов Chronos zero-shot

Непосредственно для построения прогноза необходимо создать объект класса TimeSeriesPredictor – это основной объект для работы с прогнозированием в библиотеке AutoGluon. Все существующие в библиотеке модели – это классы-наследники TimeSeriesPredictor и напрямую их создавать не очень правильно, хотя и возможно.

prediction_length = 51
metric = "WQL"
predictor = TimeSeriesPredictor(
    prediction_length=prediction_length,
    eval_metric = metric,
    freq='D')

prediction_length – длина предсказания (количество предсказываемых токенов)
eval_metric – метрика, по которой будет происходить внутренняя оптимизация модели
freq – частота измерения данных (D – ежедневно, M – ежемесячно и т.д.). Далее нужно обучить на тренировочных данных нашу модель. Причем в отличие от подачи данных в модели классического машинного обучения, здесь df_train – это данные вместе с целевой переменной.

predictor.fit(
    df_train,
    hyperparameters={
        "Chronos":
            {
                "model_path": "bolt_small",
                "device": "cpu"
            }
    },
    enable_ensemble=False,
    time_limit=120)

model_path – "путь" к нужной модели (можно использовать bolt_base или bolt_tiny)
device – настройка запуска, для более быстрого обучения разработчики рекомендуют использовать GPU. Далее перейдем к результатам работы модели.

rc_params = {
    'axes.labelsize': 16,           
    'axes.titlesize': 18,          
   'figure.figsize': (12, 3)}

predictions = predictor.predict(df_train)
predictor.plot(
    data=df,
    predictions=predictions,
    max_history_length=100,
    matplotlib_rc_params = rc_params)
Рис. 3. Прогноз модели Chronos методом zero-shot
Рис. 3. Прогноз модели Chronos методом zero-shot

Метрика

Значение

WQL

0.17061

MAPE

0.17524

Видно, что модель улавливает основной тренд в данных, но на выбросы никак не указывает. И спустя 20-30 шагов предсказывает уже со смещением.

Построение прогнозов Chronos with regressor

Для построения прогноза моделью Chronos совместно с ковариационным регрессором нужно немного дополнить конструктор класса TimeSeriesPredictor.

predictor = TimeSeriesPredictor(
    prediction_length=prediction_length,
    known_covariates_names=["year", "month", "day", "week_day", "week", "is_holiday"],
    eval_metric = metric,
    freq='D')

known_covariates_names – это названия ковариационных переменных, которые регрессор будет использовать в качестве признаков для обучения (можно добавить, например, время года).

regressor = "RF"
predictor.fit(
      df_train,
      hyperparameters={
          "Chronos":
              {
                  "model_path": "bolt_small",
                  "target_scaler": "standard",
                  "covariate_regressor": regressor,
                  "device": "cpu",
                  "model_hyperparameters": {}
              }
      },
      enable_ensemble=False,
      time_limit=120)

target_scaler – метод масштабирования данных (см. документацию)
covariate_regressor – регрессионная модель, предсказания которой также будут учитываться, может быть случайным лесом, линейной регрессией или бустингом ("RF", "LR", "GBM", "CAT", "XGB")
model_hyperparameters – для каждой модели можно отдельно настроить гиперпараметры

predictions = best_predictor.predict(df_train, df_cov)
best_predictor.plot(
    data=df,
    predictions=predictions,
    max_history_length=100,
    matplotlib_rc_params = rc_params)

df_cov – таблица с значениями ковариационных переменных на предсказываемом интервале.

Рис. 4. Прогноз модели Chronos with regressor
Рис. 4. Прогноз модели Chronos with regressor

Метрика

Значение

WQL

0.15444

MAPE

0.15337

Для предсказания данной переменной в качестве дополнительной регрессионной модели наилучший результат показал случайный лес ("RF"). Данная модель намного лучше предсказывает целевую переменную и даже указывает на выбросы в данных. А также, даже спустя большое количество шагов предсказания, угадывает тренд.

Построение прогнозов SARIMAX

А теперь построим прогноз с помощью уже зарекомендовавшей себя статистической модели семейства ARMA, состоящей из двух моделей:

  • AR – авто регрессия, которая, анализируя исторические данные, улавливает тренд

  • MA – скользящее среднее (представление данных в виде суммы среднего и нескольких компонент случайного шума)

Модель SARIMAX дополнительно учитывает сезонность временного ряда (Seasonal), может привести нестационарный ряд к стационарному с помощью конечных разностей (Integrate) и учитывает внешние экзогенные факторы (eXogenous).

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

predictor = TimeSeriesPredictor(
    prediction_length=prediction_length,
    known_covariates_names=["is_holiday"],
    freq='D',
    eval_metric=metric)
predicto.fit(
    df_train,
    hyperparameters={
        'AutoARIMA': {
            'd':1,
            'D':1,
            'max_p': 11,
            'max_q': 11,
            'max_d':3,
            'max_P': 3,
            'max_Q': 3,
            'max_D':3,
            'start_p': 1,
            'start_q': 1,
            'start_P': 1,
            'start_Q': 1,
            'seasonal_period': 7,
            'n_jobs': 4
        },
    },
    time_limit=120)
predictions = predictor.predict(df_train, df_cov_for_sarimax)
predictor.plot(
    data=df,
    predictions=predictions,
    max_history_length=100,
    matplotlib_rc_params = rc_params)
Рис. 5. Прогноз модели SARIMAX
Рис. 5. Прогноз модели SARIMAX

Метрика

Значение

WQL

0.17657

MAPE

0.15958

Легко видеть, что по метрике MAPE модели Chronos with regressor и SARIMAX не сильно отличаются друг от друга. Но если посмотреть на график, то очевидно, что Chronos with regressor предсказал значения временного ряда намного лучше, потому что уловил выбросы и лучше подстроился под недельную сезонность (почти все падения на выходных угаданы с хорошей точностью). И метрика WQL лучше отражает этот факт.

Результаты расчетов для остальных значений

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

Общее рабочее время

MAPE

WQL

Chronos with regressor

0.13589

0.09750

Chronos zero‑shot

0.13944

0.10759

SARIMAX

0.16226

0.13104

Рис. 6. Прогноз общего рабочего времени Chronos with regressor
Рис. 6. Прогноз общего рабочего времени Chronos with regressor
Рис. 7. Прогноз общего рабочего времени Chronos zero-shot
Рис. 7. Прогноз общего рабочего времени Chronos zero-shot
Рис. 8. Прогноз общего рабочего времени SARIMAX
Рис. 8. Прогноз общего рабочего времени SARIMAX

Для данного значения лучшим ковариационным регрессором оказалась модель "LR". Видно, что здесь Chronos with regressor не предсказал выброс, но лучше других моделей подстроился под сезонность, что и показывают метрики.

Масса товаров для отгрузки (фактическая)

MAPE

WQL

Chronos with regressor

0.08738

0.06899

Chronos zero-shot

0.08593

0.06574

SARIMAX

0.08967

0.07469

Рис. 9. Прогноз массы отгрузки Chronos with regressor
Рис. 9. Прогноз массы отгрузки Chronos with regressor
Рис. 10. Прогноз массы отгрузки Chronos zero-shot
Рис. 10. Прогноз массы отгрузки Chronos zero-shot
Рис. 11. Прогноз массы отгрузки SARIMAX
Рис. 11. Прогноз массы отгрузки SARIMAX

Здесь прогноз модели Chronos with regressor выглядит неоднозначно, хотя по метрикам он лучше, чем SARIMAX. Лучшим ковариационным регрессором в этом случае стал "CAT".

В данном случае, возможно, имеет смысл отдельно настроить параметры Chronos и параметры ковариационного регрессора.

Масса товаров для приемки (фактическая)

MAPE

WQL

Chronos with regressor

0.13435

0.12418

Chronos zero-shot

0.11511

0.11438

SARIMAX

0.12443

0.12319

Рис. 12. Прогноз массы приемки Chronos with regressor
Рис. 12. Прогноз массы приемки Chronos with regressor
Рис. 13. Прогноз массы приемки Chronos zero-shot
Рис. 13. Прогноз массы приемки Chronos zero-shot
Рис. 14. Прогноз массы приемки SARIMAX
Рис. 14. Прогноз массы приемки SARIMAX

В этот раз прогноз модели Chronos with regressor с ковариационным регрессором "LR" оказался наихудшим с точки зрения метрик. А вот Chronos zero-shot показал хорошие результаты.

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

Суммарные результаты

SARIMAX

Chronos

Разница

Средняя точность

86.6 %

88.9 %

2.3 %

Наименьшее значение точности

77.0 %

84.7 %

7.7 %

Наибольшее значение точности

94.6 %

94.8 %

0.2 %

Модель Chronos всегда бралась та, у которой лучшие показатели метрики (поэтому для каждой задачи нужно отдельно подбирать гиперпараметры модели). Наиболее значимого результата удалось добиться в повышении наименьшего значения точности, т. е. теперь точность гарантировано не хуже 84.7 % для любого прогноза (на тестовых данных, конечно же, что будет на реальных значениях точно сказать нельзя).

Выводы

Анализируя результаты, можно с уверенностью сказать, что Chronos with regressor из библиотеки AutoGluon – это мощный инструмент прогнозирования временных рядов. Модель самостоятельно улавливает тренд и с помощью дополнительной регрессионной модели может найти в данных дополнительные зависимости. В большинстве случаев Chronos показал себя с лучшей стороны, превосходя по метрикам статистическую модель SARIMAX (в некоторых случаях при помощи регрессора, в некоторых без его помощи).

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

Комментарии (0)


  1. alexhu
    21.09.2025 15:15

    Видится мне, что нагрузка на склад складывается из факторов заготовки, обслуживание оборудования и объёма заказов. Ну так было в правильных книгах, так и на производстве меня учили.