Добро пожаловать на курс «Анализ данных и статистика в розничной торговле одеждой на Python: от данных к управленческому решению».
Представьте, что вы пришли работать аналитиком в розничную сеть из 50 магазинов одежды.
Добро пожаловать на курс «Анализ данных и статистика в розничной торговле одеждой на Python: от данных к управленческому решению».
Представьте, что вы пришли работать аналитиком в розничную сеть из 50 магазинов одежды.
Разберем задачу прогнозирования месячной выручки 50-ти магазинов розничной сети одежды. У нас есть данные по месячным выручкам каждого магазина с января 2022 года по сентябрь 2025 года. Необходимо рассчитать прогноз на период с октября 2025 года по февраль 2027 года. Для решения этой задачи будем использовать библиотеку sktime.
Загрузка и визуализация данных
Библиотека sktime – библиотека для прогнозирования временных рядов. Она использует библиотеку pandas для представления временных рядов: pd.Series для одномерных временных рядов и последовательностей; pd.DataFrame для многомерных временных рядов и последовательностей. Индекс объекта Series и индекс объекта DataFrame используются для представления индекса временного ряда или индекса последовательности.
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 |
Будем решать нашу основную задачу в два этапа : на первом этапе мы разобьем наши
данные на обучающую и тестовую части и с помощью четырех методов
прогнозирования сделаем прогнозы и оценим их точность,
на втором этапе мы обучим наши модели на всех наших данных, но сделаем прогноз
в том числе на период, по которому у нас есть фактические данные, что даст нам
возможность выбрать прогноз, который покажет наилучшую точность на фактических
данных. Конкретно это будет выглядеть так : обучаем модели на всех 45 месяцах,
с января 2022 по сентябрь 2025 и делаем прогноз на период с января 2025 по
февраль 2027 и по точности за период с января 2025 по сентябрь 2025 выберем
наиболее походящий прогноз.
С помощью функции temporal_train_test_split() мы можем разбить набор на обучающую
и тестовую выборки с учетом временной структуры. В наших данных выручки за 45
месяцев, разобьем их на две части : обучающая 36 месяцев с января 2022 по
декабрь 2024 и тестовая 9 месяцев с января по сентябрь 2025.
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.
Рассмотрим как наивный прогноз библиотеки ETNA справится с задачей соревнования Data Fusion Contest 2025 4cast
Начинаю серию статей о сравнительно молодой библиотеки ETNA для прогнозирования временных рядов от команды Тинькофф Банк. В работе над статьями использую очень полезную книгу Груздев А. В. "Прогнозирование временных рядов с помощью Facebook Prophet, ETNA,sktime и LinkedIn Greykite".Начинаю с самой простой модели : модель наивного прогноза
Новое соревновании на Kaggle, на этот раз регрессия : Regression with an Insurance Dataset (Регрессия с набором страховых данных) . Цель этого набора данных — облегчить разработку и тестирование регрессионных моделей для прогнозирования страховых премий на основе различных характеристик клиентов и деталей полиса. Страховые компании часто полагаются на основанные на данных подходы для оценки премий, принимая во внимание такие факторы, как возраст, доход, состояние здоровья и история претензий. Этот синтетический набор данных имитирует реальные сценарии, чтобы помочь практикующим специалистам практиковать проектирование признаков, очистку данных и обучение моделей. Решение будем сопровождать материалами, взятыми из курса на платформе Stepik DS Глеба Михайлова.
Решил совместить две задачи : прослушать курс на Stepik DS Глеба Михайлова и принять участие в соревновании по классификации на Kaggle. Задача соревнования : кредитный скоринг, по нескольким параметрам оценить платежеспособность клиента и выдать рекомендацию дать или не дать ему кредит. Соревнование называется Loan Approval Prediction (Прогноз одобрения кредита).
Как правило, большинство дневных данных в розничной торговле не содержит пропусков за исключением такого показателя как количество зашедших посетителей. Чаще всего это связано с неисправностью счетчиков. Однако очень важно иметь достоверную информацию о посетителях. При этом важно работать не только с пропусками, но и с выбросами, которые также связаны с неисправностью счетчиков. Поэтому при подготовке данных по посетителям вначале надо отбросить выбросы, пусть они также будут считаться пропусками. Таким образом, под пропусками будем понимать как отсутствие значений, так и недостоверные данные.