Оптимальное время сдачи с использованием машинного обучения

Компромисс между эффективностью и своевременностью

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

Время имеет значение

Покупатели ценят удобство доставки продуктов на кухню. Чтобы сделать работу еще более удобной, Picnic сообщает короткое временное окно в день доставки, когда доставщик или посыльный будет у дверей клиента. Это временное окно длится всего 20 минут и попадает в часовой интервал, выбранный клиентом при размещении заказа. Чтобы мы могли сделать клиента счастливым, доставив его продукты в течение этих 20 минут, системе распределения Picnic необходимо спланировать достаточно времени, чтобы бегун мог легко прибыть к клиенту вовремя.

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

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

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

Путь к успеху

Мы начали с исследовательского анализа данных и искали факторы, влияющие на продолжительность доставки. Эти факторы можно условно разделить на четыре области: 1) клиент, 2) заказ, 3) регион и 4) бегун. Был изучен широкий спектр функций, от среднего времени доставки клиента и общего веса доставки до прогнозов погоды и плотности адресов. Естественно, доставка большого и тяжелого заказа, состоящего из нескольких пакетов с продуктами, занимает намного больше времени, чем заказа, содержащего всего пару товаров. Были также функции, которые мы хотели бы иметь, но мы не могли создать их с имеющимися у нас данными. Например, мы хотели бы знать, на каком этаже живет клиент, так как это может сильно повлиять на время сброса. Как вы понимаете, доставка клиенту на верхнем этаже четырехэтажного жилого дома занимает намного больше времени, чем доставка клиенту с входной дверью на уровне улицы. Для таких функций, которых у нас нет, мы создали прокси-переменные. В этом примере мы использовали плотность адресов и историческое время возврата клиента.

Кроме того, мы также должны были убедиться, что выбрали разумную функцию потерь. Несмотря на то, что у нас есть отличное хранилище данных, которое собирает данные из различных серверных систем и третьих сторон, иногда полученные данные могут содержать аномальные записи. Например, странные временные метки приводят к тому, что записанное время прекращения доставки отличается от реального. В этом случае мы, к счастью, смогли выявить большинство аномальных записей и отфильтровать их с помощью некоторых бизнес-правил. Кроме того, мы решили использовать функцию потерь, которая обрабатывает выбросы иначе, чем обычная функция потерь среднего квадрата ошибки, используемая для задач регрессии. Используемая нами функция потерь представляла собой потерю Хубера, комбинацию квадрата потерь и абсолютных потерь. Эта функция, как и среднеквадратичная ошибка, наказывает большие ошибки более серьезно, чем маленькие ошибки. Однако, когда ошибки превышают некоторый порог, определяемый параметром δ (обозначенный пунктирными линиями на рисунке ниже), потеря Хубера использует линейные потери, чтобы не придавать слишком большое значение этим потенциально аномальным ошибкам.

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

Пора на тест-драйв

Оценив несколько вариантов, мы получили многослойный персептрон (MLP). Эта модель показала наивысшую производительность, и со всеми хорошо разработанными фреймворками глубокого обучения, доступными в настоящее время, она привела к тому, что код был едва ли более сложным. По сравнению с текущей ситуацией, модель MLP уменьшила ошибку примерно на 30% при оценке исторических данных тестирования. Данные включали все центры Picnic (сайт, с которого Picnic осуществляет доставку в один или несколько городов) в Нидерландах. Если эти результаты применить на практике, это будет означать, что мы сможем значительно сократить буфер безопасности.

Чтобы проверить, как новая модель будет работать в реальности, мы решили провести быстрый эксперимент в одном из центров Picnic. На период в одну неделю мы спланировали все поставки с использованием времени доставки, рассчитанного по модели MLP. По прошествии этой недели мы обнаружили, что эффективность, измеряемая количеством доставок за поездку, увеличилась для этого конкретного хаба примерно на 20%. Своевременность снизилась только примерно на 2 процентных пункта. Небольшое снижение, но с помощью критерия согласия оказалось статистически значимым. Уменьшение может быть связано с неожиданными событиями во время поездки, такими как дорожные заграждения или пробки. Когда у вас недостаточно безопасного буфера сверх расчетного времени доставки, эти неожиданные события приводят к задержке доставки некоторых заказов. В целом испытание прошло успешно, и мы планировали выпустить модель по всей территории Нидерландов.

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

Готовы принять вызов?

Вас интересуют такие вызовы и вы хотите внести свой вклад в развитие Picnic как специалист по данным? Тогда перейдите по этой ссылке и свяжитесь с нами!