چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد

چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد

یک سرویس تاکسی خوب باید ایمن، قابل اعتماد و سریع باشد. کاربر وارد جزئیات نمی شود: برای او مهم است که روی دکمه "سفارش" کلیک کند و خودرویی را در اسرع وقت دریافت کند که او را از نقطه A به نقطه B برساند. اگر خودرویی در این نزدیکی وجود نداشته باشد، سرویس باید بلافاصله در این مورد اطلاع دهید تا مشتری انتظارات نادرست نداشته باشد. اما اگر علامت "بدون ماشین" خیلی زیاد ظاهر شود، منطقی است که شخص به سادگی استفاده از این سرویس را متوقف کند و به سراغ یک رقیب برود.

در این مقاله می‌خواهم در مورد اینکه چگونه با استفاده از یادگیری ماشینی، مشکل جستجوی خودروها در مناطق کم تراکم (به عبارت دیگر، جایی که در نگاه اول، ماشینی وجود ندارد) را حل کردیم. و از آن چه آمد.

ماقبل تاریخ

برای فراخوانی تاکسی، کاربر چند مرحله ساده را انجام می دهد، اما در داخل سرویس چه اتفاقی می افتد؟

کاربر صحنه Backend Yandex.Taxi
نقطه شروع را انتخاب می کند پین ما در حال راه اندازی یک جستجوی ساده برای نامزدها هستیم - جستجوی پین. بر اساس درایورهای یافت شده، زمان رسیدن پیش بینی می شود - ETA در پین. ضریب افزایش در یک نقطه معین محاسبه می شود.
مقصد، کرایه، الزامات را انتخاب می کند پیشنهاد ما یک مسیر می سازیم و قیمت ها را برای همه تعرفه ها با در نظر گرفتن ضریب افزایش محاسبه می کنیم.
دکمه "تماس با تاکسی" را فشار می دهد سفارش ما یک جستجوی کامل برای ماشین راه اندازی می کنیم. ما مناسب ترین راننده را انتخاب می کنیم و به او سفارش می دهیم.

بر ETA در پین, محاسبه قیمت и انتخاب مناسب ترین راننده قبلا نوشتیم و این یک داستان در مورد یافتن رانندگان است. هنگامی که یک سفارش ایجاد می شود، جستجو دو بار انجام می شود: روی پین و روی سفارش. جستجو برای سفارش در دو مرحله انجام می شود: جذب نامزدها و رتبه بندی. اول، رانندگان کاندید موجود که نزدیکترین آنها در امتداد نمودار جاده هستند پیدا می شوند. سپس پاداش و فیلتر اعمال می شود. نامزدهای باقی مانده رتبه بندی می شوند و برنده پیشنهاد سفارش دریافت می کند. در صورت موافقت، به او سفارش داده می شود و به محل تحویل می رود. اگر او امتناع کرد، پیشنهاد به پیشنهاد بعدی می رسد. اگر نامزد دیگری وجود نداشته باشد، جستجو دوباره شروع می شود. این بیش از سه دقیقه طول نمی کشد، پس از آن سفارش لغو و سوزانده می شود.

جستجو در پین شبیه به جستجو در یک سفارش است، فقط سفارش ایجاد نمی شود و خود جستجو فقط یک بار انجام می شود. تنظیمات ساده شده برای تعداد نامزدها و شعاع جستجو نیز استفاده می شود. چنین ساده‌سازی‌هایی ضروری هستند، زیرا تعداد پین‌های مرتبه‌ای بیشتر از سفارش‌ها وجود دارد و جستجو عملیات نسبتاً دشواری است. نکته کلیدی برای داستان ما: اگر در طول جستجوی اولیه هیچ نامزد مناسبی در پین پیدا نشد، پس ما به شما اجازه نمی دهیم که سفارش دهید. حداقل قبلا اینطور بود.

این چیزی است که کاربر در برنامه مشاهده کرد:

چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد

جستجوی خودروهای بدون خودرو

یک روز به یک فرضیه رسیدیم: شاید در برخی موارد هنوز بتوان سفارش را تکمیل کرد، حتی اگر هیچ ماشینی روی پین وجود نداشته باشد. از این گذشته، مدتی بین پین و سفارش می گذرد و جستجو برای سفارش کامل تر است و گاهی اوقات چندین بار تکرار می شود: در این مدت ممکن است درایورهای موجود ظاهر شوند. ما برعکس آن را هم می‌دانستیم: اگر راننده‌هایی روی پین پیدا می‌شدند، این واقعیت نداشت که هنگام سفارش پیدا شوند. گاهی اوقات آنها ناپدید می شوند یا همه از دستور خودداری می کنند.

برای آزمایش این فرضیه، آزمایشی را راه‌اندازی کردیم: ما در حین جستجو در پین برای یک گروه آزمایشی از کاربران، بررسی حضور خودروها را متوقف کردیم، یعنی آنها این فرصت را داشتند که "سفارش بدون خودرو" را انجام دهند. نتیجه کاملا غیرمنتظره بود: اگر ماشین روی پین نبود ، در 29٪ موارد بعداً پیدا شد - هنگام جستجوی سفارش! علاوه بر این، سفارش‌های بدون خودرو از نظر نرخ لغو، رتبه‌بندی و سایر شاخص‌های کیفیت تفاوت قابل‌توجهی با سفارش‌های معمولی نداشتند. رزروهای بدون خودرو 5 درصد از کل رزروها را تشکیل می دهند، اما کمی بیش از 1 درصد از کل سفرهای موفق را تشکیل می دهند.

برای درک اینکه مجریان این دستورات از کجا آمده‌اند، بیایید به وضعیت آنها در حین جستجو در یک پین نگاه کنیم:

چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد

  • در دسترس: در دسترس بود، اما به دلایلی در بین نامزدها قرار نگرفت، به عنوان مثال، او خیلی دور بود.
  • به سفارش: مشغول بود، اما توانست خود را آزاد کند یا برای آن در دسترس باشد ترتیب زنجیره ای;
  • مشغول: توانایی پذیرش سفارشات غیرفعال شد، اما سپس راننده به خط بازگشت.
  • در دسترس نیست: راننده آنلاین نبود، اما ظاهر شد.

بیایید قابلیت اطمینان را اضافه کنیم

سفارشات اضافی عالی هستند، اما 29 درصد از جستجوهای موفق به این معنی است که 71 درصد از مواقع کاربر مدت زیادی منتظر ماند و در نهایت به جایی نرسید. اگرچه این موضوع از نظر کارایی سیستم چیز بدی نیست، اما در واقع به کاربر امید کاذب می دهد و زمان را تلف می کند و پس از آن ناراحت می شود و (احتمالا) استفاده از سرویس را متوقف می کند. برای حل این مشکل، ما یاد گرفتیم که احتمال پیدا شدن خودروی سفارشی را پیش بینی کنیم.

این طرح به شرح زیر است:

  • کاربر یک پین قرار می دهد.
  • جستجو در پین انجام می شود.
  • اگر ماشینی وجود نداشته باشد، پیش بینی می کنیم: شاید ظاهر شوند.
  • و بسته به احتمال، به شما اجازه سفارش می دهیم یا نمی دهیم، اما به شما هشدار می دهیم که تراکم خودرو در این منطقه در این زمان کم است.

در برنامه به این شکل بود:

چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد

استفاده از مدل به شما این امکان را می دهد که سفارشات جدید را با دقت بیشتری ایجاد کنید و بیهوده به مردم اطمینان ندهید. یعنی تنظیم نسبت قابلیت اطمینان و تعداد سفارشات بدون ماشین با استفاده از مدل فراخوان دقیق. قابلیت اطمینان سرویس بر تمایل به ادامه استفاده از محصول تأثیر می گذارد، یعنی در نهایت همه چیز به تعداد سفرها کاهش می یابد.

کمی در مورد یادآوری دقیقیکی از وظایف اساسی در یادگیری ماشین، وظیفه طبقه بندی است: تخصیص یک شی به یکی از دو کلاس. در این حالت، نتیجه الگوریتم یادگیری ماشین اغلب به ارزیابی عددی عضویت در یکی از کلاس ها تبدیل می شود، به عنوان مثال، ارزیابی احتمال. با این حال، اقداماتی که انجام می‌شوند معمولا باینری هستند: اگر ماشین در دسترس باشد، به شما اجازه می‌دهیم آن را سفارش دهید، و اگر نه، آن‌وقت سفارش نمی‌دهیم. برای مشخص بودن، بیایید الگوریتمی را که تخمین عددی را تولید می‌کند، مدل، و طبقه‌بندی کننده را یک قانون که آن را به یکی از دو کلاس (1 یا -1) اختصاص می‌دهد، بنامیم. برای ایجاد یک طبقه‌بندی بر اساس ارزیابی مدل، باید آستانه ارزیابی را انتخاب کنید. اینکه دقیقا چقدر به کار بستگی دارد.

فرض کنید در حال انجام آزمایش (طبقه بندی) برای برخی از بیماری های نادر و خطرناک هستیم. بر اساس نتایج آزمایش، یا بیمار را برای معاینه دقیق تر می فرستیم یا می گوییم: "خوب، برو خانه." برای ما فرستادن یک بیمار به خانه بسیار بدتر از معاینه بیهوده یک فرد سالم است. یعنی ما می‌خواهیم این آزمایش برای هر چه بیشتر افراد واقعاً بیمار کار کند. این مقدار recall = نامیده می شودچگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد. یک طبقه‌بندی ایده‌آل فراخوانی 100% دارد. یک وضعیت منحط این است که همه را برای معاینه بفرستیم، سپس فراخوان نیز 100٪ خواهد بود.

برعکس هم اتفاق می افتد. به عنوان مثال، ما در حال ساخت یک سیستم تست برای دانش آموزان هستیم و این سیستم تشخیص تقلب دارد. اگر به طور ناگهانی چک برای برخی موارد تقلب کار نکرد، این ناخوشایند است، اما مهم نیست. از سوی دیگر، متهم کردن ناعادلانه دانش آموزان به کاری که انجام نداده اند، بسیار بد است. یعنی برای ما مهم است که در بین پاسخ های مثبت طبقه بندی کننده تا حد امکان پاسخ های صحیح وجود داشته باشد که شاید به ضرر تعداد آنها باشد. این بدان معنی است که شما باید دقت = را به حداکثر برسانید چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد. اگر تحریک روی همه اشیا اتفاق بیفتد، آنگاه دقت برابر با فرکانس کلاس تعریف شده در نمونه خواهد بود.

اگر الگوریتم یک مقدار احتمال عددی تولید کند، با انتخاب آستانه‌های مختلف، می‌توانید مقادیر دقیق فراخوانی متفاوتی را بدست آورید.

در مشکل ما وضعیت به شرح زیر است. یادآوری تعداد سفارش‌هایی است که می‌توانیم ارائه دهیم، دقت، قابلیت اطمینان این سفارش‌ها است. منحنی فراخوان دقیق مدل ما به این صورت است:
چگونه Yandex.Taxi ماشین‌ها را جستجو می‌کند در حالی که وجود ندارد
دو حالت افراطی وجود دارد: اجازه ندهید کسی سفارش دهد و اجازه دهید همه سفارش دهند. اگر به کسی اجازه ندهید، یادآوری 0 خواهد بود: ما سفارشی ایجاد نمی کنیم، اما هیچ یک از آنها شکست نمی خورد. اگر به همه اجازه دهیم، فراخوان 100٪ خواهد بود (همه سفارشات ممکن را دریافت خواهیم کرد) و دقت 29٪ خواهد بود، یعنی 71٪ سفارشات بد خواهد بود.

ما از پارامترهای مختلف نقطه شروع به عنوان نشانه استفاده کردیم:

  • زمان/مکان.
  • وضعیت سیستم (تعداد ماشین آلات اشغال شده از همه تعرفه ها و پین ها در مجاورت).
  • پارامترهای جستجو (شعاع، تعداد نامزدها، محدودیت ها).

بیشتر در مورد علائم

از نظر مفهومی، ما می خواهیم بین دو موقعیت تمایز قائل شویم:

  • "جنگل عمیق" - در حال حاضر هیچ ماشینی در اینجا وجود ندارد.
  • "بدشانس" - ماشین هایی وجود دارد، اما هنگام جستجو هیچ ماشین مناسبی وجود نداشت.

یکی از مثال‌های «بدشانس» این است که در عصر جمعه تقاضای زیادی در مرکز وجود داشته باشد. تعداد زیادی سفارش وجود دارد، افراد زیادی مایل هستند و رانندگان کافی برای همه وجود ندارد. ممکن است اینگونه باشد: هیچ درایور مناسبی در پین وجود ندارد. اما به معنای واقعی کلمه در عرض چند ثانیه ظاهر می شوند، زیرا در این زمان رانندگان زیادی در این مکان هستند و وضعیت آنها دائما در حال تغییر است.

بنابراین، نشانگرهای مختلف سیستم در مجاورت نقطه A ویژگی های خوبی بودند:

  • تعداد کل ماشین ها
  • تعداد ماشین های سفارشی
  • تعداد خودروهایی که در وضعیت «مشغول» برای سفارش در دسترس نیستند.
  • تعداد کاربران.

به هر حال، هر چه تعداد خودروها بیشتر باشد، احتمال اینکه یکی از آنها در دسترس باشد، بیشتر می شود.
در واقع برای ما مهم است که نه تنها خودروها جانمایی شوند، بلکه سفرهای موفقی نیز انجام شود. بنابراین می توان احتمال یک سفر موفق را پیش بینی کرد. اما ما تصمیم گرفتیم این کار را انجام ندهیم، زیرا این مقدار تا حد زیادی به کاربر و راننده بستگی دارد.

الگوریتم آموزش مدل بود CatBoost. داده های به دست آمده از آزمایش برای آموزش استفاده شد. پس از پیاده‌سازی، داده‌های آموزشی باید جمع‌آوری می‌شد و گاهی اوقات به تعداد کمی از کاربران اجازه می‌داد خلاف تصمیم مدل سفارش دهند.

نمایش نتایج: از

نتایج آزمایش مطابق انتظار بود: استفاده از مدل به شما امکان می دهد تعداد سفرهای موفقیت آمیز را به دلیل سفارشات بدون اتومبیل، اما بدون به خطر انداختن قابلیت اطمینان، به میزان قابل توجهی افزایش دهید.

در حال حاضر این سازوکار در تمامی شهرها و کشورها راه اندازی شده است و با کمک آن حدود 1 درصد از سفرهای موفق انجام می شود. همچنین در برخی از شهرهای با تراکم کم خودرو، سهم چنین سفرهایی به 15 درصد می رسد.

پست های دیگر در مورد تکنولوژی تاکسی

منبع: www.habr.com

اضافه کردن نظر