Прогноз спроса в рознице: от Excel к машинному обучению
Продвинутое4 минРедакция Innovialabs
Коротко
Начните с очищенных данных и простого статистического прогноза как эталона; ML оправдан, когда много SKU, промо и внешних факторов, а ценность прогноза появляется только тогда, когда он автоматически превращается в заказ поставщику.
Короткий ответ
Прогноз спроса — это оценка того, сколько единиц товара купят в конкретном магазине в конкретный период. Путь обычно такой: Excel → статистические методы → ML-модели, и каждый следующий шаг оправдан только если он точнее предыдущего на ваших данных.
Главное правило: качество данных важнее выбора алгоритма. Модель, обученная на «грязных» продажах, уверенно предскажет вчерашние ошибки.
Продажи — это не спрос
В чеках записаны продажи, а не спрос. Три фактора их расходят:
- Дефицит (stockout). Если товара не было на полке, продажи равны нулю, хотя спрос был. Такие дни нужно помечать и либо исключать, либо восстанавливать спрос (например, по средним продажам в похожие дни).
- Промо. Скидка временно поднимает продажи, а после акции часто бывает провал — покупатели запаслись. Нужен признак «товар в промо», тип механики и глубина скидки.
- Сезонность и календарь. Недельный цикл, праздники, Рамадан, начало учебного года, погода. Плавающие даты праздников нужно задавать явно, а не надеяться, что модель «увидит» их сама.
Дополнительно: каннибализация (акция на один товар снижает продажи соседних), смена ассортимента, открытие конкурента рядом, изменение выкладки.
Простые методы: эталон для сравнения
Прежде чем строить ML, сделайте базовую линию:
| Метод | Когда подходит | Ограничения |
|---|---|---|
| Наивный (как неделю назад) | Стабильный товар с недельным циклом | Не учитывает тренд и промо |
| Скользящее среднее | Ровный спрос без сезонности | Запаздывает при изменениях |
| Экспоненциальное сглаживание (Holt-Winters) | Есть тренд и сезонность | Плохо учитывает промо и внешние факторы |
| ARIMA/SARIMA | Длинная история, один ряд | Тяжело масштабировать на тысячи SKU |
Если сложная модель не обыгрывает наивный прогноз — проблема в данных или постановке задачи.
Когда переходить к ML
Модели вроде градиентного бустинга (LightGBM, XGBoost) обучаются сразу на всех товарах и магазинах и используют признаки:
- лаги и скользящие средние продаж;
- календарь: день недели, праздники, зарплатные дни;
- цена, промо-механика, глубина скидки;
- атрибуты товара и магазина;
- внешние данные: погода, события — если они действительно доступны к моменту прогноза.
ML оправдан, когда SKU много, промо частые, а история достаточная. Для новых товаров без истории используют аналоги по категории и атрибутам.
Ключевые технические правила:
- Нет утечки будущего. Признаки должны быть доступны на момент прогноза. Фактическая погода за прогнозный день — утечка, прогноз погоды — нет.
- Валидация по времени. Обучайте на прошлом, проверяйте на следующем периоде (backtesting со скользящим окном), а не на случайной выборке.
- Иерархия. Прогнозы по магазинам и товарам должны сходиться с прогнозом по категории и сети.
Метрики точности
- MAE — средняя абсолютная ошибка в штуках. Понятна, но не сравнивается между товарами.
- MAPE — ошибка в процентах. Ломается на товарах с нулевыми продажами.
- WAPE — сумма абсолютных ошибок, делённая на сумму фактических продаж. Устойчивее к нулям и удобна для агрегатов.
- Bias — систематическое завышение или занижение. Модель с небольшой ошибкой, но постоянным занижением, будет хронически создавать дефицит.
import numpy as np
def wape(actual, forecast):
actual, forecast = np.asarray(actual), np.asarray(forecast)
return np.abs(actual - forecast).sum() / actual.sum()
def bias(actual, forecast):
actual, forecast = np.asarray(actual), np.asarray(forecast)
return (forecast - actual).sum() / actual.sum()
Оценивайте метрики отдельно по сегментам: быстрооборачиваемые товары, «длинный хвост», промо-периоды.
От прогноза к автозаказу
Прогноз сам по себе ничего не меняет — ценность появляется в автозаказе:
- Прогноз спроса на горизонт = срок поставки + период между заказами.
- Страховой запас — из разброса ошибки прогноза и целевого уровня сервиса для категории.
- Заказ = прогноз + страховой запас − текущий остаток − товар в пути.
- Ограничения: кратность упаковки, минимальная партия, вместимость полки и склада, сроки годности.
- Рекомендация уходит категорийному менеджеру на подтверждение, со временем — автоматически для стабильных позиций.
Для этого нужны точные остатки, данные о товарах в пути и интеграция с ERP или товароучётной системой.
Частые ошибки
- Обучение на продажах без учёта дефицита — модель занижает спрос.
- Оценка точности только по средней по сети, без сегментов.
- Нет мониторинга: модель деградирует после смены ассортимента, и никто не замечает.
- Прогноз не встроен в процесс заказа и остаётся «отчётом для интереса».