Як у Яндэкс.Таксі шукаюць машыны, калі іх няма

Як у Яндэкс.Таксі шукаюць машыны, калі іх няма

Добры сэрвіс для замовы таксі павінен быць бяспечным, надзейным і хуткім. Карыстальнік не стане ўдавацца ў дэталі: яму важна, каб ён націснуў кнопку "Замовіць" і як мага хутчэй атрымаў машыну, якая даставіць яго з кропкі А ў кропку Б. Калі побач няма машын - сэрвіс павінен адразу аб гэтым паведаміць, каб у кліента не складалася ілжывых чаканняў. Але калі плашчак "Не машын" будзе высвечвацца занадта часта, то лагічна, што чалавек проста перастане карыстацца гэтым сэрвісам і сыдзе да канкурэнта.

У гэтым артыкуле я жадаю распавесці аб тым, як пры дапамозе машыннага навучання мы вырашалі задачу пошуку машын на тэрыторыі з малой шчыльнасцю (прасцей кажучы - там, дзе, на першы погляд, няма машын). І што з гэтага выйшла.

перадгісторыя

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

Карыстальнік этап Бэкенд Яндекс.Таксі
Выбірае кропку адпраўлення пін Запускаем спрошчаны пошук кандыдатаў - пошук на піне. На аснове знойдзеных кіроўцаў прадказваецца час прыезду - ETA ў піне. Разлічваецца які падвышае каэфіцыент у дадзенай кропцы.
Выбірае кропку прызначэння, тарыф, патрабаванні Аффер Які будуецца маршрут і разлічваем кошты на ўсе тарыфы з улікам які падвышае каэфіцыента.
Націскае кнопку «Выклікаць таксі» заказ Запускаем паўнавартасны пошук машыны. Выбіраемы найболей падыходнага кіроўцы і прапануем яму замова.

Пра ETA ў піне, разлік кошту и выбар найбольш прыдатнага кіроўцы мы ўжо пісалі. А гэта гісторыя аб пошуку вадзіцеляў. Калі ствараецца замова, пошук адбываецца два разы: на піне і на замове. Пошук на замове праходзіць у два этапы: набор кандыдатаў і ранжыраванне. Спачатку знаходзяцца вольныя вадзіцелі-кандыдаты, найбліжэйшыя па дарожным графе. Потым прымяняюцца бонусы і фільтрацыі. Астатнія кандыдаты ранжыруюцца, і пераможцу прыходзіць прапанова замовы. Калі ён згаджаецца, то прызначаецца на замову і едзе да кропкі падачы. Калі адмаўляецца, то прапанова прыходзіць наступнаму. Калі кандыдатаў больш няма, то пошук запускаецца нанова. Гэта працягваецца не больш за тры хвіліны, пасля чаго заказ адмяняецца - згарае.

Пошук на піне падобны на пошук на замове, толькі замова не ствараецца і сам пошук выконваецца толькі адзін раз. Таксама выкарыстоўваюцца спрошчаныя наладкі колькасці кандыдатаў і радыусу пошуку. Такія спрашчэнні патрэбны, таму што пінаў на парадак больш, чым заказаў, а пошук - даволі цяжкая аперацыя. Ключавы момант для нашай гісторыі: калі падчас папярэдняга пошуку на піне падыходных кандыдатаў не знайшлося, то мы не дазваляем зрабіць замову. Прынамсі, раней было так.

Вось што бачыў карыстальнік у дадатку:

Як у Яндэкс.Таксі шукаюць машыны, калі іх няма

Пошук машын без машын

Аднойчы ў нас з'явілася гіпотэза: магчыма, у некаторых выпадках замову ўсё ж можна выканаць, нават калі на піне не знайшлося машын. Бо паміж пінам і замовай праходзіць нейкі час, а пошук на замове больш поўны і часам паўтараецца некалькі разоў: за гэты час вольныя кіроўцы могуць з'явіцца. Яшчэ мы ведалі адваротнае: калі кіроўцы знайшліся на піне, то яшчэ не факт, што яны знойдуцца пры замове. Часам яны знікаюць ці ўсё адмаўляюцца ад замовы.

Каб праверыць гэтую гіпотэзу, мы запусцілі эксперымент: перасталі правяраць наяўнасць машын падчас пошуку на піне для тэставай групы карыстачоў, т. е. у іх з'явілася магчымасць зрабіць "заказ без машын". Вынік атрымаўся даволі нечаканым: калі машына не знаходзілася на піне, то ў 29% выпадкаў яна знаходзілася пазней - пры пошуку на замове! Больш за тое, замовы без машын не моцна адрозніваліся ад звычайных па частаце адмен, ацэнак і іншым паказчыкам якасці. Колькасць заказаў без машын склала 5% усіх заказаў, але крыху больш за 1% усіх паспяховых паездак.

Каб зразумець, адкуль бяруцца выканаўцы гэтых заказаў, паглядзім на іхнія статусы падчас пошуку на піне:

Як у Яндэкс.Таксі шукаюць машыны, калі іх няма

  • Вольны: быў даступны, але па нейкіх прычынах не патрапіў у кандыдаты, напрыклад быў занадта далёка;
  • На замове: быў заняты, але паспеў вызваліцца ці стаць даступным для замовы па ланцужку;
  • Заняты: магчымасць прымаць замовы была адключаная, але потым кіроўца вярнуўся на лінію;
  • Недаступны: кіроўцы не было ў сетцы, але ён з'явіўся.

Дадамо надзейнасці

Дадатковыя замовы - гэта выдатна, аднак 29% паспяховых пошукаў азначаюць, што ў 71% выпадкаў карыстач доўга чакаў і ў выніку нікуды не з'ехаў. Хоць з пункта гледжання эфектыўнасці сістэмы ў гэтым няма нічога жудаснага, але насамрэч, карыстач атрымлівае ілжывую надзею і марнуе час, пасля чаго хвалюецца і (магчыма) перастае карыстацца сэрвісам. Каб вырашыць гэтую праблему, мы навучыліся прадказваць верагоднасць таго, што машына на замове будзе знойдзена.

Схема такая:

  • Карыстальнік ставіць пін.
  • Праводзіцца пошук на піне.
  • Калі машын няма прадказваем: можа быць, яны з'явяцца.
  • І ў залежнасці ад верагоднасці даем ці не даем зрабіць замову, але папярэджваем, што шчыльнасць машын у гэтым раёне і тым часам маленькая.

У дадатку гэта выглядала так:

Як у Яндэкс.Таксі шукаюць машыны, калі іх няма

Выкарыстанне мадэлі дазваляе акуратней ствараць новыя замовы, не абнадзейваць чалавека дарма. Гэта значыць рэгуляваць суадносіны надзейнасці і лікі заказаў без машын з дапамогай precision-recall мадэлі. Надзейнасць сэрвісу ўплывае на жаданне і далей карыстацца прадуктам, т. е. у выніку ўсё зводзіцца да ліку паездак.

Трохі пра precision-recallАдна з базавых задач у машынным навучанні - задача класіфікацыі: аднесці аб'ект да аднаго з двух класаў. Пры гэтым вынікам працы алгарытму машыннага навучання часта становіцца лічбавая ацэнка прыналежнасці да аднаго з класаў, напрыклад ацэнка верагоднасці. Аднак дзеянні, якія здзяйсняюцца, звычайна бінарныя: калі машына будзе - то даём замовіць, а калі не - то не. Для пэўнасці назавём мадэллю алгарытм, які выдае лікавую адзнаку, а класіфікатарам - правіла, якое адносіць да аднаго з двух класаў (1 або -1). Каб на аснове адзнакі мадэлі зрабіць класіфікатар, трэба падабраць парог адзнакі. Як менавіта - моцна залежыць ад задачы.

Выкажам здагадку, мы робім тэст (класіфікатар) на нейкую рэдкую і небяспечную хваробу. Па выніках тэсту мы ці адпраўляем пацыента на больш падрабязнае абследаванне, ці кажам: "Здароў, ідзі дадому". Для нас адправіць дадому хворага чалавека значна горш, чым дарма абследаваць здаровага. Гэта значыць, мы хочам, каб тэст спрацоўваў для як мага большай колькасці рэальна хворых людзей. Гэтая велічыня называецца recall =Як у Яндэкс.Таксі шукаюць машыны, калі іх няма. У ідэальнага класіфікатара recall роўны 100%. Выраджаная сітуацыя - адпраўляць на абследаванне ўсіх, тады recall таксама будзе 100%.

Бывае і наадварот. Напрыклад, мы робім тэсціруючую сістэму для студэнтаў, і ў ёй ёсць дэтэктар спісвання. Калі раптам на нейкія выпадкі спісвання не спрацуе праверка, то гэта непрыемна, але не крытычна. З іншага боку, вельмі дрэнна незаслужана вінаваціць студэнтаў у тым, чаго яны не рабілі. Гэта значыць, нам важна, каб сярод станоўчых адказаў класіфікатара было як мага больш правільных, магчыма, у шкоду іх колькасці. Значыць, трэба максымізаваць precision = Як у Яндэкс.Таксі шукаюць машыны, калі іх няма. Калі спрацоўванні стануць адбывацца на ўсіх аб'ектах, то precision будзе роўны частаце вызначанага класа ў выбарцы.

Калі алгарытм выдае лікавае значэнне верагоднасці, то, падбіраючы розныя парогі, можна дамагчыся розных значэнняў precision-recall.

У нашай задачы сітуацыя наступная. Recall - колькасць заказаў, якое мы можам прапанаваць, precision - надзейнасць гэтых заказаў. Вось так выглядае precision-recall крывая нашай мадэлі:
Як у Яндэкс.Таксі шукаюць машыны, калі іх няма
Ёсць два крайнія выпадкі: не дазваляць заказваць нікому і дазваляць заказваць усім. Калі не дазваляць нікому, то recall будзе 0: мы не ствараем заказаў, але затое ніякі з іх не стане правальным. Калі дазваляць усім, то recall будзе 100% (мы атрымаем усе магчымыя замовы), а precision - 29%, т. е. 71% заказаў апынуцца дрэннымі.

У якасці прыкмет мы выкарыстоўвалі розныя параметры кропкі адпраўлення:

  • Час / месца.
  • Стан сістэмы (колькасць занятых машын усіх тарыфаў і пінаў у наваколлі).
  • Параметры пошуку (радыус, колькасць кандыдатаў, абмежаванні).

Больш падрабязна пра прыкметы

Канцэптуальна мы хочам адрозніць дзве сітуацыі:

  • "Глухі лес" - машын тут у гэты час не бывае.
  • Не павезла машыны ёсць, але вось пры пошуку падыходных не апынулася.

Адзін з прыкладаў «Не пашанцавала» - калі ў пятніцу ўвечары ў цэнтры вялікі попыт. Заказаў шмат, ахвочых шмат, вадзіцеляў на ўсіх не хапае. Можа атрымацца так: у піне прыдатных кіроўцаў няма. Але літаральна праз секунды яны з'яўляюцца, таму што тым часам у гэтым месцы вельмі шмат кіроўцаў і іх статут стала змяняецца.

Таму добрымі фічамі апынуліся розныя паказчыкі сістэмы ў наваколлях кропкі А:

  • Агульны лік машын.
  • Лік машын на замове.
  • Лік недаступных для замовы машын у статуце «Заняты».
  • Лік карыстальнікаў.

Бо чым больш вакол машын, тым больш верагодна, што якая-небудзь з іх стане даступнай.
Насамрэч для нас важна, каб не проста знаходзіліся машыны, але і здзяйсняліся паспяховыя паездкі. Таму можна было прадказваць імавернасць паспяховай паездкі. Але вырашылі так не рабіць, таму што гэтая велічыня моцна залежыць ад карыстача і кіроўцы.

У якасці алгарытму навучання мадэлі ўжывалі CatBoost. Для навучання выкарыстоўвалі даныя, атрыманыя з эксперымента. Пасля ўкаранення прыйшлося збіраць навучальныя дадзеныя, часам дазваляючы невялікай колькасці карыстачоў рабіць замову насуперак рашэнню мадэлі.

Вынікі

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

На дадзены момант механізм запушчаны ва ўсіх гарадах і краінах і з яго дапамогай адбываецца каля 1% паспяховых паездак. Прычым у некаторых гарадах з невялікай шчыльнасцю машын доля такіх паездак даходзіць да 15 працэнтаў.

Іншыя пасты аб тэхналогіях Таксі

Крыніца: habr.com

Дадаць каментар