Разрушение пророка
Эта статья предназначена для всех, кто практически не знает о прогнозировании, и поможет им легко реализовать расширенный алгоритм прогнозирования.
Давайте рассмотрим ежемесячные данные о продажах шампуня за три года, как показано ниже.
Наша цель - разбить столбец продаж на сумму столбцов тренда и сезонности.
Итак, что это за столбцы тренда и сезонности и как их получить?
Тренд помогает вам спроектировать поддающийся количественной оценке показатель либо в постоянно возрастающей, либо в убывающей манере. Это было не интуитивное определение, не так ли? Подумайте об этом так. Вы берете шкалу и карандаш и пытаетесь провести прямую (иногда кривую) линию, следуя мерке.
Мы будем использовать регрессию и построить линию тренда, но у нас есть только целевая переменная, «продажи (y)», и у нас нет никаких независимых переменных для регрессии. Мы будем использовать столбец даты как независимую переменную. Но как мы можем использовать столбец даты в качестве непрерывной переменной? Мы создаем новый столбец «X», индексируя даты натуральными числами, начиная с 1.
Теперь мы будем использовать метод наименьших квадратов, чтобы подобрать линейный тренд вида y = mx + c.
Я считаю, что это довольно приличная линия тренда. Но если вы внимательно посмотрите, тренд на 2016 год может быть почти ровной линией, на 2017 год он может быть постоянно растущим по сравнению с прошлым, а на 2018 год он может иметь гораздо более высокий наклон.
Так что, возможно, у нас могут быть разные наклоны для трех разных лет. Ага! Это интересная гипотеза. И в идеале это имеет смысл, правда? Если мы делаем прогнозы на 2019 год, лучше брать недавнюю тенденцию, чем включать все прошлые данные.
Я бы сказал, что доволен такой посадкой. А ты? Мало кто из вас может подумать об аппроксимации тренда полиномиальной кривой, как показано ниже:
Полиномиальная аппроксимация тоже кажется хорошей, но давайте придерживаться линейного тренда. Вы даже можете попробовать и проверить, как подходит экспоненциальная линия тренда.
Пока что мы смогли разбить столбец продаж по трендам, и нам все еще нужно получить столбец сезонности.
Сезонность можно определить как сезонную закономерность, повторяющуюся в течение определенного периода. Например, предположим, что по выходным ваши средние продажи будут немного выше, чем средние продажи в будние дни, по крайней мере, для большинства розничных продавцов. Это можно назвать еженедельной сезонностью. В общем, мы можем сказать, что сезонность - это все, что повторяется после определенного сезонного периода, это может быть день, неделя, месяц или год.
Если вы видите приведенную выше таблицу, нам все равно нужно учитывать сезонность, используя последний столбец. Этот столбец создается путем удаления тренда из продаж, и мы называем его продажами без тренда. Построим и посмотрим, как оно есть,
Как мы можем смоделировать этот странный граф? Мы будем использовать синусоидальные и косинусоидальные волны. Ошеломлен? Позволь мне объяснить. Благодаря Фурье мы можем записать любую волну в виде бесконечной суммы синусоидальных и косинусоидальных волн. Мы будем рассматривать столбец продаж без тренда как волну и сопоставим его с взвешенной суммой синусоидальных и косинусных волн с помощью регрессии.
Поскольку наши данные находятся на ежемесячном уровне, мы можем учесть сезонность за год, т. Е. Предположить, что после удаления тенденции продажи в течение января 2016 г., января 2017 г. и января 2018 г. одинаковы. Точно так же и в остальные месяцы. Технически, если мы подбираем годовую сезонность, мы подразумеваем, что существует модель, которая повторяется каждый год. Все еще схематично? Возьмем пример.
Я разделил данные на три части в зависимости от года. Надеюсь, у вас все еще есть карандаш из предыдущего наброска. Теперь вам нужно нарисовать кривую свободной рукой и убедиться, что вы должны использовать одну и ту же кривую во всех трех сегментах. Я тоже попробую, но на Python.
Ой! Это довольно приличное приближение. Теперь мы будем использовать множественную линейную регрессию, чтобы найти сезонность, то есть более устойчивую кривую, которая соответствует данным. Вам может быть интересно, как я мог построить приблизительную зеленую кривую на приведенном выше графике. Угадай, что? Это просто сумма нескольких синусоидальных и косинусоидальных волн. Мы возьмем набор синусоидальных и косинусоидальных волн, проведем регрессию по продажам без тренда, найдем веса, просуммируем их в соответствии с их весами, и мы получим очень хорошее приближение продаж без тренда, то есть сезонность. Как мы создаем эти синусоидальные и косинусоидальные волны? Фурье приходит на помощь.
Мы используем вышеуказанные функции для генерации синусоидальных и косинусоидальных волн. Так много вопросов. Что это за «я» и «т»? И почему в знаменателе стоит 365,25? «I» - это периодичность, «t» - это значение, при котором вы хотите получить результат функции, а знаменатель - 365,25, потому что мы хотим, чтобы кривая повторялась каждый год. Итак, когда я говорю, что i равен 1, это означает, что волна завершает один цикл для 365 пунктов.
Все еще сложно понять? Я определенно предлагаю вам, ребята, открыть Excel и попытаться воспроизвести эту формулу.
Если вы не смогли воспроизвести это в Excel, позвольте мне еще раз изложить это, когда i = 1, я вычислил f (t) для t = 1,2,3 ... 365 и получил график ниже,
Поскольку у нас есть данные за 3 года, позвольте мне увеличить значение t до 1096 и построить то же самое,
Теперь вернемся к нашей цели: «Как я могу записать продажи без тренда в виде взвешенной суммы этих синусоидальных и косинусоидальных волн, которые будут повторять годовой шаблон?».
Итак, для моделирования годовой сезонности мы берем синусоидальные и косинусные волны для i = 1,2,3..10 и вычисляем f (t), g (t), когда t = 1,2,3,4 …… 1096. В конечном итоге это означает, что мы берем 10 синусоидальных волн и 10 косинусоидальных волн с 1096 точками.
Количество волн следует выбирать с особой осторожностью, так как в конечном итоге вы получите чрезмерную подгонку кривой с большими степенями свободы. С 10 синусоидальными и 10 косинусными волнами за три года мы получаем следующую таблицу:
Переходя к данным, мы пытаемся рассчитать столбец продаж с исключенным трендом как сумму регрессии синусоидальных и косинусоидальных волн с периодом 365 дней. Но за год у нас всего 12 очков. Как мы можем сопоставить это с 365 точками? К настоящему времени вы должны были подумать, зачем нам даже использовать 365 дневных точек для моделирования сезонности, если наш набор данных ежемесячный? Дело в том, что мы не можем аппроксимировать чистую синусоидальную волну или косинусоидальную волну всего с 12 точками для моделирования годовой сезонности. Поэтому вместо этого мы берем 365 точек данных, чтобы лучше аппроксимировать синусоидальные и косинусоидальные волны. Но при регрессии мы возьмем точки данных с общими датами. Думайте об этом как о фрейме данных, полученном после пересечения дат в обоих фреймах данных. Как сказал бы большинство людей, «внутреннее соединение» на основе столбца даты.
Когда мы объединяем данные продаж без тренда, содержащие 36 строк, с данными синуса и косинуса, имеющими 1096 строк в столбце даты, мы получаем следующую таблицу с 36 строками:
Мы будем использовать «продажи без тренда» в качестве зависимой переменной «y» и проводить регрессию во всех остальных столбцах. Здесь я использую модель без перехвата, и y_pred будет рассматриваться как член сезонности.
Мы построим график фактических продаж без тренда и его прогноз, и посмотрим, насколько хорошо мы смогли зафиксировать продажи без тренда, то есть сезонность за год,
Это было достаточно прилично. Теперь давайте суммируем полученные столбцы тренда и сезонности, чтобы получить указанные ниже значения.
Я построил график фактических и прогнозируемых продаж, и, честно говоря, он оказался довольно приличным, чем большинство других алгоритмов.
Самая важная часть, прогнозирование будущего. И угадай что? Это самая легкая часть. У нас есть коэффициенты регрессии, и все, что нам нужно сделать, это подключить и спрогнозировать будущее.
Основная идея для этого взята из библиотеки Prophet, представленной Facebook, где она использует вероятностное программирование для подгонки оценок с кусочно-линейной функцией или функцией логистического роста для тренда и рядов Фурье для моделирования сезонности.
Я советую всем начинающим аналитикам данных избегать импорта, подгонки и прогнозирования. Я бы посоветовал реализовать алгоритм самостоятельно и настроить его для интуитивного понимания и объяснимых результатов.
Свяжитесь со мной в LinkedIn для получения любых разъяснений / отзывов или если вы хотите сотрудничать в проектах по науке о данных.