Skip to content

MikhailovDaniil/demand_forecasting_hackathon

Repository files navigation

demand_forecasting_hackathon

preprocessing.py - предобработка данных перед предсказанием спроса по дням

daily_demand.py - предсказание спроса в каждом регионе по дням

orders_partners.py - распределение количества заказов по часам + поиск оптимального количества доставщиков

simplex_method.py - поиск оптимального распределения доставщиков по сменам

./input/ - raw data from slack/CMF2022/hackathon-workshifts

./proceeded/ - промежуточные и конечные данные, получаемые и используемые в процессе решения

./notebooks/ - jupyter notebooks, в которых мы работали над задачей

Предсказание количества заказов по дням

Предсказание количества заказов в каждый из дней следующей недели строилось на основе нормированного количества заказов за последние 21 день.

Нормировка производилась на медиану по количеству заказов за последние 7 дней. Такой подход позволяет обучаться на всех данных, не учитывая регионы и их особенности (в каких-то заказов сильно больше, в каких-то - сильно меньше).

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

В качестве моделей бралась линейная регрессия. Её точность (MAPE) на тестовой выборке составила ~18.

Интуитивным объяснением предсказаний такой моделью можно назвать "умное" скользящее среднее - линейная регрессия подбирает коэффициенты, давая больший вес более свежим данным и учитывая то, какой день недели мы предсказываем (модель для вторника дает больший вес дням у вторников, и так далее)

Output: ./proceeded/predictions/

Распределение количества заказов по часам

Были взяты предсказания количества заказов по дням недели, а также были внесены в таблицы столбцы 'Часы' и 'День недели'. Каждый день недели был сгруппирован по дате и региону доставки. Далее на основании предсказаний и плотности распределния было сформировано число необходимых заказов по часам. То есть плотность распределения заказов умножалась на предсказания, тем самым преобразуя данные в столбце orders_cnt в нужные значения, которые уже были сопоставимы с колонкой hour. И так для каждого дня недели.

Output: ./proceeded/orders/

Поиск необходимого количества партнеров

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

Далее на тренировочной выборке был составлен прогноз опоздания для каждого случая, механизм был применен для тестовой выборки. Далее проходил отбор оптимального соотношения числа курьеров и заказов, а также минимального опоздания. Распределяем по убыванию опозданий, как только опоздание меньеше 0.05 по прогнозу, то выбираем данное в этой строке число курьеров. Однако ставится дополнительное ограничение на максимальное число курьеров: если число пронозируемых курьеров в 2 или более раза больше числа заказов, то сокращаем курьеров до разумного числа. Данные выбросы объясняются недостаточным количеством данных, например, отсуствием реальных названий регионов, местности, количества населения, погодных условий и тп. Параметры важные для точности, так что при текущих данным всплывают погрешности.

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

Output: ./proceeded/orders/

Распределение партнеров по сменам

Для нахождения оптимального распределения курьеров по сменам был использован симплекс-метод(библиотека scipy.optimize, linprog). Распределение считалось отдельно для каждого дня каждого региона(в итоге имеем 7 таблиц для каждого дня отдельно). В качестве данных были использованы таблицы с оптимальным количеством курьеров по часам, полученные из предыдущего пункта.

Чтобы учесть то, что магазины в разных регионах открываются и закрываются в разное время, и занести показания для всех регионов доставки в одну таблицу, был взят минимальный час открытия и максимальный час закрытия магазинов на всех территориях доставки и составлена таблица со всеми возможными вариантами смен, ограниченных данными часами. Далее, циклом для каждого региона отдельно была посчитана матрица со всеми возможными сменами, учитывая индивидуальное время работы магазина, затем был использован симплекс-метод(на вход подавалась матрица смен, нужное количество курьеров в данный час и массив коэффициентов). Получившиеся данные переносились в общую таблицу, учитывая время начала и конца смены.

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

Output: ./proceeded/shifts/

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published