Привет! Продолжаю знакомить вас с библиотекой Prophet в качестве инструмента прогнозирования продаж. Первая часть тут.

Функции для критериев качества в нашей прогнозной модели будут выглядеть следующим образом:

Далее выбираем для трех гипер-параметров значения, из которых будем компоновать модели. Параметр seasonality_prior_scale рекомендуется устанавливать в диапазоне до 10 и это и есть значение по умолчанию. Как было сказано ранее, сезонность в нашем рассматриваемом ряду очень выраженная, поэтому логично предположить, что значение параметра должно быть достаточно близко к максимальному. Можно было бы оставить только 10, но попробуем взять также уменьшенное в 2 раза, т.е. 5. 

Параметр changepoint_prior_scale изменяется в диапазоне от 0.01 до 0.5 – возьмем минимальное значение (0.01), дефолтное (0.05), максимальное (0.5) и еще два между ними. Последний параметр changepoint_range также имеет смысл брать максимально близким к максимуму – возьмем дефолтное 0.8, также 0.9 и 0.95. Итого набор гипер-параметров будет иметь вид:

Построим модели для каждого из сочетаний (всего будет 30) и выберем лучшую – для которой относительная ошибка выборки будет минимальной.

Лучшей стала модель с параметрами seasonality_prior_scale = 10, changepoint_prior_scale = 0.5 и changepoint_range = 0.95, что было ожидаемо – максимальная величина сезонных колебаний и максимальная доля исторических данных для обучения. Для данной модели построим прогноз.

Относительная ошибка (MAPE) лучшей модели составила 0.98%, абсолютная (MAE) – 14.62.

Для сравнения ошибки худшей модели (с параметрами 5, 0.1, 0.8) составили, соответственно, абсолютная – 39.76 и относительная – 2.67%.

Результаты прогноза также удобно визуально оценить на графиках. Библиотека Prophet имеет собственные средства визуализации, например, с помощью метода plot_components, который позволяет посмотреть отдельно на все компоненты модели: тренд, сезонность, праздники.

На графиках с праздниками (holidays) отображаются корректировки модели в основные периоды с большим количеством нерабочих дней – январь, конец февраля-начало марта, май.

Сезонность очень точно смоделирована – как по дням недели, так и по месяцам.

Помимо этого, с помощью стандартного метода Prophet.plot можно построить график, на котором будут отображены факт, основные расчетные прогнозные значения, а также границы доверительного интервала – на рисунке это области, выделенные светло-синим. Красным цветом выделены точки перелома тренда – тот самый гипер-параметр changepoint prior scale.

Также построим график, на котором отобразим факт только за последние 3 месяца (чтобы сделать его более информативным) и прогноз. 

Видим, что прогноз практически бесшовно продолжает ряд фактических значений. 

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

Строим итоговую прогнозную модель

Данные по продажам FTTB-FMC хранятся и обновляются на кластере, для выгрузки используем PySpark (версия 3.2.4). Выгружаем данные по продажам за прошедшие 2 года, только FTTB и конвергентные минуса, без переездов, по каналам, филиалам и сегментам. Конкатенируем значения полей канал, филиал и сегмент для создания ключа, по которому будем формировать группы. Это будет основной дата-фрейм.

Как уже упоминалось ранее, все группы по каналу/филиалу/сегменту делятся в сущности на два больших кластера. Первый из них – это группы с четким и ярко выраженным трендом, сезонностью, стабильным количеством продаж – для них мы будем использовать модель с трендом, как рассмотрели выше. Второй кластер– это отсутствие тренда, практически нулевые продажи или мерцающего типа. Для таких групп будем использовать модель без тренда (growth = flat).

Чтобы присвоить каждой группе флаг наличия или отсутствия тренда, считаем среднее значение продаж за последние 3 месяца и, в случае если оно оказывается меньше установленного порогового значения, присваиваем индекс отсутствия тренда. Либо можно сделать наоборот – если значение больше, что тренд наличествует, в данном случае это не принципиально. Получаем таким образом второй дата-фрейм из двух столбцов – ключ группы и флаг наличия тренда.

Прогноз будем строить на 2 месяца вперед – текущий, в данном случае это октябрь и ноябрь 2024. Устанавливаем период для модели.

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

Сначала строим модель для кластера с трендом – всего в нем будет 492 группы, то есть чуть меньше половины.

Затем, от противного, находим перечень групп с отсутствующим трендом и для них также строим прогнозную модель.

Конкатенируем оба дата-фрейма и агрегируем данные по месяцам – прогнозная модель готова. Оценим качество прогноза на визуализации.

Для наглядности отобразим на графике только данные за 12 месяцев, с ноября 2023 по ноябрь 2024, фактические значения – это синяя линяя и прогнозные – сиреневая. На график видно, что прогноз достаточно хорошо описывает имеющиеся исторические данные – есть эффект сглаживания, прогноз повторяет тренд и сезонность.

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

Абсолютная ошибка и относительная ошибка, рассчитанные по агрегированным данным, составили, соответственно, 800.74 и 2.55%. 

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

Итоги

Подводя итог, еще раз отметим достоинства модели Phophet. Самое главное – это интерпретируемость и гибкость. Модель позволяет выбрать функцию для тренда, учесть сразу все варианты сезонности, управлять гипер-параметрами, причем все компоненты модели представлены в «человеко-интерпретируемом» виде. Очень важная особенность – возможность добавлять аномальные дни, причем есть возможность корректировать поведение модели не только в эти указанные дни, но и в заданное количество дней до и после. Подобные вещи позволяют делать модель более гибкой.

В модель Phophet можно добавлять факторы (или регрессоры). В моей задаче мы не использовали регрессоры или, точнее, использовали в качестве фактора только время, но все же считаю важным отметить это преимущество. Например, если прогнозировать выручку или выживаемость, то в качестве фактора можно добавить активную базу абонентов, пользователей услуги и т.п.

Еще одно преимущество Phophet заключается в том, что модель хорошо обучается на коротких временных рядах, менее 100 наблюдений. На самом деле, чтобы построить приемлемый вариант прогноза на Phophet достаточно иметь хотя бы 12 наблюдений (то есть 1 год по месяцам), не всякая прогнозная модель способна на таком объеме исторических данных построить что-то адекватное.

Теперь о недостатках модели. В первую очередь я бы выделила не слишком высокую скорость. Одна итерация считается примерно за 3-5 секунд, соответственно, в моем случае с учетом 1000+ итераций весь расчет занимает больше часа. 

Следующий недостаток – это невозможность учесть в явном виде авторегрессию, как, например, это делается в моделях SARIMA. Как вариант, если учитывать авторегрессионные процессы необходимо, то можно использовать библиотеку Neural Prophet, но в рамках просто Prophet авторегрессию не добавить.

И последнее, что относится не только к Phophet, но и вообще к подобному классу моделей – они обладают достаточной степенью устойчивости при небольших или даже средних колебаниях, но, конечно, не могут справиться с каким-то серьезными изломами тренда. Например, во время пандемии в 2020-м многие тенденции оказались нарушены – в некоторых каналах продажи были остановлены. Подобные кризисные явления не способна описать модель, базирующаяся на трендах. Для таких случаев подходят адаптивные модели, вроде экспоненциального сглаживания.