Это мой первый средний рассказ. Надеюсь, вам будет интересно.

Оглавление:

  1. "Введение".
  2. Постановка проблемы и метрика ошибок.
  3. Цели и информация.
  4. Исследовательский анализ данных (EDA).
  5. Feature Engineering.
  6. Моделирование.

Вступление:

Спрос на продукт или услугу время от времени меняется. Ни один бизнес не может улучшить свои финансовые показатели без точной оценки потребительского спроса и будущих продаж продуктов / услуг. Прогнозирование продаж относится к процессу оценки спроса или продаж определенного продукта за определенный период времени. В этой статье я покажу вам, как машинное обучение можно использовать для прогнозирования продаж для решения реальной бизнес-задачи, взятой из Kaggle. Этот кейс решает все с нуля. Таким образом, вы увидите каждый этап того, как решается конкретный пример в реальном мире.

Постановка задачи

Россманн управляет более чем 3000 аптек в 7 странах Европы. В настоящее время менеджерам магазинов Rossmann поручено прогнозировать свои ежедневные продажи на срок до шести недель. На продажи в магазинах влияют многие факторы, включая рекламные акции, конкуренцию, школьные и государственные праздники, сезонность и местность. Поскольку тысячи менеджеров прогнозируют продажи, исходя из своих уникальных обстоятельств, точность результатов может сильно варьироваться.

Метрика ошибки: среднеквадратическая ошибка в процентах (RMSPE)

Формула для метрики следующая:

Цели:

1. С учетом данных спрогнозируйте продажи на 6 недель вперед.

2. Максимально минимизируйте данную метрику.

Данные:

Данные можно скачать здесь.

Предоставляются следующие файлы:

  1. train.csv
  2. test.csv
  3. store.csv

Поля данных:

Id - идентификатор, представляющий дуплекс (Store, Date) в тестовом наборе.

Магазин - уникальный идентификатор для каждого магазина.

Продажи - оборот за любой день (это то, что вы прогнозируете).

Клиенты - количество клиентов в определенный день.

Открыть - индикатор того, был ли магазин открыт: 0 = закрыт, 1 = открыт.

StateHoliday - указывает на государственный праздник. Обычно все магазины, за редким исключением, закрыты в государственные праздники. Обратите внимание, что все школы закрыты в праздничные и выходные дни. a = государственный праздник, b = праздник Пасхи, c = Рождество, 0 = нет.

SchoolHoliday - указывает, повлияло ли закрытие государственных школ на (Магазин, Дата).

StoreType - различает 4 разные модели магазинов: a, b, c, d.

Ассортимент - описывает уровень ассортимента: a = основной, b = дополнительный, c = расширенный.

CompetitionDistance - расстояние в метрах до ближайшего магазина конкурента.

CompetitionOpenSince [Месяц / Год] - дает примерный год и месяц открытия ближайшего конкурента.

Акция - указывает, проводится ли в этот день в магазине акция.

Promo2 - Promo2 - это постоянная последовательная акция для некоторых магазинов: 0 = магазин не участвует, 1 = магазин участвует.

Promo2Since [Год / Неделя] - описывает год и календарную неделю, когда магазин начал участвовать в Promo2.

PromoInterval - описывает последовательные интервалы запуска Promo2, называя месяцы, в которые продвижение начинается заново. Например. «Фев, май, август, ноябрь» означает, что каждый раунд начинается в феврале, мае, августе, ноябре любого года для этого магазина.

Исследовательский анализ данных (EDA)

Давайте выполним EDA, чтобы получить представление о данных.

Информация о train.csv следующая:

Как мы видим здесь, у нас около 1 миллиона точек данных. Кроме того, поскольку это проблема прогнозирования времени, мы должны отсортировать данные по дате.

Здесь наша целевая переменная - Продажи.

Информация о store.csv следующая:

Всего у нас 1115 уникальных магазинов. И многие столбцы здесь имеют нулевые значения. Мы позаботимся о них через некоторое время.

Теперь давайте проверим информацию о столбцах, присутствующих в данных.

Промо:

Мы видим, что и продажи, и количество клиентов значительно увеличиваются во время рекламных акций. Это показывает, что продвижение имеет положительный эффект для магазина.

Продажи:

Также интересно отметить, что Рождество и Новый год (см. График на 52 неделе) приводят к увеличению продаж. Поскольку магазины Rossmann продают товары для здоровья и красоты, можно предположить, что во время Рождества и Нового года люди покупают косметические товары, когда выходят на празднование, и это может стать причиной внезапного увеличения продаж.

День недели:

Здесь мы видим, что и продаж, и покупателей по воскресеньям очень мало, так как большинство магазинов закрыто в воскресенье.

Кроме того, продажи в понедельник самые высокие за всю неделю. Это может быть связано с тем, что магазины закрыты по воскресеньям.

Открытым:

Это ясно показывает, что большинство магазинов закрыто по воскресеньям. Некоторые магазины были закрыты и в будние дни, это может быть связано с государственными праздниками, поскольку магазины обычно закрыты во время государственных праздников и открываются во время школьных каникул.

Государственные и школьные каникулы:

Мы можем наблюдать, что большинство магазинов закрыто во время государственных и школьных каникул. Но интересно отметить, что количество магазинов, открытых во время школьных каникул, было больше, чем во время государственных праздников.

Еще один важный момент: в магазинах, открытых во время школьных каникул, было больше продаж, чем обычно.

StoreType:

Мы видим, что у магазинов типа А больше покупателей и продаж. StoreType D занимает второе место как по продажам, так и по количеству покупателей.

Конкурс открыт с года:

Большинство магазинов открыли свои конкурсы после 2000 года.

Фурье-анализ на сезонность:

Здесь мы построили график продаж магазина каждого типа.

На графиках выше мы видим, что на определенных частотах есть всплески. Это указывает на то, что в данных о продажах в магазине присутствует сезонный компонент.

Таким образом, мы можем использовать эти функции Фурье для обозначения сезонности данных.

CompetitionDistance:

Мы ясно видим, что у большинства магазинов есть свои конкуренты в пределах 5 км.

Выводы EDA:

  • Самый продаваемый и многолюдный тип магазина - А.
  • Продажи сильно зависят от количества клиентов.
  • Для всех магазинов продвижение приводит к увеличению продаж и клиентов.
  • В магазинах, которые открываются во время школьных каникул, больше распродаж, чем в обычные дни.
  • Во время школьных каникул открывается больше магазинов, чем во время государственных праздников.
  • Продажи увеличиваются в течение рождественской недели, это может быть связано с тем, что люди покупают больше косметических товаров во время празднования Рождества.
  • Отсутствие значений в функциях CompetitionOpenSinceYear / Month не означает отсутствие конкуренции, поскольку значения CompetitionDistance не равны нулю, тогда как два других значения равны нулю.
  • Проанализировав продажи с помощью разложения Фурье, я обнаружил, что в данных о продажах есть небольшая сезонная составляющая.

Feature Engineering и мелочи

Столбец выбросов:

Здесь я создам столбец, в котором будет указано, является ли значение продаж выбросом на основе среднего абсолютного отклонения (MAD).

Я создал хранилище столбцов с выбросами, то есть я сделал это для каждого уникального хранилища отдельно, а затем объединил данные.

Дата Особенности:

Сначала мы преобразуем столбец Date, используя функцию to_datetime панд. После этого мы можем просто извлечь другие функции из Date.

Выходные на этой неделе, на прошлой неделе и на следующей неделе:

Здесь я создал три функции, которые показывают общее количество праздников на текущей неделе, на прошлой неделе и на следующей неделе. Код можно увидеть в моем Github здесь.

Счетчик государственных праздников:

Выше показана функция, которую я использовал для создания двух новых функций. Один показывает, сколько дней осталось до государственного праздника, а другой показывает, сколько дней прошло после государственного праздника.

Счетчик акций и школьных каникул:

То же, что и выше, я создал еще 4 функции, указывающие количество дней до или после промо или школьных каникул. Код на гитхабе здесь.

Фиктивная переменная для Close:

Эта функция просто имеет 2 значения +1 или -1. +1, если магазин закрыт вчера или завтра, иначе -1.

Удаление точек с нулевыми продажами:

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

Продажи_за_день, Клиенты_за_день и Продажи_за_клиента_за_день:

Название функций просто указывает на их значение. Здесь нет необходимости в дополнительных объяснениях.

Открытый конкурс и открытый промо:

Здесь мы просто преобразуем эти две характеристики из «года» в единицу измерения в «месяц» как единицу.

Генерация признаков с помощью Promointerval:

Промоинтервал оформляется так: май, август, ноябрь. Теперь мы просто разделим их, например, май - это одна характеристика, август - вторая характеристика, а ноябрь - третья характеристика.

Вариация и ускорение продаж:

Вариация = y - (y-1), y = продажи

Ускорение = [(y-1) - (y-2)], y = продажи

Особенности Фурье:

Здесь я просто использую функцию fft из numpy для вычисления частот и амплитуды Фурье. Затем используйте их как функции.

Некоторые другие особенности:

К ним относятся основные тенденции DayOfWeek, Promo, Holidays и т. Д.

Внешние данные:

Для дополнительных данных их всего два. Один из них - данные о состоянии, который указывает, к какому состоянию принадлежит магазин, другой - данные о погоде в штате на определенную дату.

Дополнительные данные / информация взяты отсюда.

Анализ VIF:

После добавления всех функций я выполнил анализ VIF, чтобы проверить коллинеарность функций. Характеристики с высокой коллинеарностью просто отбрасывались.

А теперь займемся моделированием.

Моделирование

Базовая модель:

Вот те особенности, которые я сохранил для создания базовой модели:

Store, DayOfWeek, Promo, StateHoliday, SchoolHoliday, StoreType, Assortment, CompetitionDistance, CompetitionOpenSinceMonth, CompetitionOpenSinceYear, Promo2, Promo2SinceWeek, Promo2SinceYear ',' Год ',' Месяц ',' День ',' WeekOfYear ',' DayOfYear ',' SalesPerDay ',' Customers_per_day ',' Sales_Per_Customers_Per_Day ',' PromoInterval0 ',' PromoInterval1 ',' PromoInterval2 ',' PromoInterval3 '.

Для предварительной обработки данных я использовал sklearn Pipeline и ColumnTransformer.

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

Теперь разделим данные на обучение и проверку.

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

Выбор функций:

После создания указанной выше базовой модели я выполнил прямой выбор всех новых функций, созданных в разделе проектирования функций.

Вот наконец то, что осталось:

Store, DayOfWeek, Promo, StateHoliday, SchoolHoliday, StoreType, Assortment, CompetitionDistance, CompetitionOpenSinceMonth, CompetitionOpenSinceYear, Promo2, Promo2SinceWeek, Promo2SinceYear ',' Год ',' Месяц ',' День ',' WeekOfYear ',' DayOfYear ',' SalesPerDay ',' Customers_per_day ',' Sales_Per_Customers_Per_Day ',' PromoInterval0 ',' PromoInterval1 ',' PromoInterval2 ',' PromoInterval3 ', «Ускорение», «Состояние», «Промо_до_дней», «Промо_после_дней», «Частота_2», «Частота_3», «Амплитуда_2», «Амплитуда_3», «Средняя_ТемператураC», «События».

Теперь с этими функциями мы можем опробовать разные модели.

Ниже представлен конвейер с новыми функциями:

Для всех моделей методом проб и ошибок были выбраны лучшие параметры.

Регрессор SGD:

Для этого оценка составляет:

Регрессор дерева решений:

Для этого оценка составляет:

Регрессор случайного леса:

Для этого оценка составляет:

Легкая модель GBM:

Для этой модели оценка составляет:

Мета-обучение:

Этот подход определяется следующим образом:

  1. Разделите данные на 80–20 частей.
  2. Разделите часть поезда на 2 части, D1 и D2.
  3. Возьмите 9 образцов из D1 и обучите модель случайного регрессора леса на всех образцах.
  4. Предскажите D2 по этим 9 моделям. Используйте эти 9 прогнозов как функции и D2 y_original как выходные данные для обучения новой модели.
  5. Теперь что касается тестового набора, спрогнозируйте его, используя 9 моделей и используя 9 прогнозов, поскольку функции передают его в метамодель. Используйте прогноз из метамодели в качестве окончательного прогноза.

Для этого подхода оценка:

Вывод:

Из приведенной выше таблицы мы можем сделать вывод, что лучшая модель - это модель Light GBM.

Будущая работа:

С развитием глубокого обучения, LSTM может стать хорошей отправной точкой для дальнейшего повышения производительности данного набора данных.

Можно использовать другие методы ансамбля, чтобы проверить, могут ли они улучшить результат.

Использованная литература:

Выбросы заставляют нас сходить с ума: однофакторное обнаружение выбросов

Мультиколлинеарность | Обнаружение мультиколлинеарности с помощью VIF

Загадка отсутствующих данных: методы исследования и вменения

Программа просмотра блокнотов Jupyter



Вы можете связаться со мной здесь LinkedIn и Github.