Разберем задачу прогнозирования месячной выручки 50-ти магазинов розничной сети одежды. У нас есть данные по месячным выручкам каждого магазина с января 2022 года по сентябрь 2025 года. Необходимо рассчитать прогноз на период с октября 2025 года по февраль 2027 года. Для решения этой задачи будем использовать библиотеку sktime.
Загрузка и визуализация данных
Библиотека sktime – библиотека для прогнозирования временных рядов. Она использует библиотеку pandas для представления временных рядов: pd.Series для одномерных временных рядов и последовательностей; pd.DataFrame для многомерных временных рядов и последовательностей. Индекс объекта Series и индекс объекта DataFrame используются для представления индекса временного ряда или индекса последовательности.
import numpy as np
import pandas as pd
from time import time
from sktime.utils.plotting import plot_series
from sktime.forecasting.model_selection import temporal_train_test_split
# импортируем класс ForecastingHorizon, задающий горизонт
from sktime.forecasting.base import ForecastingHorizon
# импортируем функцию, вычисляющую метрику качества sMAPE
from sktime.performance_metrics.forecasting import (
mean_absolute_percentage_error,
MeanAbsolutePercentageError)
from sktime.forecasting.arima import ARIMA, AutoARIMA
from sktime.forecasting.exp_smoothing import ExponentialSmoothing
from sktime.forecasting.statsforecast import StatsForecastAutoARIMA
from sktime.forecasting.compose import EnsembleForecaster
from sktime.forecasting.bats import BATS
from sktime.forecasting.fbprophet import Prophet
Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 \
month
2022-01-31 2364488 1036838 3648782 1330480 1668548 2407337 2258058
2022-02-28 1492999 870461 2053257 950569 1062742 1372846 1352454
2022-03-31 2018963 1066751 2749680 1430781 1387147 2403290 2253839
Sh8 Sh9 Sh10 ... Sh42 Sh43 Sh44 \
month ...
2022-01-31 4727988 1569439 2802047 ... 3050872 1114756 4555560
2022-02-28 2559290 1250363 1784248 ... 1869267 883099 2333665
2022-03-31 4159812 1702816 3119833 ... 2148136 1200477 2184147
Sh45 Sh46 Sh47 Sh48 Sh49 Sh50 Sh51
month
2022-01-31 1437763 3284044 2058178 2809661 3661559 2460779 132473028
2022-02-28 957407 1821049 1230815 1562765 1785294 1227001 85571611
2022-03-31 1237669 2493867 1205422 1670421 2530268 2014150 120354786
[3 rows x 51 columns]| Sh51 | |
|---|---|
| month | |
| 2022-01-31 | 132473028 |
| 2022-02-28 | 85571611 |
| 2022-03-31 | 120354786 |
36 9
ForecastingHorizon(['2025-01-31', '2025-02-28', '2025-03-31', '2025-04-30',
'2025-05-31', '2025-06-30', '2025-07-31', '2025-08-31',
'2025-09-30'],
dtype='datetime64[ns]', freq=None, is_relative=False)Здесь мы уже видим абсолютные индексы – конкретные метки времени. Абсолютныйгоризонт, созданный с помощью класса ForecastingHorizon, можно преобразовать вотносительный и наоборот с помощью методов .to_relative() и .to_absolute(). Оба этихпреобразования требуют передачи cutoff в соответствующий метод. Сutoff – этопоследняя временная точка обучающей выборки, отсечка, разделяющая обучающую итестовую выборки.
Переходим непосредственно к прогнозированию.
Библиотека sktime включает целый ряд встроенных прогнозных моделей,
многие из которых связаны с современными пакетами по прогнозированию.
Все прогнозные модели поддерживают единый интерфейс sktime.
Основные классы, которые в настоящее время стабильно поддерживаются:
-классы ExponentialSmoothing, ARIMA, SARIMAX, ThetaForecaster, autoETS,
VAR, VARMAX, VECM из пакета statsmodels;
-класс autoARIMA из пакета pmdarima;
-класс StatsForecastAutoARIMA из пакета statsforecast;
-классы BATS и TBATS из пакета tbats;
-класс PolynomialTrend для прогнозирования трендов;
-класс Prophet, который позволяет использовать библиотеку prophet от
Facebook в формате интерфейса sktime.
Первая модель, которую мы будем использовать, это модель экспоненциальногосглаживания. Библиотека sktime предлагает свой интерфейс для классаExponentialSmoothing библиотеки statsmodels, выполняющего экспоненциальноесглаживание. К нашему набору мы применим экспоненциальное сглаживание смультипликативными трендом и сезонностью. Поскольку у нас месячные данные,
указываем сезонный период (sp) равный 12.# создаем экземпляр класса ExponentialSmoothing, задаем
# мультипликативную тренд и сезонность, sp=12
forecaster = ExponentialSmoothing(trend='mul', seasonal='mul', sp=12)
# задаем абсолютный горизонт прогнозирования
fh = ForecastingHorizon(y_test.index, is_relative=False)
# обучаем модельforecaster.fit(y_train)
# получаем прогнозы
y_pred = forecaster.predict(fh)
# визуализируем прогнозы
plot_series(y_train, y_test, y_pred, labels=['y_train', 'y_test', 'y_pred'])
# вычисляем MAPEer_ex=round(mean_absolute_percentage_error(y_pred, y_test),3)
print(er_ex)
0.091
#Класс StatsForecastAutoARIMA – это автоматически настраиваемыйвариант ARIMA.
# создаем экземпляр класса StatsForecastAutoARIMA,
# в котором реализована модель StatsForecastAutoARIMA
forecaster = StatsForecastAutoARIMA(sp=12)
# обучаем модель
forecaster.fit(y_train)
# получаем прогнозы
y_pred = forecaster.predict(fh)
# визуализируем прогнозы
plot_series(y_train, y_test, y_pred,labels=['y_train', 'y_test', 'y_pred'])
# вычисляем MAPE
er_ar=round(mean_absolute_percentage_error(y_pred, y_test),3)
print(er_ar)
0.105
Классы BATS и TBATS – это еще два алгоритма прогнозирования временных рядов,
которые реализованы в библиотеке sktime в виде оберток над пакетомBATS и TBATS – это акронимы основных компонентов моделей: Trigonometric seasonality, Box-Cox transformation, ARMA errors, Trend and Seasonal components (тригонометрическая сезонность, преобразование Бокса–Кокса, ошибки ARMA, трендовая и сезонная компоненты). Эти алгоритмы позволяют моделировать временные ряды с несколькими сезонностями. Для нашего прогноза используем модель BATS
# создаем экземпляр класса BATS
forecaster = BATS(sp=12, use_trend=True, use_box_cox=False)
# обучаем модель
forecaster.fit(y_train)
# получаем прогнозы
y_pred = forecaster.predict(fh)
# визуализируем прогнозы
plot_series(y_train, y_test, y_pred,labels=['y_train', 'y_test', 'y_pred'])
# вычисляем MAPE
bats_ar=round(mean_absolute_percentage_error(y_pred, y_test),3)
print(bats_ar)0.078Теперь проиллюстрируем работу с классом Prophet, который позволяет использовать библиотеку prophet от Facebook в формате интерфейса sktime.
forecaster = Prophet(# задаем тип сезонности
seasonality_mode='multiplicative',
# задаем количество точек изменения тренда
n_changepoints=4,
# задаем факт наличия/отсутствия годовой сезонности
yearly_seasonality=True,
# задаем факт наличия/отсутствия недельной сезонности
weekly_seasonality=False,
# задаем факт наличия/отсутствия дневной сезонности
daily_seasonality=False)
# обучаем модель
forecaster.fit(y_train)
# получаем прогнозы
y_pred = forecaster.predict(fh)
# визуализируем прогнозы
plot_series(y_train, y_test, y_pred,labels=['y_train', 'y_test', 'y_pred'])
# вычисляем MAPE
er_ph=round(mean_absolute_percentage_error(y_pred, y_test),3)
print(er_ph)
0.077
Выведем ошибки моделей в одной таблице
data = {'Model':['ExponentialSmoothing','StatsForecastAutoARIMA','BATS','Prophet'],
'MAPE':[er_ex,er_ar,er_bats,er_ph]}
df_er=pd.DataFrame(data)
df_er
| Model | MAPE | |
|---|---|---|
| 0 | ExponentialSmoothing | 0.091 |
| 1 | StatsForecastAutoARIMA | 0.105 |
| 2 | BATS | 0.078 |
| 3 | Prophet | 0.077 |
Выполнение первого этапа дало представление об ошибке, которую выдают каждаяиз рассмотренных моделей. Теперь переходим ко второму этапу - прогнозированиюпо всем магазинам.Для того, чтобы с одной стороны получить прогноз по февраль 2027 года, а с другойиметь возможность выбрать этот прогноз из четырех прогнозов опираясь на сравнениеошибок этих прогнозов на фактических данных, задаем горизонт с января 2025 пофевраль 2027 года.
period=pd.date_range('2025-01','2027-03',freq='ME')fh = ForecastingHorizon(period, is_relative=False)
fh
ForecastingHorizon(['2025-01-31', '2025-02-28', '2025-03-31', '2025-04-30', '2025-05-31', '2025-06-30', '2025-07-31', '2025-08-31', '2025-09-30', '2025-10-31', '2025-11-30', '2025-12-31', '2026-01-31', '2026-02-28', '2026-03-31', '2026-04-30', '2026-05-31', '2026-06-30', '2026-07-31', '2026-08-31', '2026-09-30', '2026-10-31', '2026-11-30', '2026-12-31', '2027-01-31', '2027-02-28'], dtype='datetime64[ns]', freq='ME', is_relative=False)Каждый прогноз по четырем моделям будем записывать в файл excel.#ExponentialSmoothing forecaster = ExponentialSmoothing(trend='mul', seasonal='mul', sp=12) forecaster.fit(df) y_pred = forecaster.predict(fh) y_pred.to_excel("fc_ex.xlsx")#StatsForecastAutoARIMA forecaster = StatsForecastAutoARIMA(sp=12) forecaster.fit(df) y_pred = forecaster.predict(fh) y_pred.to_excel("fc_ar.xlsx")#Prophet forecaster = Prophet(seasonality_mode='multiplicative',n_changepoints=4, yearly_seasonality=True,weekly_seasonality=False,daily_seasonality=False) forecaster.fit(df) y_pred = forecaster.predict(fh) y_pred.to_excel("fc_ph.xlsx")#BATS forecaster = BATS(sp=12, use_trend=True, use_box_cox=False) forecaster.fit(df) y_pred = forecaster.predict(fh) y_pred.to_excel("fc_bats.xlsx")После этого собираем все прогнозы в один файл и по каждому магазину в отдельностивыбираем прогноз, который показал наименьшую ошибку за периодянварь-сентябрь 2025.В таблице приведены модели и количество магазинов, по которым был выбраннаилучший прогноз :
| Model | Shops | |
|---|---|---|
| 0 | ExponentialSmoothing | 2 |
| 1 | StatsForecastAutoARIMA | 0 |
| 2 | BATS | 14 |
| 3 | Prophet | 13 |
| 4 | BATS+Prophet | 15 |
| 5 | BATS+ExponentialSmoothing | 6 |
Как видно, модель BATS оказалась самая востребованная, как сама по себе, так и каксреднее с другими моделями. Средняя MAPE по периоду январь-сентябрь 2025составила 7,6% минимальная 2,6% максимальная 16,4%. И что еще хотелось быотметить : MAPE между прогнозом по 51-му магазину (суммарная выручка) исумма отдельно взятых прогнозов составила всего лишь 3,3%.Можно считать такие результаты удовлетворительные и описанная методика сс использованием библиотеки SKTIME может быть применена при планированиивыручек в магазинах, при том, что в качестве базы для прогноза взяты данные задостаточно короткий период, всего 45 месяцев.В этом материале описаны далеко не все возможности библиотеки SKTIME, вследующих статьях разберем скользящее обновление моделей и прогнозов,прогнозирование с использованием экзогенных показателей, перекрестная проверкас расширяющимся или скользящим окном и многое другое.При работе над данной статьей были использованы материалы из книгиГруздева А.В. "Прогнозирование временных рядов ..." ДМК Пресс, 2023.






Комментариев нет:
Отправить комментарий