Як ми відрізняли візок від виконроба — видеоаналитика для касової зони гіпермаркету (і продовження про кота-термінатора)

В одному будівельному гіпермаркеті є 18 кас, і треба вміти робити так, щоб касири відкривали їх вчасно, щоб чергу не була більше 4 чоловік. Ну, і щоб зайві каси не простоювали відкритими. Це розпізнавання людей (підрахунок покупців) з відео, аналітика по погоді і іншим факторам та передбачення потоку. Плюс багато іншого забавною статистики.


Приклад черги перед касою — картинка обрізана і замилена на прохання сб, за фактом чергу ми бачимо довше, ніж на фото.

У роздробі першим питанням стало те, як відрізнити виконроба від візка. І це було анітрохи не смішно.

Так, і тим, хто переживав за кота-термінатора з минулого поста — його впіймали. Деталі в кінці.

До цього ми робили щось подібне для кас приміських електричок і самих електричок. У випадку з касами довжина черги відмінно розпізнається, і касири стали працювати куди оптимальніше. А ось на перонах дешевше виявилося фіксувати зайців не камерами, а просто ставити вохру.

Кластери покупців

На вході у нас дані з камер, які дивляться вертикально вниз на каси. Картинка з них розпізнається ЗА Synesis CasRetail, і ми маємо вже не відеопотік, а дані про те, у скільки прийшов якийсь об'єкт і скільки він покинув зону дії.


Нарешті у нас з'явилася повна закінчена історія аналітики, яку можна розповісти.

Ось приклад лода (розшифровувати не став, і так ніби має бути зрозуміло):
{
"camera" : "22f961d5-9cfc-4214-8870-65edb79fe373",
"start" : "2016-09-11T14:28:03+03:00",
"end" : "2016-09-11T14:29:00+03:00",
"rules" : [
// дані для лінії 
{
"counter" : 12,
"rule" : "36da29cf-7858-4bc6-9b11-55ff129aeaa7",
"extendedStatistics" : [ "2015-02-11T14:28:04+03:00", "2015-02-11T14:28:04+03:00", "2015-02-11T14:28:12+03:00"] // (optional)
},
// дані для зони 
{
"counter" : 0,
"histogram":[57.61533203125003,0.0, .., 0.0,0.0], // total 256 items
"lifetimeHistogram" : [],
"lifetimeHistogramStep" : 60,
"lostObjectsCounter" : 2,
"bornObjectsCounter" : 0,
"objectsAtEndInterval" : 12,
"rule" : "ea473652-2f7d-49fc-bce0-e6d93e472c17"
}
]
}


Дані з кас за чеками ми брати не могли — вони безпосередньо з'єднані з Європою по VPN, і, на жаль і ах, потрібно подолати одразу два законодавства щодо персональних даних. Загалом, якщо ми не хочемо чекати рік (а ми не хочемо), цих даних на практиці немає.

ЗА обробляє картинку 640х480 і, до речі, для завдання підрахунку покупців більше і не потрібно. Система справляється легко… Так-так, downsample майже в 3 рази і це збільшує швидкість обробки зображення. Тут не потрібно багато мегапікселів, так як людина може займати в кадрі всього 30-40 пікселів.

Проблема визначення кількості людей за ловга ніяк не вирішувалася, і ось чому:
  • Покупець може прийти натовпом (наприклад, сім'єю). За фактом буде 3-4 людини, але реально — один чек. А дані про чек в європейській країні, і якщо ви не хочете чекати рік… ну, ви зрозуміли.
  • Може прийти виконроб, набрати будматеріалів в 3-4 візки і піти. Система отфиксирует групу об'єктів, але покупець буде знову один.
  • Матір з коляскою і візком — це 3 незрозумілих об'єкта.


Ми прийшли до того, що прямо на касі така задача не вирішується швидко, без копання в низькому рівні розпізнавання, ніяк. Промислово, звичайно, можна профілювати візки та інші об'єкти, але ми згадали дядька Дейкстру з його історією з залізничними вагонами і вирішили ще поспостерігати.

Через кілька днів спостережень за звичками візків з'ясувалося, що вони горнуться до людей. І група людей, зробила один чек, практично одночасно йде з касової зони. Тобто задача зводилася до підрахунку кластерів об'єктів, які виходять за віртуальну лінію каси (на картинці — tripwire_11) — а це вирішується дуже просто. До речі, лінія потрібна для того, щоб коректно розуміти, коли чоловік пішов з каси. адже якщо він вийшов із зони, то він просто міг піти з черги назад у зал (наприклад, психанув, не став чекати).

Тобто система в реальному часі видає статистику «два об'єкта ≈ один покупець» і з цього показує довжину черги. А з затримкою 1 хвилину валидирует себе і уточнює, скільки покупців було за фактом на основі того, як вони повели себе за касою.

Це було суперкруто. Ми вирішили майже всі проблеми такої системою з помилкою в 2-5% (залежить від кількості візків, прибиральниць, охоронців та інших відхилень від статистичного середнього).

Сюрпризи розпізнавання

Отже, ми:
  • Знаємо вхідний потік людей за кожен день і знаємо його в реальному часі.
  • Знаємо довжину черги на кожній касі.
  • Вміємо робити в реальному часі повідомлення про те, що треба відкривати ще касу (десь чергу довше 4-5 чоловік).
  • Вміємо закривати каси, якщо вони порожні.
  • Починаємо збирати дані для аналізу для передбачення розкладу кас.


Зараз системі вже півроку, і вона працює з хорошим рівнем складання розкладу, але тоді історичних даних у нас не було. Тому для початку ми вважали за пару тижнів завантаження кас. Висновки вийшли парадоксальні:
  • Так, є моменти, коли потрібно більше касирів.
  • Так, є моменти, коли магазин несе втрати через простоюють кас (сотні тисяч рублів на місяць).
  • найвеселіше — при піках на касах 10-18 каси 1-3 можуть бути не завантажені.


Про останнє скажу окремо: виявляється, люди не вміють грамотно розподілятися по касі. І цілком можливі ситуації, коли якісь каси простоюють, а якісь завантажені. Уміле розподіл дозволяє сильно заощадити за фактом, і магазин цьому навчився.


Результати аналізу динаміки максимальної і середньої довжини черги по зонах обслуговування на одну з дат

Хід проекту

Потім ми зробили для операційного керуючого дашборд, де видно дані по кожній касі раз в півгодини з середньою і максимальною завантаженням. Дві штрафні функції — мало людей і багато людей. Виходить накопичена статистика: сумарний простій касирів, перевантаження і так далі.
Мінімальна зміна касира з аутстаффа (зовнішньої компанії, що надає касирів) — 4 години. Чим раніше касир буде замовлено, тим дешевше. Тому далі задача зводиться, по-перше, до прогнозування (треба знати, скільки касирів і коли треба, алгоритм, треба сказати, не з простих — для тих, хто в темі — це блендінг з 6 від класичних моделей ARIMA до RandomForest (любителям kaggle — і без xgBoost можна точно прогнозувати). А по-друге, до оптимізації на основі прогнозних даних, а саме — до мінімізації загальної вартості персоналу при дотриманні необхідного рівня сервісу і купи технічних обмежень (наприклад, аутстафф касира не можна висмикнути менше ніж на півдня).

Через місяць ми вирішили цю задачу без урахування сезонних піків:
  • Історичні дані по днях дають точну завантаження по годинах.
  • Є профілі для кожного дня тижня.
  • Є спецпрофили для ситуацій «опади», «свято», «день перед вихідними», «день перед 3 вихідними» — це дуже важливі ситуації для аналітики. Дощ, наприклад, дає мінус 18 відсотків до покупцям, а день перед 3 вихідними — плюс 14%.
  • Є дані про погоду.
  • Є кореляти з інших проектів (відомі графіки колег з усього світу) — там просто 3-4 виміру за день, але вони дуже корисні іноді, коли немає даних (наприклад, будуть корисні на Новий рік).
  • Ми знаємо конверсію, тобто з якою ймовірністю зайшов у магазин стане покупцем. Це просто множник до вихідного потоку.
  • Для людей, що заходять через каси, ми теж знаємо зразкові коефіцієнти — їх довелося вважати руками, але вони вносять дуже малу похибку.


Все це разом просто компонується як модифікатори (кожен профіль — це графік, тобто матриця), та суперпозиція векторів кожні півгодини дає прогнозовану навантаження. А потім на це накладається обмеження по тривалості зміни і допустима похибка — і складається розклад.

Система може вчитися, і сама себе верифікувати за схемою " план-факт. Плюс можна прикрутити email-повідомлення, збирати статистику.

Далі

В цілому система працює. Маркетологи щасливі. До неї зараз придивляється і минулий замовник з історії з котом. Є в тому числі інтерес у їхніх європейських колег для ряду об'єктів, вважаємо зараз і для них.

А це результати нашого тесту або «жартівливого» сервісу під назвою «пробки в їдальні». Теж відмінно працює вже кілька років. Для того, щоб ним скористатися, достатньо зайти в корпоративну соцмережа, де в реальному часі можна подивитися поточну завантаженість нашої офісній їдальні, а також прогноз часу, необхідного для того, щоб відстояти чергу в касу і пообідати в залежності від того, коли підійти. І що найцікавіше – зовсім недавно таку систему собі захотіли запровадити два зовнішніх замовника. Один з них, наприклад, як виявилося, вже 2 роки безрезультатно бився з величезними чергами в їдальні.





Про кота

Нагадаю, в минулому пості про розпізнавання осіб на вході на об'єкт фігурував кіт, що завдає збитку магазину на 50-100 тисяч рублів на місяць. Цей невтомний мисливець відзначився на відеоспостереженні тінню, стрибаючою зверху на найжирніші мішки з кормом і вскрывающей їх у пошуках теплих соковитих нутрощів. А ще на нього списували багато дорогого алкоголю.

Кіт втікав від погоні 4 роки. Навіть коли за нього (живого) давали нагороду 5 тисяч рублів, його не могли спіймати протягом декількох місяців. Але після минулого посту тварина збагнув хабраэффект: співробітники організувалися і вистежили дикого звіра. Спійманий кіт тепер живе в найближчій до магазину військової частини (у ролі талісмана) і звикає до людей. Ось його хитра пика:



проекти

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.