Это мой первый средний рассказ. Надеюсь, вам будет интересно.
Оглавление:
- "Введение".
- Постановка проблемы и метрика ошибок.
- Цели и информация.
- Исследовательский анализ данных (EDA).
- Feature Engineering.
- Моделирование.
Вступление:
Спрос на продукт или услугу время от времени меняется. Ни один бизнес не может улучшить свои финансовые показатели без точной оценки потребительского спроса и будущих продаж продуктов / услуг. Прогнозирование продаж относится к процессу оценки спроса или продаж определенного продукта за определенный период времени. В этой статье я покажу вам, как машинное обучение можно использовать для прогнозирования продаж для решения реальной бизнес-задачи, взятой из Kaggle. Этот кейс решает все с нуля. Таким образом, вы увидите каждый этап того, как решается конкретный пример в реальном мире.
Постановка задачи
Россманн управляет более чем 3000 аптек в 7 странах Европы. В настоящее время менеджерам магазинов Rossmann поручено прогнозировать свои ежедневные продажи на срок до шести недель. На продажи в магазинах влияют многие факторы, включая рекламные акции, конкуренцию, школьные и государственные праздники, сезонность и местность. Поскольку тысячи менеджеров прогнозируют продажи, исходя из своих уникальных обстоятельств, точность результатов может сильно варьироваться.
Метрика ошибки: среднеквадратическая ошибка в процентах (RMSPE)
Формула для метрики следующая:
Цели:
1. С учетом данных спрогнозируйте продажи на 6 недель вперед.
2. Максимально минимизируйте данную метрику.
Данные:
Данные можно скачать здесь.
Предоставляются следующие файлы:
- train.csv
- test.csv
- 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:
Для этой модели оценка составляет:
Мета-обучение:
Этот подход определяется следующим образом:
- Разделите данные на 80–20 частей.
- Разделите часть поезда на 2 части, D1 и D2.
- Возьмите 9 образцов из D1 и обучите модель случайного регрессора леса на всех образцах.
- Предскажите D2 по этим 9 моделям. Используйте эти 9 прогнозов как функции и D2 y_original как выходные данные для обучения новой модели.
- Теперь что касается тестового набора, спрогнозируйте его, используя 9 моделей и используя 9 прогнозов, поскольку функции передают его в метамодель. Используйте прогноз из метамодели в качестве окончательного прогноза.
Для этого подхода оценка:
Вывод:
Из приведенной выше таблицы мы можем сделать вывод, что лучшая модель - это модель Light GBM.
Будущая работа:
С развитием глубокого обучения, LSTM может стать хорошей отправной точкой для дальнейшего повышения производительности данного набора данных.
Можно использовать другие методы ансамбля, чтобы проверить, могут ли они улучшить результат.
Использованная литература:
Выбросы заставляют нас сходить с ума: однофакторное обнаружение выбросов
Мультиколлинеарность | Обнаружение мультиколлинеарности с помощью VIF
Загадка отсутствующих данных: методы исследования и вменения
Программа просмотра блокнотов Jupyter