Любой из нас перед покупкой продукта или услуги старается узнать точную цену. Понятно, что порой случаются истории, когда финальная стоимость сильно превышает запланированную. И если с ремонтом машины или квартиры это уже стало привычным, то в остальных случаях разница между ожиданием и реальностью скорее раздражает.
До недавнего времени стоимость поездки в такси тоже была плавающей. Даже онлайн-сервисы рассчитывали сумму лишь примерно — окончательная стоимость формировалась только в конце пути. Тариф, как правило, включает три компонента: стоимость посадки (иногда с включенными километрами и/или минутами), стоимость километра и стоимость минуты. Конечно, можно было рассчитать примерную цену за поездку и раньше, но в конце она могла измениться из-за того, что, например, по пути водитель задержался в пробке. Понятно, что пассажирам это не всегда нравилось.
Кажется, нет ничего проще, чем использовать данные маршрутизатора в Яндекс.Навигаторе и данные Пробок, чтобы Яндекс.Такси с самого начала рассчитало точную цену, которая не менялась бы по окончании поездки. Но на самом деле на стоимость влияет огромное число факторов, не только тариф. Важно не просто уметь её рассчитывать. С одной стороны, стоимость должна быть привлекательной для пользователя, причём с учётом не только текущей ситуации на дороге, но и, например, пробок, которых на маршруте пока нет, но которые скоро возникнут. С другой, цена должна быть такой, чтобы водители не потеряли в заработке, даже если путь из точки А в точку Б оказался длиннее или дольше, чем планировалось. В этой статье мы расскажем, как решали задачу и как искали сбалансированный алгоритм, выгодный всем участникам платформы Яндекс.Такси.
Маршрут и время
Для того чтобы иметь возможность рассчитывать сбалансированную стоимость поездки, мы должны были научиться точно прогнозировать длину и продолжительность маршрута. Давайте разберёмся, как вообще исходно работает наш маршрутизатор.
Это довольно сложная система, которая строит маршрут из одного пункта в другой на основе другой системы попроще — дорожного графа. Граф выглядит так же естественно, как вы наверняка себе его и представляете: каждая дорога соответствует одному или нескольким рёбрам, а перекрёстки и разветвления дорог находятся в вершинах. Этот граф — направленный (так как дороги — это тоже штука направленная).
Так выглядит дорожный граф в районе московского офиса Яндекса
Наиболее важная характеристика рёбер графа — средняя скорость движения по ним в данный момент. Она зависит от текущей дорожной обстановки и от правил дорожного движения (например, ограничений скорости). Каждую секунду мы получаем десятки тысяч обезличенных сигналов — GPS-треков — от пользователей геосервисов Яндекса, агрегируем их, а далее за счёт фильтрации и интерполяции делаем сигнал более качественным и менее шумным. На финальной стадии вычисляем текущую скорость ребра в режиме реального времени (подробнее о том, как работают Пробки можно прочитать здесь).
Адрес — «вершина» виртуального графа — состоит из ребра дорожного графа и направления движения по нему:
Что происходит, когда вы заказываете поездку в приложении? Мы отправляем запрос в маршрутизатор для того, чтобы найти оптимальный маршрут от точки посадки (А) до пункта назначения (Б), который указан в заказе. Маршрутизатор, в свою очередь, проецирует точку А на граф, чтобы найти её «адрес» — комбинацию ребра и направления. То же самое происходит с точкой Б. И уже здесь проявляется первая особенность системы: процесс определения кратчайшего пути происходит не в оригинальном, «естественном» дорожном графе, а в неком «виртуальном». Его вершинами являются уже не перекрёстки, а те самые «адреса», а рёбрами — не улицы, а «манёвры», то есть переходы из одного «адреса» в другой.
Представление одной и той же траектории движения в дорожном (слева) и в виртуальном (справа) графах
Движение по прямой тоже может состоять из маневров виртуального графа: для удобства длинная дорога при оцифровке превращается в несколько ребер
Как мы помним, наша задача — найти оптимальный маршрут, при этом, разумеется, конечному «физическому» маршруту будет совершенно всё равно, построили ли мы его в «естественном» графе или «виртуальном». Но для начала нужно определиться, что такое оптимальность. С одной стороны, очевидно, что в городе это самый быстрый путь из А в Б. С другой стороны, иногда сложный маршрут по маленьким улицам и в обход больших магистралей хоть и даёт экономию в 2 минуты, но, за счёт большого количества поворотов оказывается значительно «дороже» для автомобилиста. Поэтому для начала мы определили функцию, которая задает «стоимость» манёвра и решили оптимизировать её с помощью машинного обучения.
Простейшим примером такой функции может быть длина рёбер, составляющих манёвр, разделённая на среднюю скорость движения по этим рёбрам, — так называемое «геометрическое время». Эта метрика хороша своей простотой, однако она зачастую не учитывает целый ряд особенностей конкретного манёвра. Возьмём для примера поворот налево. Очевидно, что совершить его со второстепенной дороги на регулируемом перекрестке — это совсем не то же самое, что свернуть на съезд, двигаясь по магистрали. Особенности каждой отдельной ситуации могут значительно увеличить время совершения всего манёвра, и чтобы их учесть, мы решили описать каждый манёвр набором признаков: длина составляющих его рёбер, геометрическое время проезда, функциональные классы дорог, наличие выделенной полосы общественного транспорта и так далее. Здесь же естественным образом возникли «признаки будущего»: например, мы можем заранее рассчитать время на прохождение манёвра с учётом пробок, которые возникнут к тому моменту, когда мы к этому манёвру приблизимся.
В итоге у нас получилось более 70 разных признаков, влияющих на «стоимость» маршрута, и их количество постоянно растёт, потому что мы постоянно добавляем новые сигналы, которые могут стать признаками и помочь в нашей задаче.
Ещё одна особенность нашего подхода в том, что исходную задачу мы разделили на две: построение маршрута и уточнение времени проезда по нему. Эти модели мы назвали, соответственно, «маршрутной» и «временнoй», и стоит рассказать подробнее, чем они друг от друга отличаются и почему нам нужно именно две модели.
Маршрутная модель служит для выбора оптимального пути из точки А в точку Б из множества вариантов, основываясь на длине маршрута и времени проезда по нему. Загвоздка здесь в том, что маршрутная модель должна выдавать ответ очень и очень быстро, потому что после неё системе нужно время, чтобы эти расчёты использовать в дальнейший цепочки процессов. Скажем, 100 миллисекунд на расчёт 1000 маневров — это слишком много, нужно на порядок меньше. Маршрутная модель должна быть как можно менее затратной в плане вычислений, поэтому она учитывает сокращённый набор признаков. А вот когда у нас уже есть оптимальный маршрут — мы хотим как можно точнее знать время проезда по нему, и здесь мы уже не так связаны быстродействием, можно и 100 миллисекунд себе позволить.
Для этого и существует временнaя модель, единственная задача которой — уточнение времени проезда по уже выбранному пути. Временнaя модель учитывает полный набор признаков для каждого маневра, а также параметры запроса пользователя из приложения: текущее местное время и различные макрохарактеристики маршрута — например, коэффициент перепробега (отношение длины реального маршрута из А в Б к расстоянию между этими точками по прямой). На выходе временнaя модель выдаёт уточнённое время проезда.
Подытожим: наша исходная задача «как наиболее точно построить маршрут и спрогнозировать время поездки по нему» свелась к нескольким шагам. Во-первых, мы перешли от «естественного» графа с вершинами-перекрестками и рёбрами-улицами к «виртуальному» графу, рёбрами которого являются манёвры, то есть переходы из «адреса» в «адрес». Каждый из этих манёвров мы описали набором из более 70 признаков. Во-вторых, для того чтобы оптимизировать работу маршрутизатора, мы решили, что предсказательных моделей будет две: маршрутная, которая быстро, но грубовато, выбирает нужный маршрут из множества возможных, и временнaя, которая уточняет время проезда по оптимальному маршруту. Теперь о том, как эти модели работают.
Модели
Несмотря на то, что и маршрутная, и временнaя модели сильно отличаются друг от друга, у них, по сути, схожая задача — рассчитать время проезда по маршруту. Ключевое отличие — в сложности используемых вычислений, то есть в количественном, а не качественном факторе. При этом, раз у моделей одинаковая задача, то и подход с точки зрения их обучения одинаковый. Мы можем взять только одну модель — временнyю, — а затем убрать из нее «всё лишнее» (например, лишние признаки) и получить таким образом более легковесную маршрутную модель.
Такой подход оказался выигрышным не только из-за того, что он унифицировал метод машинного обучения, но и по другим причинам, в том числе и потому, что обучение временнoй модели — это задача классическая, что называется, «из учебника». У нас есть огромная база историй поездок, то есть очень много пар «маршрут — время», которую можно использовать в качестве выборки для какого-нибудь метода машинного обучения. Маршрутную модель обучить сложнее, потому что мы не можем заставить всех водителей кататься по всем вариантам маршрутов из точки А в точку Б, чтобы сравнить, какой из них быстрее. В итоге на первом этапе мы сконцентрировались именно на обучении временнoй модели.
Первой идеей было просто использовать линейную модель над суммой признаков манёвров по маршруту, а в качестве цели обучения брать реальное время проезда. Этот подход обладает естественной для задачи характеристикой — собственно, линейностью. Действительно, рассчитанное таким образом время для маршрута, состоящего, например, из двух манёвров, равно сумме времён, рассчитанных для каждого из манёвров по отдельности. Не было никаких сложностей и с интерпретацией различных признаков, что всегда приятно: если вес при признаке большой, значит признак значимый.
Тем не менее, несмотря на кучу преимуществ, первые же попытки обучить эту модель оказались огорчающими: результаты были немногим лучше «геометрического времени», потому что мы теряли много информации, заложенной в категориальных (то есть нечисленных) признаках манёвров — например, функциональный класс дорог, форма ребра, уровень дороги над землёй и другие остались «за бортом».
Вот как рассчитывается цена поездки в момент заказа:
Как мы знаем, учёт категориальных переменных — это всегда непростая задача, недаром для этого целый CatBoost придумали. И всё же мы попробовали решить эту проблему, воспользовавшись приёмом, аналогичным N-way-split, который используют в решающих деревьях.
Учтём, что по классификации Народных Карт дороги делятся на 9 функциональных классов, а ещё бывает 5 видов конструктивных особенностей: две проезжие части, круговое движение, съезд, дублёр, разворот. К тому же на дороге или есть светофор или его нет — это ещё два значения. Итого имеем 9х5х2=90 комбинаций. Теперь для каждой такой комбинации категориальных признаков будем отдельно учитывать остальные признаки, то есть исходно поделим нашу выборку на 90 независимых фрагментов. Из-за такого дробления мы в общей сложности получили несколько тысяч признаков, потому что по сути рассматривали каждый из них 90 раз — для каждой отдельной комбинации. Даже с учётом больших обучающих выборок такая “мультипликация” привела к тому, что модель стала быстро переобучаться. Частично эту проблему удалось решить за счет L1-регуляризации (она, в отличие от L2, умеет нивелировать влияние признаков, обнуляя веса при них), но в итоге по совокупности проблем подход пришлось признать тупиковым. Правда, были и хорошие новости: такую временнyю модель уже можно было использовать в качестве маршрутной, потому что она обладала линейностью по отдельным манёврам, а значит, мы двигались в нужном направлении.
И всё-таки, проблема оставалась: как справиться с таким количеством признаков? У Яндекса есть Матрикснет — алгоритм машинного обучения, основанный на градиентом бустинге решающих деревьев, который успешно справляется с сотнями и даже тысячами признаков. Для начала мы попробовали подход «в лоб» и обучили Матрикснет на парах «маршрут — реальное время проезда». Такой метод сразу же дал хороший результат, а дальнейшая работа по наращиванию количества признаков и тонкая настройка гиперпараметров алгоритма помогли получить ощутимый прирост в качестве прогнозирования. Но, несмотря на мгновенный «выхлоп», обусловленный попросту мощью Матрикснета, были и недостатки:
- Стало сложно интерпретировать результаты, потому что в случае градиентного бустинга над деревьями мы работаем, по сути, с чёрным ящиком. Уже нельзя просто трактовать различные признаки в зависимости от их весов.
- Из модели пропала линейность — нельзя разбить маршрут на 2 кусочка, применить к ним модель, сложить и получить то же самое число, что и для маршрута целиком.
- Такую модель не получалось использовать в качестве маршрутной, ведь мы обучали ее на маршрутах целиком, а не на отдельных маневрах.
То есть для наших задач использование Матрикснета «в лоб» не подошло. В итоге мы остались с двумя разными моделями, каждая из которых была по своему хороша, но и чем-то плоха. В такой парадигме — линейная (и грозившая переобучиться) маршрутная модель и временнaя модель на основе Матрикснет — мы пытались какое-то время развиваться, однако душе хотелось какого-то универсального решения. И оно нашлось.
«Линейный Матрикснет»
Как это обычно бывает, идея, когда она уже пришла в голову, оказалось до слёз простой: применить Матрикснет к отдельным манёврам, а не ко всему маршруту, а в качестве функции ошибки брать следующую разность: сумма значений времени по маневрам маршрута минус целевое время проезда.
где T — Цель, f — признаки, F — оптимизируемая функция.
Хотя такая функция очень напоминает задачу ранжирования в поиске (оптимизация поисковой выдачи как единого целого), в нужной форме такого инструмента Матрикснета среди готовых не было, поэтому нам пришлось реализовать его самостоятельно.
После некоторых мук подбора правильного темпа обучения и количества деревьев удалось получить модель, которая почти не проигрывала «чистому» Матрикснету по качеству, зато обладала линейностью. Это позволяло использовать её в качестве маршрутной модели, а также открывало доступ к лёгкому использованию категориальных признаков за счёт их оцифровки и использования CatBoost.
Результаты
Вся эта история заняла достаточно много времени, однако в конечном счёте мы получили модель, которая одновременно удовлетворяла всем требованиям по быстродействию и давала необходимую точность при оценке времени. Именно эта последняя характеристика дала возможность точно рассчитывать стоимость поездки на такси заранее, и не менять её по окончании пути.
Последний вопрос — какие результаты мы получили, есть ли с чем сравнить? Разумеется, полный ответ потребовал бы обсуждения множества факторов и достаточно серьёзной аналитики. Но какие-то совсем простые оценки мы можем дать.
«Было — стало». Слева — старая версия приложения с примерным расчётом стоимости поездки. Справа — текущая версия с точной ценой поездки в разных тарифах.
Очевидно, что показ точной цены поездки в приложении Яндекс.Такси ещё в момент заказа — это само по себе существенное преимущество, которое делает сервис прозрачным для пользователей, поэтому здесь мы мало чем рисковали. Единственное, что оказалось сложно — это объяснить, что если человек приезжает не в ту точку Б, которую он указал при заказе, то вся поездка пересчитывается по таксометру, потому что в таких случаях наши расчёты бессмысленны. Но это уже другая история. Поскольку таких случаев немного, большинство наших пользователей оценило не просто показ финальной цены перед поездкой, но и то, что в конце поездки она не меняется, даже если такси стояло в пробке или водитель её объезжал. И разумеется, они стали чаще указывать точку Б, понимая, что только в этом случае получают такой расчет.
Как мы и говорили в начале, если бы наши алгоритмы работали плохо и делали цену хорошей только для пользователя, это могло бы привести к существенной потере заработка водителей и, как следствие, к их оттоку. После того, как цена стала показываться ещё до поездки, количество заказов начало активно расти — многим людям, для которых критична точная стоимость, стало психологически проще пользоваться Яндекс.Такси. Рост заказов привёл к значительному росту утилизации машин такси — то есть к доле за рабочую смену, когда водитель везёт пассажира или едет на заказ, а не тратит время вхолостую. Произошло это ещё и из-за того, что рост улучшил работу других технологий сервиса — например, цепочки заказов. Это алгоритм, который начинает искать следующего клиента ещё до того, как водитель довёз предыдущего — и ищет его в том районе, куда водитель скоро приедет с пассажиром.
Рост утилизации машин в Москве и области.
Благодаря росту утилизации вырос и самый важный для водителя показатель — earn per hour, средний заработок за час смены: по нашим оценкам, примерно на 15–22% в среднем по России. Хотя некоторые города оказались настоящими рекордсменами, там этот показатель вырос ещё больше.
Впереди нас ждёт множество мелких и крупных улучшений модели, вроде подключения CatBoost, про которые мы обязательно расскажем.
Комментарии (87)
linuxover
18.12.2017 12:55+1Если внимательно посмотреть на Ваш скриншот:
то видно старое приложение оценивало поездку на 40 минут (информация со скриншота) в стоимость 860 руб, а новое приложение оценивает поездку в 45 минут (информация со скриншота) в 769 руб, то есть примерно на 100 руб дешевле чем раньше.
То есть главный фактор "почему клиентов стало больше" — снижение стоимости тарифа.
поправьте меня если я ошибаюсь :)
dmitryvolkovtaxi
18.12.2017 13:57Нет, это не так. Из поста вы можете видеть, сколько различных параметров учитывает приложение при формировании стоимости поездки до момента оформления заказа. Эти параметры в Москве и других крупных городах меняются настолько часто, что стоимость может быть разной даже для двух пользователей, которые стоят рядом и почти одновременно оформляют поездки по одинаковому маршруту. То есть время в пути — далеко не единственный фактор, это я вот к чему. Кроме того, тарифы в Москве мы давно уже не меняли :)
linuxover
18.12.2017 14:06То есть время в пути — далеко не единственный фактор
Кроме того, тарифы в Москве мы давно уже не меняли :)что мы видим из скриншота?
- поездки из пункта A в пункт B, пункты A и B не поменялись
- новое приложение оценило что ехать на пять минут дольше
- новое приложение оценило что ехать дешевле ~на сто рублей
и Вы говорите тариф не изменился?
PS: я понимаю, что скриншоты делались в расчете на клиента который видит более низкую стоимость в новом приложении, а не в расчете на того кто вдумается в их смысл.
эта проблема растет из работы на KPI, а не на результат, увы.
Turilion
18.12.2017 23:25Вам же сказали, прочитайте статью внимательнее и все вопросы сразу снимутся. Читая ваши размышления становиться абсолютно очевидно, что статью вы если и читали, то через строчку.
linuxover
18.12.2017 23:35дык я именно, что внимательно.
просто в статье утверждение: вся эта работа дала нам X дополнительных клиентов. И на скриншотах тариф одной и той же поездки отличается на 10%.
неужели невнимательный человек задал бы тот вопрос что и я: "Вы уверены, что именно Ваша работа, а не снижение тарифа привело Вам этих дополнительных пользователей?"
vlivyur
19.12.2017 10:31Если несколько раз пытаться проложить маршрут из точки А в точку Б, то цена может отличаться очень значительно (хотя обычно колеблется в пределах 10 рублей). Так что я бы не стал так сильно привязываться к этим скриншотам и настаивать что это та же самая поездка и они снизили тарифы.
Andrey_Epifantsev
18.12.2017 13:05А можно еще водителям добавить возможность указывать предпочтительный район по которому они хотят ездить? Чтобы при заказе автоматически отсекались те, кто по выбранному маршруту не поедут. А то вызываешь машину и каждый второй говорит: «Отменяйте заказ, я в этот район не поеду.»
dmitryvolkovtaxi
18.12.2017 14:09Мы думаем о том, чтобы такое реализовать, да. Кроме того, уже сейчас водитель дважды в сутки может воспользоваться предложением взять заказ по пути домой, для этого в Таксометре есть специальная кнопка. А вообще отказываться от заказов с такой причиной водители не должны, если вдруг такое случилось — обязательно пишите нам в поддержку, разберёмся.
balexa
18.12.2017 16:53И это предложение часто не работает, судя по отзывам водителей.
А еще у вас новая подача по цепочке глючит. Я регулярно на работу на такси еду, если решаю чуть подольше поспать. И послежнее время приложение назначает водителя который в двух км от меня в пробке и едет заканчивать заказ в противоположную сторону. При этом достаточно отменить заказ и выбрать новый (возможно пару раз), как приложение находит незанятое такси в 200 метрах от меня. Уже дважды так было.
ozonar
19.12.2017 13:45А вообще отказываться от заказов с такой причиной водители не должны
Но отказываются. Я из-за того, что таксисты Убера постоянно звонили мне перед поездкой я ушел с Убера. Теперь такая же тема на Яндексе, либо звонят, либо просят указывать в комментариях местоположение поездки. В позднее время бывает 5-6 отказов.
barbadian
19.12.2017 23:06Для этого в комментариях заказа продублируйте адрес назначения. С некоторого времени водители Яндекс такси узнают его только по приезду к клиенту. Существуют выгодные и невыгодные для водителей поездки, поэтому вполне логично, что по вторым мало кто захочет ездить.
bobnadyl
18.12.2017 13:10Почему одна и та же поездка на на 8+ айфоне выходит рублей на 30 дороже чем на 5s?
Vest
18.12.2017 14:12А мне ещё не нравится повышающий коэффициент. С утра попьешь чай, подумаешь, что такси через 10 минут закажешь и бах! поездка стала дороже на 40%.
Продукты так в магазине не дорожают, как такси.dmitryvolkovtaxi
18.12.2017 14:16Повышающий коэффициент — это вынужденная мера, которая помогает воспользоваться такси тем, кому важно уехать максимально срочно, даже в периоды высокого спроса. В такие моменты вместе с таксопарками-партнёрами мы стараемся вывести на линию как можно больше водителей, чтобы повышающий коэффициент как можно скорее исчез. Если подождать, коэффициент снизится, и уехать можно будет по обычной цене.
Vest
18.12.2017 16:50По мне это похоже на лотерею. Потому что я не знаю о том, а снизится ли этот коэффициент вообще. Вы говорите, что стараетесь вывести водителей, но я как пользователь ничего не знаю. Но я вижу, что машинки по карте катаются и не похоже, что их катастрофически не хватает.
Одно дело, у меня был бы выбор — взять машину со временем ожидания 5 минут, или 20 минут. Или же я бы просто взял более роскошный тариф/автомобиль, потому как им никто не пользуется.
Если сильно хочется, то можно ввести "торг" с другими пассажирами, если машина одна, а желающих 100, но мне такой подход не нравится. А рост цены слишком высок.
Извините.
gturk
18.12.2017 22:57а еще в последнее время регулярно делаешь заказ по одной цене, а садишься в машину к водителю — у него на табло уже цена на 20-50 рублей дороже, и время ожидания еще не началось
chippie
19.12.2017 23:07У меня как-то цена в три раза увеличилась после окончания поездки — 450 рублей за трехминутную поездку на два километра, так что лишним 20 рублям не стоит удивляться
balexa
18.12.2017 16:55Заказывайте с другого телефона или не смотрите цену перед поездкой. У меня есть стойкое ощущение, что просмотр цены за 5 минут до поездки дает нехилый буст к вероятности повышения коэффициента.
JC_Piligrim
18.12.2017 17:15Кстати да, неоднократно замечал. Смотришь цену — 300р. Через 5 минут после этого (ага, расскажите мне про сложную и непредсказуемую ситуацию на дорогах) собираешься вызвать — 500р.
Turilion
18.12.2017 23:31А вы не рассматривали такой вариант. Машина есть поблизости и свободна — вам расчитвывают условно 300р, но пока вы сомневаетесь, на этой машине уехал кто-то другой и вот уже через пять минут для вас надо гнать машину из соседнего (или не очень) района. Вот вам и прирост цены.
dmitryvolkovtaxi
18.12.2017 14:13Как вы можете видеть из поста, на стоимость поездки главным образом влияет ряд различных факторов: количество свободных водителей рядом с вами на момент заказа, приблизительное время, которое вы проведёте в пути, расстояние между точками по определённому маршруту, оптимальная скорость движения, дорожная обстановка и многое другое. Эти факторы имеют свойство очень быстро меняться, даже если взять два телефона, забить один и тот же маршрут и почти одновременно оформить заказ — стоимость может быть разной. Но вот что точно на неё не влияет, так это то, какие именно это будут телефоны. Никакой зависимости цены поездки от моделей телефонов, а также от уровня доходов пользователя, от его текущего настроения и цвета кроссовок нет.
linuxover
18.12.2017 14:17> Как вы можете видеть из поста, на стоимость поездки главным образом влияет ряд различных факторов
однако на Ваших скриншотах нет повышающего коэффициента ни на первом приложении ни на втором. Таким образом тариф в новом приложении изменился (резко подешевел), раз в новом показывает на 100 руб дешевле.knstqq
18.12.2017 15:11дело не в новом приложении, а в новых алгоритмах, которые более точно оценивают стоимость поездки, предлагают более оптимальный маршрут (не обязательно более короткий или более быстрый).
linuxover
18.12.2017 15:20+1дело не в новом приложении, а в новых алгоритмах, которые более точно оценивают стоимость поездки.
ну дык "новые алгоритмы" оценивают ту же поездку более дешево, то есть под "новые алгоритмы" Вы замаскировали снижение тарифа.
Клиентов больше стало не потому что "новые алгоритмы", а потому что цена на 100 руб дешевле теперь.
если говорить о статье, то она стандартна
- описание моря проделанной работы
- требуется практический вывод (внедрение — как раньше называлось)
Если б написали: замерили 1000 реальных поездок, у них такое вот расхождение с предсказаниями, то это было бы хорошее окончание технической статьи.
Но вместо этого привели скриншоты "было-стало" и далее график увеличения числа
поездокнепонятной утилизации. Соответственно прямо из скриншотов видно же что график увеличения числа поездок он не от внедрения "нового алгоритма" обсчета роута по 100500 серверам, а от банального снижения тарифов. И вот этой концовкой статью и испортили, увы.
PS: А внедрение фикспоездки делалось насколько я понимаю "в ответ на действия конкурента": Uber ввел фикс-поездки, затем яндекс напрягся и тоже срочно ввел. Заодно тарифы пониже сделал чем в Uber. как-то так.
ну а тут на хабре увы перемешалось в кучукони, люди, техническая работа и маркетинг. И получилась фигня :)
dmitryvolkovtaxi
18.12.2017 15:17+1Тариф не изменился, просто маршрутизатор по тем же точкам продолжил два маршрута: один по короткому пути, но дольше по времени, а другой — длиннее в километрах, но быстрее. Отсюда и разница в цене.
linuxover
18.12.2017 15:22Ехать дольше, платить меньше.
в обоих случаях — из точки А в точку B. Для клиента результат один: тариф снижен на ~10%.
mayorovp
18.12.2017 15:24Там цена же считается на время, а не на километры. Иначе не было бы смысла пытаться оценить время настолько точно.
dmitryvolkovtaxi
18.12.2017 15:38Тариф обычно складывается из трёх составляющих: стоимость посадки (иногда с включенными километрами и/или минутами), стоимость километра и стоимость минуты. Можно в любой момент в приложении проверить, или на сайте у нас посмотреть: taxi.yandex.ru/#mrt.
Afinogen
19.12.2017 13:20Недавно была такая ситуация:
вышли мы из бара на парковку, друг заказывает яндекс такси через приложение, стоим курим, ждем. Такси нет, приложение предлагает сменить эконом на комфорт. 4 утра, домой уже охота, соглашаемся.
Тут же на парковке загораются фары, подъезжает реношка. Едем за сумму х2 домой.
Водитель не был занят, он просто ждал повышения цены. Думаю он не один такой.murzilka
19.12.2017 17:07Это же разные машины — в комфорте и в эконом. Думаю, водителю, который вас в конечном итоге вёз, даже не прилетел первый заказ.
DS28
21.12.2017 07:42Никакой зависимости цены поездки от моделей телефонов, а также от уровня доходов пользователя, от его текущего настроения и цвета кроссовок нет.
Ещё где-то мелькала гипотеза, что мониторится наличие приложений конкурентов))
На самом деле, было бы интересно посмотреть спорные моменты и их объяснение с позиции «изнутри». т.е. как происходил расчёт… Наверное не просто такое организовать, но если вдруг, то возможно прояснение многих странных ситуаций
JC_Piligrim
18.12.2017 14:40А ещё если телефон скоро сядет — скорее всего поездка обойдётся вам сильно, очень сильно дороже. :) Не говоря о «налоге на богатство» — бо?льших повышающих коэффициентах для обладателей свежих моделей телефонов.
К — капитализм. Большая сила (спойлер: в виде количества собираемых и обрабатываемых сведений) — большая ответственность (спойлер: на самом деле нет. Это вкусные возможности манипулировать людьми и извлекать из них деньги на переделе возможностей).
Tairesh
18.12.2017 14:38-3более 70 разных признаков, влияющих на «стоимость» маршрута
Вот мой любимый признак:
440 рублейUgrum
18.12.2017 14:59У вас
ус отклеилсякартинки отвалились.Tairesh
19.12.2017 09:59Бывает, фиг с ними, сверхкороткий срок редактирования не прощает ошибок
lostpassword
19.12.2017 14:06Залейте на habrastorage.org, интересно же.
Tairesh
19.12.2017 16:44У меня на работе забанен хабрасторадж и все популярные фотохостинги :)
И там ничего интересного, просто маршрут от аэропорта и от дома в 300 метрах от аэропорта, от дома ехать на пять минут дольше, но в 2 раза дороже. Боюсь представить цену, что будет если заказывать из аэропорта с разряженного айфона Х.
ilyaplot
18.12.2017 15:03А насколько различается «вес» левого поворота и правого? На практике путь с 3-я правыми поворотами может быть значительно длиннее, но и значительно быстрее. Как ваша система относится к поворотам налево?
linuxover
18.12.2017 15:12кстати, это уже к навигатору конечно вопросы, а не к таксометру.
и поворот налево повороту налево рознь же: вот езжу домой: навигатор всегда предлагает там повернуть налево на перекрестке со стрелкой влево. Вроде все правильно, да нет.
Если поворот налево делать на следующем перекрестке, то там стрелки не будет (что хуже по идее), но встречного движения в 99% случаев нет (что практически сводит ситуацию к Т-образному перекрестку) и соответственно получается и ездить так быстрее и безопаснее и удобнее.
вот бы кто занялся расставить теги предпочтительности поворотов на разных перекрестках и прокладку маршрутов в соответствии с ними.
с точки зрения именно юзабилити навигатору по моему не хватает некоторых таких штучек: проставить приоритеты поворотам, например, или например начать учитывать предпочтения юзера: если юзер раз-два-три-четыре проехал не по предложенной дороге, то может быть ему виднее? повысить приоритеты узловым точкам через которые он ездит…JC_Piligrim
18.12.2017 15:20+1У меня другой вопрос к навигатору. Вот построили, например, объездную дорогу, по которой реально быстрее добираться. Полгода по ней ездят машины, водители которых знают об этой дороге. Но навигатор упорно видит там «поле». ПОЛГОДА. Яндекс, обладая всей информацией обо всех перемещениях, видя плотный поток по «полю» в десятки тысяч машин по одному и тому же маршруту каждый день в течение полугода не может «прорезать» на картах новую дорогу и предлагает путь в 2,5 раза длиннее через город по пробкам. Это позор, господа.
Akon32
18.12.2017 15:34+1Может быть, следует внести новый участок в OpenStreetMap или в те же "Народные карты" Яндекса?
JC_Piligrim
18.12.2017 15:56А зачем это делать руками, если можно на основе автоматического сбора данных?
Если миллионы человек «нарушают», то, может, это уже и не нарушение?
Если дорога есть, а по ней не ездят — то может она перекрыта?
Если дороги нет, а по полю/лесу/озеру идёт плотный транспортный поток — то может там всё же дорога?
Если на картах двухсторонняя дорога, но там уже месяц 99% едут только в одну сторону — то может она всё же односторонняя?
Почему человек должен заниматься работой, которую с лёгкостью делают машины? Тем более, что в OpenStreetMap и «народные карты» легко могут добавлять что угодно вандалы с целью поглумиться. А вот реальные данные с датчиков gps подделывать намного муторнее — там намного более актуальные данные по реальной ситуации на дорогах.za90
18.12.2017 16:11Зачем ждать полгода пока соберутся эти треки если можно за пару минут внести данные руками?
А вот на вандалов я бы как раз ML натравил, порой задалбывает вахтёрить (я из OSM если что).JC_Piligrim
18.12.2017 17:23Если всё, что теоретически можно сделать руками делать руками — то на что-либо кроме тупого рутинного ручного труда времени не останется.
Я ведь о том и говорю, что треки-то собираются, но никто особо не чешется, чтобы эта информация действительно полезно использовалась. Если бы всё сделали правильно — там полгода не надо было ждать. За день стату посмотрели — ага, 100000 машин проехало по воде со скоростью 70км/ч — значит там всё же мост, алгоритм (после отсева вандалов) дорисовал на карте временный мост. После плановой сверки дорожной сети с официальными источниками, или как там это происходит — мост коммитится в официальную карту.
Те аккаунты, что шаманят с треками и новичков (шаманство вычислять с помощью того же ML) — банить навсегда в отношении доверия к предоставляемой ими информации при расчётах. На iPhone, например, особо не пошаманишь из-за огороженности системы от потных ручек кулхацкеров, там можно доверять.
OSM — классный проект, но почему бы Яндексу, наконец, не использовать данные, которые у них и так собираются?
Turilion
18.12.2017 23:36А вот это дельное замечание, тоже все время дума, а почему бы не автоматизировать такие вещи, это ведь легко.
tundrawolf_kiba
18.12.2017 18:29в те же «Народные карты» Яндекса?
Вот кстати да. Долгое время доставало, что водителям приходилось объяснять, как ехать на развязках около моего дома, и то, не всегда получалось объяснить. А потом узнал про народную карту, подправил пару мест(в одном месте на карте можно было развернуться через двойную спошную, в другом — был внутриквартальный проезд, где фактически проезда не было). И через две недели(когда изменения переехали на основные карты) навигатор стал строить правильный путь к моему дому.
Akon32
18.12.2017 15:50вот бы кто занялся расставить теги предпочтительности поворотов на разных перекрестках и прокладку маршрутов в соответствии с ними.
Слишком сложно…
Предпочтительность поворотов зависит от загруженности дорог, т.е. как минимум от времени суток. Плюс элемент случайности — бывает, ВНЕЗАПНО появляются пробки, или наоборот, достаточно свободная дорога через центр в час-пик. Плюс данные о пробках на разных сервисах различаются (!) и довольно часто не соответствуют действительности. (речь не о дефолт-сити)
То есть приоритеты поворотов должны меняться в зависимости от каких-то условий. Адекватную статистику по трафику не всегда можно собрать. Немного пользователей будут настраивать это всё под себя, да и сходу непонятно, можно ли вообще это формализовать.
Но идея, конечно, интересная.
linuxover
18.12.2017 15:53Предпочтительность поворотов зависит от загруженности дорог, т.е. как минимум от времени суток.
в том случае о котором я говорю — всегда один поворот предпочтительнее, ну да ладно.
а почему бы не иметь временнУю зависимость коэффициента для каждого поворота.
да ЧП будут, но в среднем же лучше будет?Akon32
18.12.2017 16:21Чтобы знать, что "в среднем" получается лучше, нужно накопить достаточно статистики. Судя по неполноте графов пробок в пригородах, данных часто недостаточно.
В вашем конкретном случае может быть действительно всё однозначно, но если разница невелика, оптимальность пути нужно как-то доказывать. Вам может казаться оптимальным один путь, хотя в действительности в среднем лучше другой.
alexeykuzmin0
18.12.2017 18:26Можно для каждого поворота на перекрестке насчитать статистику того, как быстро его проходят реальные пользователи с GPS в разных условиях, и на основе этого предсказывать, сколько времени уйдет у водителя. Не слишком сложно выглядит
realize_s Автор
18.12.2017 15:23Как правило поворот налево является более «дорогим», конкретные цифры зависят от комбинации функциональных классов текущего и предыдущего ребер маневров. В вашем случае, если левый поворот действительно быстрее, то это будет учтено в скорости потока по этому маневру.
Ashot
18.12.2017 15:11Вообще иногда алгоритмы подкладывают откровенную свинью:
по такому маршруту стоимость ~230р, ибо прокладывается через шоссеtundrawolf_kiba
18.12.2017 18:43Знаете, заинтересовало, посмотрел, и кажется понял, почему так строит. Алгоритм показывает, если с Латышской напрямую ехать 11 минут, а через Ленина — 21 минуту. К сожалению не могу со своего города глянуть, сколько такой маршрут выливается в цене.
Ashot
18.12.2017 19:13Так дело в том, что ехать через ленина 21 минуту – это дело из ряда вон выходящее. Среднестатистически такая поездка должна занять минут 10-15, 20 мин и более – это редкий случай (город у нас небольшой и действительно мёртвые пробки в том направлении могут возникать в очень редких случаях.)
Уж не знаю как такое время алгоритм высчитывает, но через город в 95% случаев быстрее.
Да даже если предположить, что алгоритм прав(что через трассу быстрее) – водитель всё равно поедет по более дешёвому маршруту(не из-за его дешевизны, потому что он оптимальнее), а пересчёта цены по завершении поездки не будет. Ясное дело, что идеальный алгоритм тут вывести очень сложно, но платить за поездку 230 руб, когда она по факту стоит 150 как-то прям обидно даже.
tundrawolf_kiba
18.12.2017 19:20В приложении есть возможность задавать несколько точек. Попробуйте. может получится как-то через Ленина построить и посмотреть, какая цена выйдет?
Ashot
18.12.2017 19:28Через несколько точек конечно считает уже ~150. Только промежуточную точку тоже надо правильно выставить: ставим на Ленина, 6 – 150р, Ленина 7(через дорогу от 6) – получаем вообще 340 :)
Да и большинству пользователей такой лайфхак даже в голову не придёт. Просто закроют и вызовут местную службу такси.
rail-ka
18.12.2017 15:12Было бы интересно узнать какие технологии и базы данных используете для хранения данных и расчета по ним? Все в памяти или используете SSD или HDD?
realize_s Автор
18.12.2017 15:27Данные графа полностью прогружаются в память, другие варианты хранения не могут обеспечить нужное время отклика маршрутизатора.
fedorro
18.12.2017 16:33Каждый раз, как заказываю, — одна и та же история:
Открываю приложение, передвигаю запятую старта на то место куда нужно подать машину (например GPS неверно определил мое местоположение, или дорогу перешел, т.к. иначе пришлось бы ехать в обратном направлении пару км. для разворота), а машина подъезжает туда, где определилось мое изначальное приложение. Вопрос — зачем нужен маркер точки отправления?
Ну и ещё замечание — иногда водители приезжают немного не туда (+-3 км. бывало), ориентируясь по Яндекс.Навигатору же. Данные после этого обновляются как то, водителями, например?JC_Piligrim
18.12.2017 17:28Да, пару дней назад поставил точку на парковке. Таксист подъехал на другую сторону дороги. Звоню: «вы точку видели? Я вообще-то на парковке вас жду и специально для этого метку поставил!». Таксист: «а что мне теперь, через весь поток ехать?». Пришлось перебегать четырёхполоску, рискуя жизнью или здоровьем, чтобы не терять время. У таксистов вообще нет распоряжений насчёт того, что место ожидания, которое пользователь старательно ставит руками имеет наивысший приоритет перед их предположениями?
QDeathNick
19.12.2017 16:21Подтверждаю. Причём опрошенные водители говорят, что не видят точку, куда я ставлю, а только адрес.
Мне вот не удобно указывать свой домашний адрес, так как тогда водители заезжают кривыми дорогами во двор и выезжать бывает очень долго. Указываю на дорогу с моего торца дома, но там Яндекс определяет адрес, как дом, который находится с другой стороны дороги и он длинный, водители приезжают к его другому торцу. Каждый раз приходится звонить и объяснять куда подать машину.
Я бы вообще убрал у водителей понятие «адрес», чтобы они не путались и не доказывали что приехали по адресу. Мы у себя в службе такси давно поняли, что и заказчику и водителю лучше показывать карту, а то по адресу можно вообще уехать в другой конец города. К примеру в Балашихе куча Лесных улиц, или в МО куча сел с одинаковыми названиями, народ путается.
И спасибо Яндексу, что он реагирует на такие просьбы и постепенно улучшает свои приложения.
Alcor
18.12.2017 17:34Так уж получилось, что последние недели две пришлось изрядно покататься на яндекс-такси в Саратове. Удивил факт, что ни разу не было, чтоб водители не завершили заказ до конца поездки. Говорят — не хотим платить яндексу. Раньше не было такого. Ну и да, то что нельзя поставить точку старта/стопа на перекрестке — реально бесит (вернее, теоретически можно, но водители едут по адресу, определенному автоматически — по ближайшему дому, а дома бывают очень длинные).
Mogwaika
18.12.2017 17:46А в Москве думаете по другому? Мне интересно почему яндекс не отслеживает и не банит тех, кто всё таки доехал до конца первого маршрута (т.к. если бы банил, то так бы не часто делали).
Afinogen
19.12.2017 13:06Уже банят, точнее штрафуют. Мне недавно таксист жаловался что на 12к налетел. Но тем не менее он мой заказ завершил раньше времени.
alexeykuzmin0
19.12.2017 14:43А чем водителю выгодно завершить заказ до конца поездки?
Mogwaika
19.12.2017 15:02Вы ему платите полную сумму, а он процент платит с суммы до полпути.
Более того некоторые просят пользователя отменить заказ.alexeykuzmin0
19.12.2017 15:03Но разве сумма не уменьшится при изменении пункта назначения? И с карты, соответственно, спишется стоимость только за полпути
Mogwaika
19.12.2017 15:07Х.з. как с картой, я налом плачу обычно в такси. Я думаю попросит доплатить наликом. Или предлагает только тем, кто за налик катается.
alexeykuzmin0
19.12.2017 15:09Упс, понятно, спасибо. Мне как-то не пришло в голову, что можно еще и наличными платить.
Mogwaika
19.12.2017 15:19Я как-то добавил карту в Убер, но в процессе заказа такси в аэропорт, после нажатия вызов, пошла проверка и ошибка мол карта не понравилась, пришлось срочно перебивать другую карту, которая подошла, по приезду спрашиваю водителя, пришли ли деньги, он не знает и я не знаю (но всё сработало), дальше оказалось, что карточку просто так не удалишь, надо чтобы была хотябы одна, благо я знал, что моя первая не работает с убером, но приложение осталось довольно нерабочей картой.
Не хочется привязывать к сервису карту, но наверное виртуальную яндексовую яндексу можно доверить))alexeykuzmin0
19.12.2017 15:33Ну а я карточной паранойей не страдаю. Просто выйти из машины, сказав «до свидания» несколько проще, чем ругаться из-за размена.
QDeathNick
19.12.2017 16:44А не каждую виртуальную карту можно добавить. Например QIWI Visa Virtual не принимается ни Яндексом ни другими такси.
kirillaristov
18.12.2017 22:27Сегодняшний таксист посетовал на то, что Яндекс.Таксометр не умеет определять выделенные полосы для автобусов (которые также подходят и для такси).
Что иногда Таксометр подбрасывает заказ, не учитывая направление его движения (например, едет по внешнему кольцу МКАДа, а заказ прилетает с внутреннего).
Еще его брали сомнения об оплате труда (компенсации со стороны Яндекса на дешевые поездки) после 1 января 2018 года, когда Убер и Яндекс официально станут работать вместе.
А в остальном порадовался, что работает с Яндексом.
Интересно, мог бы Яндекс как-то это прокомментировать? Делаются ли какие движения, чтобы исправить такое поведение? А я перешлю таксисту :)
dmitryvolkovtaxi
19.12.2017 13:40Сейчас мы учимся показывать водителям возможность проезда по выделенке, и как только это будет реализовано — обязательно расскажем. В большинстве случаев мы уже умеем учитывать направление движения — в этом нам помогают алгоритмы, которые обрабатывают данные GPS на устройстве водителя, мы над ними очень активно работаем. Нужны данные водителя, чтобы проверить заказы, это нам поможет сделать алгоритмы ещё лучше. Попросите его, пожалуйста, написать нам в техподдержку через Таксометр или на taxist@taxi.yandex.ru — проверим, почему так получилось.
EvilArcher
19.12.2017 13:42Было бы круто каким-то образом в самом приложении визуализировать расчет цены за поездку. А то это, конечно, в теории выглядит очень круто, но на практике, когда за один и тот же маршрут в одно и тоже время с тебя берут то Х, то 2Х, а иногда и 3Х, начинаешь сомневаться в том, что ценообразование работает именно так.
Лично я заметил следующие факторы, которые также влияют на цену:
— Если несколько раз проверять цену до поездки, то она будет увеличиваться;
— Регулярные маршруты со временем слегка дорожают.
ZakharS
19.12.2017 14:44Яндекс, респект за очередную прекрасную статью! Из личных замечаний, скорее, не к такси, а к маршрутизации: есть места, где водителю предлагается выехать с прилегающего переулка на улицу и через 20-50 метров перестроиться через 3 полосы в левую для разворота или поворота налево. Как правило, в часы пик это невозможно, потому что в левой полосе уже стоит очередь на разворот. Как бы это научиться учитывать? Просто если не перестроиться, то следующий разворот может быть и через пару километров по пробкам.
LenLord
Я рад, что вы хорошо оптимизируете маршруты, но вот мне совсем никак не предлагает маршрут дешевле, хотя, казалось бы, улицу перейти
dmitryvolkovtaxi
Если исходить из ваших скриншотов, то до точки, которую мы должны были вам предложить, идти 7-8 минут пешком. Это слишком далеко, мы предлагаем такие точки в пределах 3-4 минут ходьбы — кажется, дальше этого предлагать нет смысла, это уже не альтернативная точка получается, а иногда и полпути до точки Б :)
LenLord
Ну разница цены почти в 2 раза — можно и показать вариант. Да и ехать там 40 минут.
А как тогда такой скриншот объясните?
И это не случайность, стабильно воспроизводится, и там идти явно не 7-8 минут
linuxover
на лайфхак похоже очень то что Вы на скриншоте показали :)
dmitryvolkovtaxi
Мы, кстати, очень подробно рассказывали о том, как работает эта функция в одном из предыдущих постов на Хабре: habrahabr.ru/company/yandex/blog/330524.
stifff
точно помню, что мне показывало. типа перейди улицу — будет быстрее/дешевле