ELK для бизнес-аналитики: как мы разбираем причины интервенций на кассах самообслуживания с весовой платформой

49ee7d92ca8a6f6f348d069b2df0f17f.png

Привет! Меня зовут Даша, я работаю в CSI в команде, которая развивает направление самообслуживания. За 10 лет мы установили больше 10 тысяч касс самообслуживания в магазины торговых сетей — и у нас есть касса самообслуживания собственной разработки, которую зовут CSI K. Вы точно хотя бы раз видели её в магазине. 

Давайте для начала разберемся, что такое интервенция. В контексте касс самообслуживания — это ситуация, когда штатный процесс самостоятельной покупки прерывается вмешательством помощника на «острове» самообслуживания. Это плохо для всех: для покупателя (дольше покупка) и для ритейлера (увеличение длительности покупки и затраты на работу помощников). Поэтому задача нашей команды — снижать количество таких интервенций.

Пару лет назад мы разработали для нашей кассы самообслуживания новый модуль — контрольно-весовую платформу (КВП). Она контролирует вес отсканированного товара, положенного покупателем на платформу, и сравнивает его с тем, что находится в базе кассы. Это позволяет предотвратить как махинации со стороны покупателя, так и просто ошибки. Нашей КВП укомплектованы уже больше 2000 касс CSI K, но мы продолжаем совершенствовать её работу.

В статье я расскажу, как мы решили вопрос со сбором данных с КВП наших клиентов — тех данных, которые позволяют нам анализировать работу платформы, точно выявлять причины возникающих ошибок и устранять их. По техническим вопросам мне помогал коллега Роман, так что он тут тоже незримо присутствует :)

Итак, конечная задача — в том, чтобы покупателям как можно реже приходилось видеть вот такой экран с той самой интервенцией:

b765692b9a5c927be98c8fbf35498bb8.png

Контрольно-весовая платформа

deb4c19f079a19697f20aa4e67918abb.png

Вот наша касса. Обратите внимание на металлическую консоль. В центре ритейлер может установить весы, чтобы покупатель мог взвесить прямо на кассе ветку бананов. Полочки по бокам — это элементы КВП.

2ba0dcbfcf892dff71932c78e07c0067.png

Берете товар из корзины, сканируете, перекладываете на другую сторону. Под полкой — чувствительные весы. Платформа сверяет вес товара. 

Откуда появляется вес в базе? Платформа обучается сама. При первом сканировании касса запоминает вес каждого товара, продающегося в магазине. Если в следующий раз он не совпадает — вы понимаете, что будет: та самая интервенция. Помощник подтверждает или отклоняет вес товара, тем самым дообучая КВП, устанавливая для товара новые границы веса. Безусловно, в модуле задаются допустимые отклонения веса, и вообще есть масса гибких настроек по разным категориям товаров, призванных избежать ненужных интервенций. На практике очень важно, чтобы консультант всегда действовал правильно — тогда платформа переобучается. Не узнав правильный вес, касса так и будет каждый раз останавливать покупку и бесить покупателей.

Итак, общая задача — снизить количество интервенций до минимально необходимого (подтверждение возраста, например) и полностью убрать ошибки, связанные с весовой платформой. Для этого нам с ритейлером нужно оперативно и объективно оценить: что вызывает интервенции на его кассах, сколько их, на какие товары «ругается» платформа, где реально проблема в КВП, а где неправильно реагирует персонал.

Как получить эти данные?  

Напомню, мы разработали модуль КВП с нуля. Поначалу — в силу небольшого количества инсталляций, нужные данные мы могли получать из логов платформы вручную. Но магазинов становилось больше, процесс трудозатратнее и дольше (нужно ведь обеспечить доступ, подключаться к каждой кассе и анализировать логи, выбирая проблемные товары и реакции помощника). Сами клиенты не всегда готовы предоставить данные для анализа, особенно в случае плавающих ошибок.

Потребовалось технологичное решение. Его описание вместе с интересными живыми примерами аналитики я предлагаю вам далее. 

Наше решение: инструменты и процесс — шаг за шагом 

Что нужно — получать события с кассы и отправлять их на анализ. 

Что мы используем для сбора и анализа — стек ELK для парсинга лог-файлов с кассы. 

Стек ELK развернем на своем сервере — это будет точкой входа для касс разных клиентов, и будем максимально сокращать трафик, чтобы можно было подключить больше касс.

Какие события нам нужны — сообщения об ошибках работы весовой службы контроля, неподтверждение веса товара, действие помощника на кассе.

Что мы хотим получить на выходе — дашборды по проблемным товарам и по кассам, где есть проблемы с контролем веса товара. 

714275b1f99b16a08ea53ee514ebd04f.png

Шаг 1. Установка службы сбора данных filebeat на кассу

Касса работает под операционной системой linux ubuntu 22.04, поэтому будем скачивать deb пакет для установки. Как правило, кассам в сети клиента закрыт доступ к внешним репозиториям в целях безопасности. Поэтому заранее выкачаем пакет и скопируем на кассу. (в одну строку)

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.12.1-amd64.deb

Напишем инсталлятор для установки, чтобы потом было удобно автоматизировать процесс доставки и запуска его на кассах. 

sudo dpkg -i ./filebeat-8.12.1-amd64.deb
sudo systemctl enable filebeat
sudo service filebeat restart

Добавим в скрипт копирование нашего yml файла, обязательно меняем права на файл, иначе будет ошибка при запуске.

sudo cp -f ./filebeat.yml /etc/filebeat/
sudo chown root:root /etc/filebeat/filebeat.yml
sudo chmod 600 /etc/filebeat/filebeat.yml

Еще раз перезапустим filebeat, чтобы применилась наша конфигурация

sudo service filebeat restart

Все, теперь касса отправляет события. Далее разберем конфигурацию для наших задач.

Шаг 2. Настройка получения данных о событиях с кассы 

В нашем случае касса записывает в отдельный лог события по каждому товару, вес которого не соответствует записанному в БД кассы. Такие события мы будем передавать в ELK. 

В filebeat.yml добавим следующее правило:

 — type: log

    enabled: true

    paths:

 — /home/tc/storage/crystal-cash/reports/logWrongItem.csv

    scan_frequency: 10s

    include_lines:  

 — '^\d{2}\.\d{2}\.\d{4};\d{2}:\d{2}:\d{2};\d{7,14};\d{1,5};.*$'

    processors:

 — dissect:

        field: message

        tokenizer: '%{datetime};%{+datetime};%{barcode};%{weight};%{item}'

        target_prefix: wrongitem

 — add_fields:

        target: event

        fields:

          error: «Вес товара не соответствует заданному»

По этим данным можно выявить топ-100 самых проблемных товаров в рамках одного магазина или всей торговой сети и далее уже более детально разбираться с каждым товаром. 

Салат в горшочке, минтай, бананы и вода — что не так?  

Немного забегу вперед и покажу график и выводы, которые объяснят ценность полученных данных для ритейлера.

6b211da90b47c8ab36ed202ead01fc6b.png

Вот, например, мы выяснили, что в этот список часто попадают товары с непостоянным весом. 

Лидер в данном конкретном случае — салат в горшочке. Продается поштучно, а вес его варьируется в рамках 100 грамм, и это не соответствует заданным параметрам точности контрольно-весовой службы и базе весов товаров. Для остальных товаров допуски намного меньше, всего несколько грамм. 

Также в топ проблемных товаровпопадает свежемороженый минтай. Почему? Здесь разница (и соответственно необходимость подтверждения веса) возникает от того, что на рыбе может накапливаться глазурь или наледь, которая не влияет на цену, если рыба взвешена заранее, но вызывает необходимость подтвердить, что товар соответствует указанному на штрихкоде, потому что вес увеличился из-за наледи.

Емкость с водой 5 литров при установке на контрольно-весовую платформу может долгое время стабилизироваться, потому что вода качается и влияет на тензодатчик в платформе. 

Бананы относятся к товарам, которые покупают очень часто, по ним в целом больше взвешиваний и они также могут разваливаться в пакете, если их несколько, при расположении на платформе — это влияет на время стабилизации веса, то есть бананы еще качаются, а платформа уже считала вес и он не соответствует тому, что указано в ШК.

Но в список попадают и товары с очевидно неменяющимся весом, например макароны весом 450 гр. По таким товарам существенных отклонений быть не должно. Скорее всего, по товару был сохранен некорректный вес и теперь КВП постоянно на этот товар «ругается». В этом случае помощник должен сохранить для него новый корректный вес. Проблема в том, что помощнику на острове часто некогда читать сообщения кассы и даже товары с некорректным весом пропускаются. 

Мы хотим знать, что делает помощник, если видит подобную ситуацию

Для этого «вытащим» события из лога кассы, которые покажут нам, как он отреагировал. У него есть 3 варианта:  

  1. переобучить кассу (Запомнить новый вес товара),  

  2. добавить товар в чек без переобучения (Пропустить),

  3. отменить добавление товара в чек. 

cae434ae07320f380e5ace0abcad92dc.png

Мы также хотим знать, проверяет ли помощник состав чека после подобной ошибки или халатно относится к своим обязанностям, допуская потери магазина. 

Добавим правила в filebeat.xml для этих событий:

— type: log

    enabled: true

    paths:

 — /home/tc/storage/crystal-cash/logs/visualization.log

    scan_frequency: 10s

    include_lines:  

 — INFO +\[visualization\].+mouseReleased.+Запомнить новый вес

 — INFO +\[visualization\].+mouseReleased.+Пропустить

 — INFO +\[visualization\].+mouseReleased.+Удалить товар из чека

 — INFO +\[visualization\].+mouseReleased.+Эти ошибки исправлены

 — 'INFO +\[visualization\] Нажатие кнопки: Проверить список товаров'

 — 'DEBUG +\[visualization\] Нажатие кнопки: Тарирование контрольных весов'

 — 'INFO +\[visualization\] Нажатие кнопки: Тарирование контрольных весов'

    processors:

 — add_fields:

        when.regexp.message: «Запомнить новый вес»

        target: event

        fields:

          button: 'Запомнить новый вес для товара' 

 — add_fields:

        when.regexp.message: «Пропустить»

        target: event

        fields:

          button: 'Пропустить товар с неправильным весом' 

 — add_fields:

        when.regexp.message: «Удалить товар из чека»

        target: event

        fields:

          button: 'Удалить товар из чека' 

 — add_fields:

        when.regexp.message: «Эти ошибки исправлены»

        target: event

        fields:

          button: 'Эти ошибки исправлены'

          error: 'Верните товар на платформу'

 — add_fields:

        when.regexp.message: «Проверить список товаров»

        target: event

        fields:

          button: 'Проверить список товаров'

          error: 'Верните товар на платформу'

 — add_fields:

        when.regexp.message: «Тарирование контрольных весов»

        target: event

        fields:

          button: 'Тарирование контрольных весов' 

Шаг 3. Превращаем данные в дашборды. Как мы из логов строим графики 

  1. Сформировав правила для получения необходимых данных, мы можем создать дашборды. Нажимаем Create Visualization, выбираем нужный тип графика и переходим на экран настройки. Слева перечень полей, которые можно использовать, перетягивая их вправо формируем график.

c3e772bab0b02defd8d8800025e2d203.png

Например, переносим в основное окошко поле @timestamp по вертикальной оси отобразится общее количество записей по временным промежуткам и визуализация изменится следующим образом:

b271a4e1f87c3d9c0b2704d6c1735c89.png

Для данных в отчетах можно выводить суммирующие значения за период, медиану, среднее, нужный персентиль и так далее, то есть весь необходимый инструмент работы с данными для аналитика. 

На данном этапе мы не добавляем фильтров по сетям/магазинам/кассам, их вынесем на готовый дашборд, чтобы данные фильтровались по всем графикам сразу (для этого необходимо, чтобы данные тянулись из одного источника). 

После создания нужных графиков добавляем их на дашборд.

  1. В ходе наших экспериментов с наглядностью графиков получился вот такой результат:

92492f576bc53472cc16efc62062ebe5.png

  • Количество прерываний покупки по событиям, связанным с работой КВП — когда контрольно-весовая платформа не ожидает, что вес изменится: например, покупатель перекладывает покупки на платформе, кладет неотсканированный товар на платформу и когда возникает расхождение фактического веса товара с тем, что записано в весовой базе.

e75abc481100d79d89c8b36246bcb3cf.png

  • Те же самые прерывания покупки по событиям, связанным с работой КВП, но отображаемые общим количеством, для оценки распределения их в течение недели. В большинстве магазинов по выходным увеличивается количество покупок, а значит и количество событий, получаемых в результате работы касс. В общем количестве легче посмотреть корреляцию с днями недели.

42d168c85509650fcc3de898f4d93eac.png196e8d2f5d5a628b6c9c71f85f5806eb.png

  • Распределение того, какой вес был фактически помещен на КВП. Удобнее использовать при изучении конкретного проблемного товара. 

4dea0dc9dc1d432589bd8203f8fc5494.png

  • ТОП проблемных товаров по ШК, а не по наименованию (для удобства поиска конкретного товара в весовой базе, например). 

4c236a6557bb87f37b7e1e5f457c1df1.png

  • И еще одна последняя табличка, в которой можно посмотреть, с каких магазинов и касс сейчас есть события. Это полезно, потому что бывает, что кассы обновляются или вносятся какие-то существенные изменения в настройки, и данные перестают поступать с касс.

0e74cf4b49fcee846e9657ada347f8ab.png

В верхней панели, над дашбордом, можно отфильтровать данные по сети/магазину/кассе, указать необходимый период выборки данных. Есть еще одна особенность — сейчас при подключении нового магазина все имеющиеся данные распределяются не по фактическому времени события, а фиксируются временем подключения магазина к сервису, что искажает данные для аналитики. 

  1. Основной график, который мы используем для понимания проблемных товаров, представлен ниже (туда попадают только товары, вес которых не сошелся с тем, что есть в весовой базе КВП). А при выборе, например, конкретного товара, который повторяется чаще всех, можно посмотреть, какой вес был помещен на КВП и сколько раз это происходило за выбранный период.

07b3f6344c43525edba5c5de3c511fe5.png

Например, выбрав «Молоко, 900 мл», мы увидим, с каким весом товар был помещен на КВП и соответственно какой вес КВП не устроил:

dddac3d5704c4af78750d8525e76b2f0.png

Мы видим, что наибольшее количество повторений было с весом 940 грамм, затем 960 грамм — с учетом возможных отклонений, это нормальные значения, на них КВП не должна выдавать ошибку. А далее идет вес 1880 грамм — очевидно, в этот момент на КВП было помещено два товара вместо одного, то есть это не ошибка работы КВП. Используя ШК товара из другого графика, мы можем посмотреть в БД, с каким весом этот товар сейчас сохранен. А посмотрев на последнюю табличку дашборда, мы узнаем, в каких магазинах и на каких кассах были ошибки по данному товару. 

На следующем графике видно, в какие дни происходили ошибки. После 2 марта событий по данном товару не было, потому что вес в БД был скорректирован помощником на кассе или диапазон автоматически расширился от большого количества повторений:

e4884d8a9aeeae2e309662dd8a63655c.png

Мы можем проверить, является ли вес в БД корректным на текущую дату, и не включать товар в список на переобучение веса (в данном случае описан ручной процесс проверки, на деле выбор товаров на переобучение производится с помощью скрипта, а ELK в большей степени используется для общей оценки «до и после»).

Как мы соотносим данные по товарам с данными по интервенциям?  

Параллельно мы сопоставляем данные по чекам и количество интервенций помощника с тем, что видим в ELK. Например, получая большое количество интервенций (больше 1 подхода помощника на 5 покупок при наличии КВП), мы смотрим на данный график:

e296c9b3e4f1a2e59ef595b336ef58ae.png

В данном случае мы видим большой процент аннуляций (7,73%), то есть покупатели часто бросают корзину неоплаченной и уходят. Либо покупателям что-то непонятно, или для завершения покупки необходимо подтвердить возраст покупателя, а помощника нет на острове самообслуживания, покупатели не дожидаются. Еще есть события «Эти ошибки исправлены» (28,89%). Доля событий «Пропустить товар с неправильным весом» составляет 16,82% — существенное значение, но рассмотрим пример из другого магазина.

52c533d8b198d2d11ee5e33f0dfc3a94.png

Здесь, например, пропуск товаров с неправильным весом составляет 27,44% — то есть помощник намного чаще игнорирует расхождение между весом в базе и на КВП. В идеале такое должно происходить в основном в случае надпитых в торговом зале бутылок с водой и товаров с переменным весом (яйца, выпечка, фрукты). Вывод: в этом магазине необходимо провести переобучение по весам товаров, потому что помощники не только сохранили некорректный вес по товару, но и постоянно пропускают эту ошибку, не исправляя ее.

Обычно для сравнения показателей используем полную календарную неделю без праздников, но для понимания динамики после внесения обновлений (например, переобучение по товарам) достаточно и нескольких дней.

Настройки контрольно-весовой службы устроены так, что товары с легким весом должны быть заведены отдельным списком. Это сделано в силу технических ограничений работы КВП, она не может измерять точный вес товаров менее 5 грамм. Поэтому, например, когда на график проблемных товаров попадает п/э пакет или упаковка специй, мы понимаем, что работа с легковесными товарами у клиента не до конца отлажена и это будет дополнительной причиной интервенций помощника. Легковесные товары не должны попадать в категорию проблемных, подобный мониторинг позволяет такие ситуации быстро выявлять и выдавать клиенту рекомендации по корректировке настроек. 

Шаг 4. Делаем выводы — и сокращаем количество интервенций 

Главное, что мы получаем на выходе — мы можем точно и оперативно выявить для ритейлера причину сбоев в работе КВП. Локализуем проблему. Понимаем, где человеческий фактор, где сложности с конкретным товаром. 

Если с товаром — делаем для него индивидуальную настройку (отличную от общей массы настроек), ждем, потом снова снимаем статистику. В результате такого переобучения КВП и переобучения помощников правильной реакции количество интервенций сокращается до минимума. 

На примере работы кассы самообслуживания мы показали только один кейс использования, а в целом ELK используется в нашей компании как средство сбора статистической информации о поведении касс, скорости выполнения операций, количестве незапланированных зависаний и других важных для наших клиентов нефункциональных свойствах кассы. Если будет интересно, мы расскажем об этом подробней в следующих статьях. 

Желаем всем только приятных и быстрых покупок! Если возникли вопросы, пишите. 

One more thing…

P.S. Пока мы готовили материал для этой статьи, опыт нашей команды поддержали другие продуктовые направления команды CSI, ведь практически в каждом продукте есть, что измерять и улучшать с помощью статистического анализа. 

Ниже — примеры от ребят из кассового направления, где с помощью описанного подхода происходит измерение ключевых для каждого ритейлера метрик работы кассы.

  • скорость добавления просканированных товаров

  • скорость авторизации покупателей при использовании дисконтной карты или вводе номера телефона

  • скорость расчета скидок

85b966f0ca3db0c6086791bbb97ccea0.png58ba0601dc552949371e02f177c909a3.png

Планируем и дальше развивать этот инструмент для получения важной информации о работе наших решений.

© Habrahabr.ru