Прогноз продаж Россманна
1. Бизнес-проблема
Rossmann управляет более чем 3000 аптеками в 7 европейских странах. В настоящее время менеджерам магазинов Rossmann поручено прогнозировать свои ежедневные продажи на срок до шести недель. Продажи в магазине зависят от многих факторов, включая рекламные акции, конкуренцию, школьные и государственные праздники, сезонность и местоположение. Поскольку тысячи отдельных менеджеров прогнозируют продажи на основе своих уникальных обстоятельств, точность результатов может быть весьма разной.
К июлю 2015 года основной целью этого проекта было ежедневно прогнозировать продажи для каждых 1115 магазинов и данные о продажах, доступные на Kaggle.
2. Использование машинного обучения
Мотивация использования машинного обучения заключается в том, что благодаря надежному прогнозированию ежедневных продаж менеджеры магазинов могут снизить эксплуатационные расходы, создать эффективные графики работы персонала и соответствующим образом спланировать запасы и цепочку поставок. Кроме того, мы хотели бы определить, какие методы являются одновременно эффективными и действенными в задаче прогнозирования продаж в реальном мире. Прежде чем строить какие-либо модели регрессии или машинного обучения для прогноза, мы попытались определить, какие функции в данных могут быть важны для определения ежедневных продаж в магазинах, и исследовать любые интересные взаимосвязи между переменными. Прежде чем строить регрессию или модель машинного обучения, мы также попробовали простое скользящее среднее, взвешенное скользящее среднее и экспоненциальное взвешенное скользящее среднее для прогнозирования продаж.
Модели машинного обучения используются для анализа данных и прогнозирования будущих продаж (суммы). Таким образом, методы регрессии требуют линейной зависимости между входной функцией и выходной функцией и могут не обеспечивать точное прогнозирование продаж. Эти нелинейные отношения можно зафиксировать с помощью алгоритмов Random Forest и Gradient Boosting, таких как XGBoost.
3. Источник данных
Набор данных, собранный из Kaggle. Данные можно скачать здесь.
train — исторические данные, включая данные о продажах.
test — исторические данные без учета продаж.
магазин — дополнительная информация о магазинах.
4. Существующие подходы
На данный момент у нас есть несколько подходов, доступных в Интернете. Я прошел через многих, перечислив некоторые из них.
Подход 1: https://www.hindawi.com/journals/jhe/2021/2474473/
В этой статье они попытались применить алгоритм машинного обучения к реальной задаче — прогнозированию продаж в аптеках. Получив информацию о магазине и записи о продажах, они применили линейную регрессию, регрессию опорных векторов (SVR) с гауссовскими и полиномиальными ядрами и алгоритм случайного леса и попытались спрогнозировать продажи на 1–3 недели. Среднеквадратическая ошибка в процентах (RMSPE) используется для измерения точности. Как оказалось, Random Forest затмил все остальные модели и достиг RMSPE 12,3%, что является надежным прогнозом, позволяющим менеджерам магазинов эффективно распределять персонал и пополнять запасы.
Подход 2: https://cs229.stanford.edu/proj2015/216_report.pdf
В этой статье они попытались применить алгоритм машинного обучения к реальной задаче — прогнозированию продаж в аптеках. Получив информацию о магазине и записи о продажах, они применили линейную регрессию, регрессию опорных векторов (SVR) с гауссовскими и полиномиальными ядрами и алгоритм случайного леса и попытались спрогнозировать продажи на 1–3 недели. Среднеквадратическая ошибка в процентах (RMSPE) используется для измерения точности. Как оказалось, Random Forest затмил все остальные модели и достиг RMSPE 12,3%, что является надежным прогнозом, позволяющим менеджерам магазинов эффективно распределять персонал и пополнять запасы.
5. Улучшения
Понимание домена: я просмотрел различные блоги и статьи, чтобы понять бизнес фармацевтического магазина. Что помогло мне сделать следующие улучшения.
Отмечено, что «Клиенты» являются наиболее важной характеристикой, где продажи пропорциональны количеству клиентов, посещающих магазины. У нас нет информации в будущих данных о том, сколько клиентов собирается посетить магазины. Я включил среднее количество покупателей, посетивших один магазин; Средний объем продаж в одном магазине. На продажи также повлияли последние тенденции, включая средние продажи в магазине за последнюю неделю.
Поскольку магазин является фармацевтическим, продажи в основном зависят от сезона заболеваемости, например, сезон гриппа или любой другой соответствующий сезон также может повлиять на продажи. Итак, собраны данные, сколько процентов (от 0 до 100) положительных тестов диагностировали каждую неделю в период с 2013 по 2016 год.
6. Исследовательский анализ данных (EDA)
Самый важный шаг в решении любой проблемы машинного обучения или глубокого обучения — понимание данных. Как специалист по данным, я просматриваю и анализирую данные должным образом, просматривая данные в каждом столбце/функции. Это помогает мне получить ценную информацию о структуре данных и информации. Статистические инструменты играют большую роль в правильной визуализации данных. Надлежащий EDA дает интересные особенности данных, которые, в свою очередь, также влияют на нашу предварительную обработку данных и критерий выбора модели.
Данные поезда:
. Ни в одном из столбцов не найдено пустых данных. Date, StateHoliday имеют тип, остальные объекты имеют тип int64. Функции с типом Object должны быть закодированы.
. Минимальные продажи и Максимальные продажи равны 0 и 4155. 16% (172871) данных имеют NaN как продажи, потому что магазин закрыт (172817) в эти дни.
. В воскресенье сообщалось о дополнительных продажах, кажется, что магазин закрыт в субботу или продаж нет.
. Выбросы в продажах — 99,9 процентиль данных = 24680.
. Выбросы по клиентам — 99,9 процентиль данных составляет ›= 3600.
. Акция применялась только к 50% данных. Значительное влияние промо на продажи.
. Столбец StateHoliday содержит два разных значения: 0 (количество = 131072) и «0» (количество = 855087).
. StateHoliday повлиял на продажи в магазинах.
. Различные StateHoliday применялись только к 3% данных.
. SchoolHoliday применяется только к 17% данных и не оказывает большого влияния на продажи в магазинах.
Хранить данные:
. CompetitionDistance имеет значение null/NaN для 3 магазинов.
. 354 магазина не имеют CompetitionOpenSinceMonth, определены CompetitionOpenSinceYear, т.е. null/NaN. Eventhoguh они определили CompetitionDistance.
. 554 магазина не имеют Promo2SinceWeek, Promo2SinceYear, PromoInterval определены, т. е. null/NaN.
. Найдены значения NaN/null в CompetitionOpenSinceYear, CompetitionOpenSinceMonth, Promo2SinceYear, Promo2SinceWeek, PromoInterval.
После объединения поезда с магазином:
. Продажи больше для StoreType «b». Средний объем продаж также больше для StoreType «b».
. Продажи больше для ассортимента «b». Средняя продажа также больше для StoreType «b».
. С или без Promo2, разница в средних продажах составляет около 13%. С Promo2 средние продажи больше.
. Средний объем продаж увеличивается с 2013 по 2015 год, у нас есть значительное улучшение в 2015 году (у нас есть данные на 31 июля).
. Характеристики продаж и клиентов имеют значительную корреляцию (0,89).
. Функции Sales и Open имеют некоторую корреляцию (0,68).
. Функции «Продажи» и «Промо» имеют некоторую корреляцию (0,45).
. Корреляция между DayOfWeek и Sales/Customers/Open/Promo отрицательная. функции имеют некоторую значительную корреляцию
. СоревнованиеРасстояние равно нулю для 3 магазинов, может рассматриваться как отсутствие конкурентов для этих 3 магазинов. Замените nan средним значением CompetitionDistance.
Одномерный анализ:
. Перекрытие StoreType и Sales не может быть различено в однофакторном анализе. Тот же опыт наблюдения с ассортиментом и продажами, промо и продажами.
Одномерный анализ с использованием Box Plot, выполненный в отношении ассортимента и продаж, StoreType и продаж, Promo и Sales, PromoInterval и Sales, DayOfWeek и Sales, Promo2 и Sales.
например, DayOfWeek против продаж
Двумерный анализ:
Наблюдения:
. Клиенты и продажи по типу магазина — согласно 1-му графику ниже, больше продаж и клиентов для типа магазина b, чем для d, чем для a, чем для c.
. Согласно 2-му графику, продажи больше для StoreType b, для остальных StoreTypes продажи равны.
. Согласно 3-му графику, клиентов больше для StoreType b, для других StoreType значительно меньше.
Многофакторный анализ:
Наблюдения согласно приведенной ниже гистограмме:
. Магазин: все магазины открыты одинаковое количество дней.
. DayOfweek: В субботу продаж нет.
. Продажи: распространяется нормально.
. Клиенты: Распределяются нормально.
. Открыто: у нас есть только данные с открытыми магазинами.
. Промо: Данные имеют 380 КБ с промо.
. SchoolHoliday: Данные содержат около 180 тыс. SchoolHolidays.
. CompetitionDistance: Конкуренция смещена вправо, большинство участников находятся ближе.
- Год: у нас есть данные за 2013, 2014, 2015 годы.
Наблюдения согласно приведенному ниже парному графику:
. Продажи против клиентов: продажи и клиенты пропорциональны друг другу
. Sales vs CompetitionDistance: Продажи больше, чем CompetitionDistance
. Продажи против промо: Промо не сильно влияет на продажи.
. Продажи против Promo2: Продажи не сильно зависят от Promo2.
Уменьшение размерности:
t-SNE с использованием Scikit-Learn
Наблюдение: на основе приведенного ниже t-SNE
. Недоумение 30 распространяет продажи шире и в большем количестве групп
- Недоумение 50 распространяет продажи ближе, и меньшие группы
PCA с использованием Scikit-Learn
Наблюдения: на основе приведенного ниже метода PCA
. Более 90% дисперсии объясняется 10 признаками
. Основной компонент 1 объясняется о продажах с меньшей дисперсией.
. Основной компонент 2 объясняется о продажах с небольшими отклонениями.
Нахождение корреляции между признаками:
Тестовые данные:
. Уникальный идентификатор для каждой строки в наборе тестовых данных (от 1 до 41088).
. Найдено около 11 строк с нулевым значением в столбце Open.
. Задача состоит в том, чтобы спрогнозировать продажи с 1 августа 2015 года по 17 сентября 2015 года.
Очистка/предварительная обработка данных
После объединения поезда с магазином:
. Удалите строки, в которых Sales имеет значение NaN/null/0.
. Удалить выбросы в продажах — 99,9 процентиля данных, после чего = 24680.
. Удалить выбросы в клиентах — 99,9 процентиля данных, после чего = 3600.
. Столбец StateHoliday содержит два разных значения: 0 (count=131072) и «0» (count=855087), поэтому для этих данных 0 заменено на «0».
. Замените CompetitionDistance null/NaN на медиану (2325) CompetitionDistance.
. Замените значения NaN/null в CompetitionOpenSinceYear, CompetitionOpenSinceMonth, Promo2SinceYear, Promo2SinceWeek, PromoInterval на 0.
. Преобразование типа объекта даты из «объекта» в «datetime64[ns]» для извлечения из него функций
. Сортировка данных поезда по дате.
Тестовые данные:
. Уникальный идентификатор для каждой строки в наборе тестовых данных (от 1 до 41088).
. Найдено около 11 строк с нулевым значением в столбце Open, удалите их.
7. Решение для первого разреза
Включая существующие функции:
* Магазин
* День недели
* Продажи
* Тип магазина
* Ассортимент
* Государственный праздник
* ПромоИнтервал
* Клиенты
* Школьные каникулы
* Дистанция соревнований
* КонкуренцияОткрыта с года
* КонкуренцияОткрытаСМесяца
* Промо
* Промо2
* Promo2SinceYear
* Promo2SinceWeek
Добавление новых функций:
* Кодировка StoreType, Ассортимент, StateHoliday, PromoInterval категориальный.
* Год — извлечено из даты.
* Месяц — извлечено из даты.
* День — извлечено из функции «Дата».
* AvgCustSpentOnDay — В указанный день в данных количество продаж/количество клиентов, посетивших этот магазин в этот день.
* AvgSalesPerStore — средний объем продаж в магазине, извлеченный из функции «Продажи».
* AvgCustomersPerStore — среднее количество покупателей, посетивших магазин; Извлечено из функции «Клиенты».
* PerCentDiseaseAffInWeek — Найдите данные о заболеваемости в странах Европы в Google, используя функцию даты, найдите год и неделю. На основании предоставленных данных % положительных тестов введите значение этой характеристики в диапазоне от (0 до 100). См. раздел «Подготовка данных» в приведенных выше шагах.
Добавление временных функций:
* Год-неделя — Объединено из года и недели, разделенных «-».
Удаление существующих/временных функций:
* Дата
* Открыть
* Год-неделя
8. Примеры кодов
Добавление функции: PerCentDiseaseAffInWeek
Добавление функций: AvgSalesPerStore, AvgCustomersPerStore
9. Объяснение моделей
Простая скользящая средняя:
Первая используемая модель — это модель скользящих средних, которая использует предыдущие n значений для прогнозирования следующего значения. «n» — размер окна ниже.
Взвешенное скользящее среднее:
Используемая модель скользящих средних придавала равную важность всем значениям в используемом окне, но мы интуитивно знаем, что будущее, скорее всего, будет похоже на последние значения и менее похоже на более старые значения. Средневзвешенные значения преобразуют эту аналогию в математическое соотношение, присваивая наивысший вес при вычислении средних значений до последнего предыдущего значения и уменьшении весов до последующих более старых.
«N» — размер окна ниже.
Экспоненциально-взвешенная скользящая средняя:
С помощью взвешенного усреднения мы удовлетворили аналогию с присвоением более высоких весов последнему значению и уменьшению весов последующим, но мы все еще не знаем, какая схема взвешивания является правильной, поскольку существует бесконечно много возможностей, в которых мы можем присвоить веса в невозрастающий
заказать и настроить размер окна гиперпараметра.
Чтобы упростить этот процесс, мы используем экспоненциальные скользящие средние, которые являются более логичным способом назначения весов и в то же время также используют оптимальный размер окна.
Гиперпараметры: альфа (α) — коэффициент сглаживания; w - размер окна.
P — истинное наблюдение, P’ — прогнозируемое значение.
Линейная регрессия:
Линейная регрессия только от sklearn не требует настройки многих параметров. Так что использовать нельзя.
SGDRegressor дает отрицательный прогноз для прогноза продаж, поэтому классификатор исключен.
Ридж-регрессор, который я использовал для настройки гиперпараметров и создания модели, как показано ниже.
График важности функции
Регрессор случайного леса:
RandomForestRegressor, я настроил гиперпараметры, как показано ниже, и создал модель с лучшими гиперпараметрами.
График важности функции:
Регрессор XGBoost:
XBBoost Regressor, я запустил гиперпараметры, как показано ниже, и создал модель с лучшими гиперпараметрами.
Сюжет важности функции:
10. Сравнение моделей
Вывод: обнаружено, что дерево принятия решений с повышением градиента (GBDT) работает лучше всего.
Примечание. Наилучшее значение гиперпараметра, найденное для параметров, указанных ниже, по сравнению с указанной моделью.
11. Скриншот Kaggle
Обратитесь к таблице лидеров: https://www.kaggle.com/competitions/rossmann-store-sales/overview.
12. Будущая работа
Я планирую извлечь больше функций на основе простой скользящей средней, взвешенной скользящей средней, экспоненциально взвешенной скользящей средней, чтобы проверить, полезны ли новые функции.
Я планирую изучить более широкий диапазон гиперпараметров, используя для этого уникальные функции типа linspace, а не давать только целые числа.
13. Ссылки
https://towardsdatascience.com/seaborn-heatmap-for-visualising-data-correlations-66cbef09c1fe
https://medium.com/rapids-ai/tsne-with-gpus-hours-to-seconds-9d9c17c941db
https://www.kaggle.com/code/anasmjali/dimensionity-reduction-pca-and-tsne
https://machinelearningmastery.com/hyperparameter-optimization-with-random-search-and-grid-search/
https://machinelearningmastery.com/xgboost-loss-functions/
https://machinelearningmastery.com/moving-average-smoothing-for-time-series-forecasting-python/
https://machinelearningmastery.com/hyperparameter-optimization-with-random-search-and-grid-search/
https://towardsdatascience.com/how-to-code-different-types-of-moving-averages-in-python-4f8ed6d2416f
https://towardsdatascience.com/moving-averages-in-python-16170e20f6c
https://www.geeksforgeeks.org/how-to-calculate-moving-averages-in-python/
https://www.geeksforgeeks.org/how-to-decide-window-size-for-a-moving-average-filter-in-matlab/
14. Ссылки на GitHub
https://github.com/VISHCGIT/Vishnu-Rossmann-Sales-Prediction