![]() |
![]() |
![]() |
|||||
![]() |
Как запустить ML-прототип за один день. Доклад Яндекс.Такси |
||||||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2019-04-09 08:41 Машинное обучение применяется на всём цикле заказа автомобиля в Яндекс.Такси, и число компонентов сервиса, работающих благодаря ML, постоянно растёт. Чтобы строить их единообразно, нам потребовался обособленный процесс. Руководитель службы машинного обучения и анализа данных Роман Халкечев рассказал про препроцессинг данных, применение моделей в продакшене, сервис их прототипирования и сопутствующие инструменты.
Давайте сформулируем проблему. Есть пользователи Такси, которым нужно добраться из точки А в точку Б, и есть водители, которые готовы за определенную сумму доставлять этих пользователей из точки А в точку Б. У пользователя есть несколько состояний, в которых он находится. Он вызывает такси, выбирает точку А, точку Б, тариф и так далее, производит посадку в такси, едет, и наконец, производит высадку. Cегодня я бы хотел поговорить про посадку в автомобиль и проблемы, которые могут при этом возникать. ![]() ![]() С другой стороны, проблемы могут быть и у вас как у пользователя. Водитель приехал, все хорошо, но вам неудобно садиться, потому что все перекопали. Вы просите водителя подъехать куда-то еще. Бывают и другие причины. Самым наглядным примером, квинтэссенцией всех перечисленных может служить аэропорт, в котором выполняется примерно всё. Даже если вы вылетаете из Шереметьево очень часто, все равно это незнакомая для вас локация, потому что там часто многое меняется. Там много людей, много машин, есть удобные места для посадки, есть неудобные, но про это, как правило, никто из нас не помнит. ![]() Для начала, «удобно» — субъективное понятие. Кажется, что перед тем, как решать задачу, нужно сформулировать некоторые критерии того, что задача будет решена правильно. Мы для себя сформулировали три основных. Первый критерий — как в любой задаче рекомендаций: наверное, рекомендации хороши, если ими пользуются. Если мы будем показывать такие точки, из которых пользователь действительно будет уезжать — наверное, это хорошие точки. Но это, разумеется, еще не всё, потому что можно научиться что-нибудь рекомендовать, показывать, сподвигнуть пользователя этим воспользоваться, но какого-то ощутимого профита не получить (не получим ни мы как система, ни пользователь, ни водитель). Поэтому очень важно смотреть на другие метрики. Мы выбрали две. Если мы подскажем такое место посадки, к которому водителю будет легко подъехать, то время подачи автомобиля должно снизиться. С другой стороны, если в этом месте пользователю будет легче найти автомобиль, легче произвести посадку, то должно уменьшиться время ожидания водителем пользователя. Это некоторая наша гипотеза, которую мы принимаем на веру, и это некоторые метрики, на которые мы смотрим, когда делаем эти рекомендации. Но разумеется, это не единственные метрики, на которые можно смотреть. Их можно придумать еще с десяток. Я думаю, каждый из вас может придумать свою сотню таких метрик. Вот еще некоторые примеры. Это может быть доля отмен до поездки. По идее, она должна снизиться, если пользователю будет легче произвести посадку. Условно, это звонки, когда пользователь звонит водителю, пытаясь его найти, или, наоборот, водитель звонит пользователь до того, как поездка началась. Это обращение в поддержку, и еще с десяток других. Мы сформулировали проблему. Мы примерно поняли критерий того, что мы эту проблему умеем решать. Давайте теперь подумаем про то, как можно решить эту проблему. Первое, что приходит на ум: а давайте какие-нибудь такие проверенные и понятные точки посадки будем рекомендовать. Здесь на слайде изображен пример торгового центра «Европейский». И мы знаем точно, что к выходам из этого торгового центра можно подъехать, и это некоторый ориентир, благодаря которому пользователь может найти водителя. Это могут быть какие-нибудь организации. Есть пример с «Азбукой вкуса» в каком-нибудь торговом центре. По-моему, это «Ереван Плаза». Это тоже некоторый ориентир для пользователя и водителя, про который мы знаем, что туда подъехать можно. ![]() Для машинного обучения нужны какие-то данные, и эти данные у нас на самом деле есть. Еще один способ решить проблему автоматически — использовать эти данные. Высокоуровнево идея заключается в том, что у нас есть данные про GPS, логи приложения, и есть граф дорог. И мы можем понять, где пользователи на самом деле садятся в машину. Не те точки, в которые они вызывают машину, а там, где они производят посадку. И на основе этого сделать что-нибудь в таком духе. ![]() Я высокоуровнево рассказал про нашу задачу. Теперь давайте подробнее поговорим про то, из каких этапов состоит решение этой задачи. Понятное дело, что есть этап подготовки данных. ![]() Это были исходные данные. А на выходе мы хотим две вещи. Это какие-то так называемые кандидаты в точки посадки. Каким образом они получаются? Жалко, что не получилось показать видео. Происходит приблизительно следующее. У нас есть много точек GPS, в которых мы знаем, что водитель перешел из статуса «Ожидаю пассажира» в статус «Поехали». Мы их можем, условно, притянуть к графу, то есть спроецировать на граф дорог, потому что, как правило, машина начинает движение от какой-то дороги. На этом графе какую-то кластеризацию этих точек выполнить. И получить большое число кандидатов — это места, в которых какие-то пользователи садились в автомобиль, и им это было нормально, удобно. Не куда они вызывали, а где они в итоге сели. После этого, когда у нас есть очень много кандидатов и у нас есть некоторый пользователь в онлайне, мы знаем его местоположение, вот он открыл приложение и хочет вызвать такси, то мы можем из большого числа кандидатов выбрать самые лучшие пять, и показать их. Самые лучшие пять определяет некоторая модель машинного обучения, которая учится ранжировать всех кандидатов по вероятности того, что пользователь прямо сейчас в это время с учетом его местоположения и с учетом его истории поездок удобнее всего уехать. И приблизительно так мы можем эти точки автоматически генерировать. Причем, если в какой-то момент где-то, условно, перекопают, то есть станет вызывать такси неудобно, или где-нибудь поставят знак, запрещающий остановку, и водители и пользователи действительно перестанут производить посадку в этом месте, то в какой-то момент алгоритм это поймет, и данные обновятся. ![]() ![]() Наконец, когда пайплайн готов, нам нужно его автоматизировать, чтобы была актуальность данных, и для этого мы используем такую вещь как Nirvana и Hitman. Это тоже внутрияндексовские разработки. Nirvana — это фреймворк по управлению вычислениями на кластере. На самом деле, она умеет примерно любую программу запускать, быть отказоустойчивой, быть cross DC (00:14:53). И в случае, если что-то падает, она умеет это перезапускать, создавать запуски по наступлению каких-нибудь событий. и т. д. ![]() ![]() Задачу сформулировали, критерии успеха сформулировали, научились как-то решать ее в офлайне, сделали даже какую-то модель, и по каким-то офлайн-метрикам она вроде работает — предсказывает действительно те точки, из которых пользователь уезжает, и находит те точки, которые, казалось бы, должны снижать время ожидания и подачи автомобиля. ![]() Очень поверхностная схема выглядит так. Есть пользователи, у них есть приложение, а есть водители, у них тоже есть приложение, называется «Таксометр». Эти приложения как-то общаются с бэкэндом, а бэкэнд представляет из себя набор микросервисов, которые между собой общаются — про это рассказывал Илья. Один из микросервисов — наш сервис, наша команда его делает, он называется ML as a Service, MLaaS. ![]() Каждой функциональности, например, этим точкам посадки — внутри мы называем их pickup points, — или, например, подсказкам точек Б, про которые Илья говорил и всё время ломал в предыдущем докладе, каждой такой функциональностью, где есть какое-то машинное обучение, соответствует handler, который хранит в себе логику получения запроса, генерации факторов машинного обучения, и применения моделей, и генерации ответа. Разумеется, этот сервис не изолирован, умееть ходить в какие-то дополнительные источники данных, базы данных, какие-то другие микросервисы. ![]() ![]() В первую очередь, это проблема экспериментов. Например, data scientist'у, который работает у нас в команде, пришла идея. Если запустить какой-нибудь алгоритм кластеризации или классификации чуть с другими параметрами, то можно добиться лучшего качества. Он попробовал проверить свою гипотезу в офлайне, встроился в наш Python-процесс, посчитал, и действительно получается. И теперь он хочет AB-эксперимент, то есть части пользователей показать новый алгоритм и измерить некоторые метрики уже в онлайне: падает ли действительно время подачи, ожидания, растёт ли использование. Для этого ему приходится, условно, пять версий своего алгоритма, в которые он верит, которые в офлайне дают хорошее качество: реализовывать на C++ и проводить AB-эксперимент. И после этого AB-эксперимента, возможно, все пять пойдут в утиль, то есть качество от них в онлайне окажется хуже, чем было в офлайне, то есть хуже, чем в продакшене. То есть процесс экспериментирования занимает большое время из-за того, что, условно, два разных языка, две разных технологии. Это для существующих фич. А еще есть новые. Когда-то эти pickup points тоже были идеями, которые хотелось быстро проверить. Не тратить на это два месяца разработки — желательно получить что-то за три недели. Создать такой прототип довольно трудоемко. Сперва на Python написать извлечение фич, просто потому что это удобно — move fast, что называется. На Python можно собрать любой прототип, есть много библиотек для анализа данных. Ты поэкспериментировал в своем ноутбуке, а теперь хочешь проверить на пользователях. И сделать прототип получалось довольно тяжело. Мы пришли к тому, что нам нужен какой-то дополнительный сервис, чтобы такие прототипы собирать довольно быстро — условно, за неделю или даже за день, — а также проводить AB-эксперименты. ![]() ![]() Он нам так понравился, что возникла идея — а почему бы его всё время не использовать? Потому что, условно, есть фичи, которые требуют большой нагрузки, 1000 RPS, большие требования по памяти. Хочется иметь довольно гибкую параллельность. Но для каких-то фич, для каких-то продуктов или сервисов, в которых нет таких больших требований по нагрузке, производительности, RPS и так далее, мы этот сервис вполне успешно используем. ![]() Возвращаясь к задаче про pickup points — гипотеза оказалась верной. Польза от таких точек и рекомендаций удобных мест посадки вполне ощутима. Время подачи автомобиля упало, время ожидания также упало. Сейчас примерно 30% всех поездок осуществляются из точки, которую мы рекомендуем. Большое спасибо за внимание. Источник: habr.com ![]() Комментарии: |
||||||