Тип Syntetos Boylan Croston (SBC), аккуратный прогноз, структура спроса
Анализ временных рядов - широко используемый метод в бизнесе для получения полезной информации, такой как прогнозирование спроса, определение сезонных продуктов, категоризация моделей спроса и другие характеристики. Здесь мы сосредоточимся на прогнозировании временных рядов (с использованием статистической модели / машинного обучения / модели глубокого обучения для прогнозирования будущих значений) & категоризация моделей спроса (категоризация продуктов по количеству и времени).
В этом блоге я собираюсь объяснить, как мы можем подогнать несколько (1000+) моделей временных рядов, используя статистические (классические модели), модели машинного обучения и глубокого обучения, проектирование функций временных рядов и структуру спроса. категоризация. Эта серия будет состоять из следующих 5 частей:
Часть 1: Очистка данных и категоризация спроса.
Часть 3: Разработка функций временных рядов с использованием пакета timetk R.
Часть 4. Подходите Модели машинного обучения (XGBoost, Random Forest и т. д.) & Настройка гиперпараметров с использованием пакетов R.
Часть 5: Подгонка моделей углубленного изучения (NBeats и DeepAR) и настройка гиперпараметров с использованием пакетов R.
Давайте начнем!
PS: это не ЕДИНСТВЕННЫЙ метод решения этой проблемы. Однако это один из способов решить эту проблему.
Данные
Я использую данные с хакатона Прогнозирование спроса на продукты питания в AnalyticsVidhya. Цель этого хакатона - спрогнозировать количество заказов для каждой комбинации еды / центра для службы доставки еды. У нас есть в общей сложности 3 548 комбинаций приема пищи / центра (т. Е. 77 центров и 51 прием пищи), что означает, что модели временного ряда 3548 необходимо будет подогнать. Этот метод в деловой среде также известен как масштабируемое прогнозирование.
Давайте импортируем библиотеки.
pacman::p_load(tidyverse, magrittr) # data wrangling packages pacman::p_load(lubridate, tsintermittent, fpp3, modeltime, timetk, modeltime.gluonts, tidymodels, modeltime.ensemble, modeltime.resample) # time series model packages pacman::p_load(foreach, future) # parallel functions pacman::p_load(viridis, plotly) # visualizations packages theme_set(hrbrthemes::theme_ipsum()) # set default themes
Теперь прочтите данные поезда, чтобы они соответствовали моделям временных рядов, и данные отправки, чтобы предсказать будущие значения.
meal_demand_tbl <- read.csv(unz("data/raw/train_GzS76OK.zip", "train.csv")) # reading train data new_tbl <- read.csv("data/raw/test_QoiMO9B.csv") # the data need to forecast skimr::skim(meal_demand_tbl %>% # remove id select(-id) %>% # make center & meal id factors mutate(center_id = factor(center_id), meal_id = factor(meal_id))) # summary of data
Предварительная обработка данных
На этом этапе были выполнены этапы предварительной обработки данных. Затем эти данные были преобразованы в данные временных рядов (то есть в объект tsibble: это особый тип данных, который обрабатывает модели временных рядов в пакете fpp3).
Приведенная выше сводка показывает, что в 77 центрах продается 51 вид еды, что составляет в общей сложности 3 548 данных временных рядов, каждый из которых состоит из 145 недель. Здесь нам нужно будет спрогнозировать количество заказов (num_orders
) для каждой комбинации блюд / центр. Более того, посмотрев на столбец complete_rate
, мы можем увидеть, что в переменных нет пропущенных значений.
Столбец week
состоит из чисел от 1 до 145, поэтому нам нужно будет заменить его на даты. Также удалим комбинации (прием пищи / центр), которые не требовали прогнозирования.
date_list <- tibble(id = seq(1, 155, 1), week_date = seq(from = as.Date("2016-01-02"), by = "week", length.out = 155)) master_data_tbl <- meal_demand_tbl %>% left_join(date_list, by = c("week" = "id")) %>% # joining the date inner_join(distinct(new_tbl, meal_id, center_id), by = c("meal_id", "center_id")) %>% # remove combos that did not want to forecast select(week_date, num_orders, everything(), -c(week, id))
Теперь давайте преобразуем данные по обучению и отправке в полные данные, то есть превратим данные нерегулярных временных рядов в данные обычных временных рядов, вставив новые date
rows. Эти недавно созданные date
rows содержат пропущенные значения для num_orders
и других переменных. Следовательно, для переменнойnum_orders
было условно присвоено ноль, предполагая, что в эти конкретные недели не было продаж, а для других переменных мы заменили их соответствующими значениями предыдущей недели.
Например, следующие данные временного ряда (таблица 1) показывают, что после 4-й недели отсутствуют данные вплоть до 7-й недели. В таблице 2 показаны завершенные данные с новыми записями за те недостающие недели (т.е. недели 5 и 6).
Затем emailer_for_promotion
& homepage_featured
переменные преобразуются в коэффициент.
master_data_tbl <- master_data_tbl %>% as_tsibble(key = c(meal_id, center_id), index = week_date) %>% ## num_urders missing value imputation ---- fill_gaps(num_orders = 0, .full = end()) %>% # make it complete by max week dates ## X variables missing value imputation ---- group_by_key() %>% fill_(fill_cols = c("emailer_for_promotion", "homepage_featured", "base_price", "checkout_price")) %>% # filling other variables ungroup() %>% ## change variables to factor ---- mutate(emailer_for_promotion = factor(emailer_for_promotion), homepage_featured = factor(homepage_featured))
Аналогичная операция проводится с файломsubmission
.
## New Table (Submission file) data wrangling ---- new_tbl <- new_tbl %>% left_join(date_list, by = c("week" = "id")) %>% # joining the date full_join(new_data(master_data_tbl, n = 10), by = c("center_id", "meal_id", "week_date")) %>% as_tsibble(key = c(meal_id, center_id), index = week_date) %>% group_by_key() %>% fill_(fill_cols = c("emailer_for_promotion", "homepage_featured", "base_price", "checkout_price")) %>% # filling other variables ungroup() %>% # change variables to factor mutate(emailer_for_promotion = factor(emailer_for_promotion), homepage_featured = factor(homepage_featured))
Визуализация пищевых данных временного ряда
График 1. Количество заказов по центрам
master_data_tbl %>% # Randomly Pick 4 Centres distinct(center_id) %>% sample_n(4) %>% # Joining the transaction data left_join(master_data_tbl) %>% group_by(week_date, center_id) %>% # aggregate to centres summarise(num_orders = sum(num_orders, na.rm = T)) %>% as_tsibble(key = center_id, index = week_date) %>% fill_gaps(num_orders = 0, .full = end()) %>% autoplot(num_orders) + scale_color_viridis(discrete = T)
На приведенном выше графике показано, что первые несколько недель транзакций для Центра № 24 равны 0; эти транзакции были удалены. Однако после этого периода времени существуют непрерывные транзакции, которые были включены в данные для соответствия модели.
master_data_tbl <- master_data_tbl %>% filter(center_id != 24) %>% bind_rows(master_data_tbl %>% filter(center_id == 24 & week_date > as.Date("2016-07-16"))) # remove entries before 2016/07/16 for center 24
График 2: количество заказов по идентификаторам блюд
master_data_tbl %>% # Randomly Pick 4 Meals distinct(meal_id) %>% sample_n(3) %>% # Joining the transaction data left_join(master_data_tbl) %>% group_by(week_date, meal_id) %>% summarise(num_orders = sum(num_orders, na.rm = T)) %>% as_tsibble(key = meal_id, index = week_date) %>% fill_gaps(num_orders = 0, .full = end()) %>% autoplot(num_orders) + scale_color_viridis(discrete = T)
На приведенном выше графике показано введение новых блюд, что позволяет сократить данные временного ряда. Таким образом, существует вероятность того, что эти типы данных временных рядов следует обрабатывать отдельно с помощью метода перекрестной проверки.
Категоризация спроса - метод SBC.
Теперь мы собираемся определить каждую категорию модели спроса на комбинированные блюда / комплекс (S непостоянный, неустойчивый, неровный и прерывистый).
Почему?
Когда вы делаете прогноз на основе реальных данных (т. Е. Данных вашей организации), вы в конечном итоге получите большую часть своих продуктов со спорадическим спросом. Этот тип продуктов показывает низкую точность прогнозов, и их сложно повысить. Это связано с их низкой прогнозируемостью. Итак, что мы можем сделать с такими продуктами? Мы должны рассчитывать стоимость страхового запаса, а не тратить время на повышение точности прогнозов.
Более того, в большинстве случаев эти спорадические продукты не приносят высоких доходов. Это поможет нам разделить наш проект прогнозирования на две части. При регулярном спросе продукты ориентированы на повышение точности прогнозов, а продукты со спорадическим спросом рассчитывают страховой запас.
Кроме того, определение этих моделей спроса означает, что к ним можно применять различные модели временных рядов. Например, Croston и SBA подходят для спорадических моделей спроса.
Как?
В R мы можем использовать функцию idclass
в пакете R tsintermittent
. В функции idclass
, когда параметр type
равен SBC
, будут вычислены следующие два значения:
cv2
- измеряет изменение количестваp
- измеряет интервал между запросами
Основываясь на этих двух показателях, мы можем разделить структуру спроса на Сглаженный (p ‹1,32 & cv2‹ 0,49) , Неустойчивый (p ‹1,32 & cv2 ≥ 0,49 ) , неровный (p ≥1,32 и cv2 ≥0,49) и прерывистый (p ≥1,32 и cv2 ‹0,49) .
Плавный:
Плавная структура спроса показывает регулярный спрос и регулярное время. Т.е. этот вид товаров можно продавать каждый день или каждую неделю.
Ошибочно:
Неустойчивая структура спроса показывает регулярность во времени, но объем продаж сильно варьируется. То есть этот тип продуктов может продаваться каждый день или каждую неделю, однако, например, в один прекрасный день он может продать 3 количества, тогда как в другой день он может продать 100 штук.
Периодически:
Неустойчивая структура спроса показывает неравномерность во времени и регулярность в структуре количества. т.е. этот тип продукта продается в течение первой недели, затем в течение нескольких недель он не будет продаваться, но, в конце концов, продается такое же количество продукта.
Неровно:
Неровная структура спроса показывает неравномерность во времени и неравномерность в структуре количества. Этот конкретный тип структуры спроса трудно предсказать, независимо от того, какой тип моделей временных рядов используется. Решение для этого типа продукта - иметь страховой запас.
Приступим к кодированию!
Во-первых, мы преобразуем данные более длинного формата в более широкий формат, т. Е. Создаем 3 548 столбцов (общее количество данных временных рядов для приема пищи / центра). Например:
# make each combo ts as column wide_dt <- .x %>% transmute(week_date, id = paste0("x_", center_id, "_", meal_id), num_orders) %>% pivot_wider(names_from = id, values_from = num_orders, values_fill = 0) %>% arrange(week_date) %>% # arrange by week date select(-week_date) %>% data.frame()
Затем примените idclass
к преобразованному фрейму данных.
ts_cate_obj <- idclass(wide_dt, type = "SBC", outplot = "none")
ts_cate_obj
, показанный выше, представляет собой матрицу. Теперь мы изменим этот формат матрицы на thedata.frame
, а затем применим значения отсечения для категоризации моделей спроса.
ts_categorization <- data.frame(id = row.names(t(wide_dt)), cv2 = ts_cate_obj$cv2, p = ts_cate_obj$p) %>% separate(id, into = c("x", "center_id", "meal_id"), sep = "_") %>% select(-x) %>% mutate(demand_cate = case_when(p < 1.32 & cv2 < 0.49 ~ "Smooth", p >= 1.32 & cv2 < 0.49 ~ "Intermittent", p < 1.32 & cv2 >= 0.49 ~ "Erratic", p >= 1.32 & cv2 >= 0.49 ~ "Lumpy")) %>% mutate(center_id = as.integer(as.character(center_id)), meal_id = as.integer(as.character(meal_id)))
Давайте посмотрим сводку приведенного выше анализа в виде гистограммы.
Приведенный выше график показывает, что в данных большинство комбинаций приема пищи / центра временного ряда попадают в категорию «Плавный и непостоянный». Это означает, что хорошо подошла бы модель обычного временного ряда, такая как ARIMA, ETS и т. Д. Кроме того, были установлены передовые модели, такие как Croston & SBA, чтобы справиться с неустойчивой и неоднородной структурой спроса. Модели машинного обучения / глубокого обучения также можно адаптировать, используя этот тип шаблона спроса в качестве функции. Метод перекрестной проверки использовался для соответствия комбинациям без спроса (т. е. транзакций менее 20).
В следующих частях мы проведем проектирование функций, подгоним модели временных рядов, модели машинного обучения, модели глубокого обучения и сравним их точность, чтобы найти подходящую модель.
Ссылки
Куренцес, Н., 2014. Пакет периодического прогнозирования спроса для Р. - Николаоса Курентеса. Kourentzes.com. Доступно по адресу: ‹https://kourentzes.com/forecasting/2014/06/23/intermittent-demand-forecasting-package-for-r/› [по состоянию на 22 января 2021 г.].
БЕСПЛАТНО. 2021. Классификация спроса: почему имеет значение прогнозируемость - Frepple APS. Доступно по адресу: ‹https://frepple.com/blog/demand-classification/› [по состоянию на 22 января 2021 г.].