Это первая публикация из нашей серии о машинном обучении

Авторы Тайво Кяспер, Антон Потапчук и Максим Мишин

Если попросить описать Sixfold одним предложением, разумным ответом будет: «Мы оцениваем время прибытия миллионов грузовых грузовых автомобилей». Расчетное время прибытия (ETA) - это основа нашей деятельности. Мы ежедневно вычисляем миллионы прогнозов ETA и делаем это без серьезных инцидентов в течение почти четырех лет.

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

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

Какую проблему мы пытаемся решить?

На первый взгляд, прогноз ETA кажется относительно простым. В конце концов, поставщики онлайн-карт, такие как Google Maps или HERE Maps, похоже, без проблем предсказывают расчетное время в пути для всех видов режимов движения. Действительно, до тех пор, пока у человека есть доступ к ограничениям скорости для грузовиков и можно получить обновленный график дорожной сети, расчет времени в пути существенно сокращается до расчета оптимального пути.

Вопрос становится гораздо менее однозначным, если мы вспомним, что водители грузовиков - это люди! Например, Google Maps сообщает, что время в пути между Берлином и Мадридом составляет примерно 23 часа.

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

В Sixfold мы решили применить подход машинного обучения (ML) для решения этой проблемы. В отличие от классических алгоритмов, модели машинного обучения могут учиться на данных, к которым у нас есть доступ. Имея достаточно богатую информацию, они могут определять маршруты, распорядки и возможные задержки, которые предпочитают водители, с которыми водители грузовиков могут столкнуться по пути.

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

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

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

Конечно, мы понимаем, что принятый нами подход далек от совершенства - погрешность все-таки не равна нулю! Если у вас есть идеи или предложения, не стесняйтесь оставлять комментарии или связываться с нами!

Набор данных

На высоком уровне Sixfold работает с двумя типами данных.

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

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

Изначально нам удалось обойтись управляемым предложением PostgreSQL от Google Cloud - Cloud SQL, но вскоре мы решили перейти на подходящее решение для облачного хранилища данных.

Между Snowflake и BigQuery мы выбрали BigQuery из-за его обширной поддержки географических функций и хорошей интеграции с экосистемой Google. Единственным недостатком BigQuery является то, что он не подходит для частого изменения данных. Таблицы, содержащие такие данные, хранились в нашем старом хранилище данных PostgreSQL. Поскольку BigQuery может получать доступ к данным в базах данных Cloud SQL, у нас не возникло никаких проблем.

Еще одна часть нашего конвейера данных - это управляемый Google Airflow - Cloud Composer. Мы ввели его, как только поняли, что наши данные слишком зашумлены и запутаны для обучения машинному обучению - модели обычно работают лучше, когда они обучаются на чистых данных.

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

Мы решили не кэшировать эти дополнительные функции (также известные как использование хранилища функций), поскольку вычисление этих свойств может выполняться на лету внутри BigQuery - запрос выполняется менее 10 минут и обрабатывает около ТБ данных. Окончательный результат сохраняется в формате Parquet в облачном хранилище Google.

Kubeflow

Весь наш рабочий процесс обучения ML ETA разработан как единый конвейер Kubeflow, визуализированный на рисунке ниже.

Он еженедельно повторно обучает модель и выполняет различные проверки только что обученной модели. После того, как модель пройдет все тесты, конвейер автоматически открывает запрос на вытягивание GitHub, который должен быть одобрен инженерами - этот ручной шаг служит дополнительной мерой безопасности, позволяя инженерам просматривать числа и гарантировать, что они кажутся разумными. Весь процесс обучения был специально разработан таким образом, чтобы любой инженер мог уверенно обновить модель, следуя пошаговым инструкциям, прилагаемым к запросу на вытягивание. В дополнение к этапам оценки и автоматическим тестам у нас также есть мониторинг платы Grafana, а также сквозные тесты, которые непрерывно отслеживают производительность модели как в промежуточной, так и в производственной средах.

Мы всегда сравниваем текущую действующую модель с повторно обученной моделью, чтобы установить базовую производительность и обеспечить хотя бы некоторый уровень защиты от потенциального дрейфа концепции. Еще один уровень защиты от неизвестного добавляется еженедельным повторным обучением модели. Мы более подробно рассмотрим мониторинг модели в одном из следующих постов.

Опытно-производственные этапы моделей

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

Все эти исследования были очень полезными и значительно ускорили процесс внедрения, но взять код из записных книжек непросто - в записных книжках данные, подготовка данных и предварительная обработка отделены.

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

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

Одно интересное различие между производственной средой и средой обучения связано с базами данных.

Наши обучающие данные собираются в BigQuery, а в производственных средах используется PostgreSQL. У этих двух есть некоторые заметные различия в реализации; это означает, что даже если код выглядит одинаково, результаты могут быть разными.

Некоторые примеры включают функцию ST_Distance, которая в PostgreSQL использует вычисление сфероидов, но BigQuery в настоящее время приближает Землю к плоской. То же самое касается расчета дня недели, который в одной базе данных начинается с 0, а в другой - с 1. Такие ошибки легко могут остаться незамеченными, особенно если они влияют только на несколько прогнозов.

Полный конвейер

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

Большинство моделей машинного обучения ожидают, что данные будут в числовом формате, поэтому логические значения (None, False, True), категории (loading, unloading), даты, тексты, изображения и т. Д. Необходимо каким-либо образом или в форме преобразовать в числа. К счастью, наша установка ML относительно проста и использует табличные данные, где нам нужно только преобразовать логические значения, категориальные значения и заполнить некоторые пропущенные значения.

Есть много разных способов кодирования (представления) нечисловых значений. В конечном итоге разработчик модели должен выбрать формат кодирования, который лучше всего работает в данном контексте. После принятия решения стратегия кодирования должна быть везде одинаковой, иначе вы снова рискуете получить разные прогнозы в разных средах.

Мы поэкспериментировали с несколькими различными стратегиями предварительной обработки и в конце концов остановились на конвейерах scikit-learn.

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

Прежде чем остановиться на scikit-learn, мы постарались разделить предварительную обработку данных и модель. Это означало, что всякий раз, когда кто-то хотел загрузить модель и сделать прогнозы - на этапах оценки, производства или исследования - сначала нужно было загрузить код и состояние логики предварительной обработки, преобразовать данные, а затем передать преобразованные данные в модель в правильный путь. Этот подход оказался очень подверженным ошибкам.

С конвейерами scikit-learn вся эта логика закодирована прямо в модели, устраняя ошибки, которые в противном случае могли бы возникнуть из-за неправильного использования модели.

Резюме

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

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

В следующих статьях мы более подробно остановимся на этом подходе, рассмотрим, как модель работает в производственной среде и как мы отслеживаем ее эффективность.