Начну с краткого интро. Мы зарабатываем тем, что проводим промо-акции для производителей и продавцов разнообразных потребительских товаров. Как правило, это что-то из разряда «купи товар – найди код – отправь его нам – выиграй приз». Основной наш продукт — это платформа, которая эти коды генерирует, принимает, обрабатывает, помогает коммуницировать с участниками, выплачивает бонусы и делает еще много чего интересного.
В последнее время мы стали все чаще видеть акции от коллег по цеху, где подтверждением покупки служил не промо-код, как в примере выше, а фото чека. Причем теперь явление становилось массовым. Оставаться в стороне было непозволительно.
Первым делом я зарегистрировался во всех акциях с чеками, о которых узнал (ну если честно не во всех, где-то в районе второго десятка мне надоело). Чеков у меня, как вы догадываетесь, не было и я решил вместо чека использовать фото котика на абстрактном фоне. Каково же было мое удивление, когда во всех акциях, кроме одной, моего котика приняли и допустили меня до розыгрыша призов. А кое-где даже выдали моментальный приз в виде промо-кода в онлайн-библиотеку. Честно говоря, в той одной акции котика тоже приняли, но обещали направить его на модерацию и в течение 8 (!) часов решить вопрос о моём участии в акции.
Такой вариант нам явно не подходил. Во-первых, допускать человека до розыгрыша по любому фото не хорошо. Он может сколько позволит платформа раз загрузить фото одного и того же чека, тем самым многократно повысив свои шансы на получение выигрыша. Когда одна из этих заявок выигрывает, предъявляется оригинал того самого единственного чека и забирается приз. Конечно, есть шанс выиграть дважды и выдать себя, но это мы уже увлеклись. Во-вторых, 8 часов не давать человеку обратной связи выглядит издевательски в мире, где посетитель, проведший на сайте более 15 секунд, считается целевым. В-третьих, давать приз за фото котика означает показать себя не очень компетентным организатором. Кстати, вот он.
Вывод напрашивался сам собой: нам нужно научиться распознавать чеки. Задача сложная, потому пошли к профессионалам – одной известной компании. У них по счастью оказалось решение для распознавания чеков, по несчастью не локализованное на российском рынке. В честь этого нам дали 1000 бесплатных попыток распознать чек, обещание помочь советом и пожелали удачи.
К тому моменту появился запрос от клиента. Перед нами стояла задача провести акцию для крупной сети розничных магазинов. Забегая вперед, скажу, что принимали до 1000 регистраций в день. Чтобы претендовать на призы в акции вам нужно было в определенный промежуток времени купить чего-нибудь на сумму от N руб. и обязательно оплатить покупку картой VISA. Фото полученного при покупке слипа следовало загрузить к нам на промо-сайт. Если вы признавались победителем, вы должны были предъявить слип и карту VISA на кассе и забрать приз. Одно фото – один шанс на победу. Победитель вычисляется среди всех участников, загрузивших корректные слипы, по специальной формуле. Наша задача на данном этапе: принять слип и допустить/не допустить человека до участия в розыгрыше. При этом желательно по максимуму отсечь хитрецов, которые могут пытаться подсунуть нам один слип дважды, подсунуть слип, напечатанный до начала акции и еще много всего интересного включая, но не ограничиваясь фото котика.
Многократное тестирование продукта крупной компании показало, что он определяет сумму покупки, тип карты, номер карты, время и дату печати слипа. И вроде вот оно: дубликаты отметаем (для этого вычисляя хеши распознанных параметров и самой картинки), сумму, дату, платежную систему и номер карты распознаем. Правда, распознается с ошибками… и не все.
Напомню, при выдаче приза у победителя проверялась сумма слипа и карта, точнее последние 4 цифры номера карты. Данные сверялись с реестром, который по итогам розыгрыша автоматически отправлялся в магазин нашей системой. То есть, эти данные просто обязаны быть корректными.
Нам пришлось пойти на первый компромисс: просим участника руками ввести сумму покупки и последние 4 цифры номера карты. Далее если то, что ввел человек и то, что распознала машина, совпало, а платежная система и дата печати слипа корректны, допускаем участника к розыгрышу.
Посчитали, оказалось, что допускаем мы только 71% слипов. Остальные 29% это некорректные либо некачественные изображения и корректные, но некорректно распознанные изображения в примерном соотношении 50/50.
Как быть с этими 14,5% чеков, отклоненных ошибочно? Решение пришло довольно быстро, стали отправлять на ручной аппрув в дружественный контакт-центр. Из минусов: дорого и долго. Если 71% счастливчиков получали результат в течение минуты, то этим людям пришлось сообщать об ожидании до 8 часов. Было решено попытаться нормализовать результаты распознавания в нашей системе.
Включаем аналитику: вручную сверяем данные на фото и результат распознавания. Результат распознавания прилетает следующим образом: отдельно поля «дата», «сумма» и т.д. и отдельно полный текст, то есть вообще все что было найдено на изображении. Зачастую данные, не содержащиеся в одном из первых полей, можно было отыскать в полном тексте глазами. По итогу анализа нескольких сотен слипов решили делать следующее:
1) Отличаем чек от слипа: среди всех принятых слипов ищем слип с максимальным количеством строк. Для любого отклоненного (по любой причине) документа считаем количество строк, если оно превышает рассчитанный ранее максимум, говорим человеку «Возможно, вы пытаетесь загрузить чек, а не слип. Сфотографируйте слип отдельно от чека и повторите попытку». Таким образом человек лучше понимал, что не так с его фото.
2) Если не распознана дата: пробуем искать в полном тексте фрагмент по маске «ХХ/ХХ/ХУ», где Х-любое число, а У – любой символ. При нахождении фрагмента У менять на 6 (или 7 в зависимости от года проверки), найденный фрагмент считать датой печати слипа. Да-да, косячила система в основном на последней цифре даты. Выиграли 2%.
3) Если не распознана сумма: искать в полном тексте по маске «ZХХХХ.ХХ RU», где Х-любое число, а Z – любой символ в том числе пробел или отсутствие символа. Найденный фрагмент сравнить с тем, что ввел участник. При расхождении поочередно заменить все символы 6 на 8 в найденном фрагменте и сравнить с тем что ввели. Почему-то машина часто путала именно 6 и 8, причем не 8 и 6, а именно 6 и 8. Выигрыш порядка 3%.
4) Номер карты: искать в полном тексте по маске «** XXXX», где Х-любое число. Между символами Х могут стоять пробелы либо знаки препинания, их отбрасываем. Полученное число сравниваем с введенным вручную номером карты. + 1%.
5) Карта оплаты: искать в полном тексте один из фрагментов: «Карта:V», «Карта: V», «Карта’V», «VISH». При нахождении считать карту картой VISA. + 3%.
Таким образом, мы довели количество принимаемых в течение одной минуты заявок до 80%. Увы, на этом возможности нормализации были практически исчерпаны, и мы переключились на повышение эффективности ручного распознавания (но это уже другая история).
В общем и целом, у нас получилась, насколько мне известно, первая в стране акция с реальным машинным распознаванием чеков. Результат для первого раза мне кажется неплохой, а к лету наш партнер обещал заметно повысить качество распознания, официально представив русскую версию своего сервиса.
Комментарии (22)
alexmay
07.02.2017 22:53+4Хм… а статья -то о чем?
О том, что вы научились данные из одного ПО обрабатывать в другом, следуя набору правил?
KivApple
08.02.2017 07:56Лично мне вариант с кодом нравится куда больше чека. Ибо чеки имеют свойство выцветать, теряться, рваться и т. д. Плюс сделать нормальное четкое фото будет не такой простой задачей для владельцев бюджетных смартфонов.
DR17
08.02.2017 09:301) «пошли к профессионалам – одной известной компании» А название раскроете?
2) Как бороться с подделками? Можно самому печатать такие слипы и получать бонусы. Или гелевой ручкой исправлять 6 до 8 или 0 до 8 или 5 до 6 итд.
3) Данная точность для вас приемлема? Почему?Pavel_SD
08.02.2017 10:16+11) Жду от них разрешения.
2) Это нельзя на 100% исключить. Но с таким слипом вам не выдадут приз. К тому же мы ежедневно вручную проверяли некоторое количество слипов, отслеживали подозрительную активность участников. А подделка слипов это уже, думается мне, уголовно наказуемое деяние.
Вообще существуют целые сообщества так называемых призоловов и борьба с ними тема отдельной статьи). Некоторые действуют профессионально. Например, в одной из акций с уникальными кодами (вместо чеков) из типографии клиента похитили бобины с этикетками (мы так думаем) и устроили нам атаку с пула в несколько сотен очень похожих друг на друга номеров. Причем попытки блокировать по номера маске приводили к тому, что страдали рядовые участники.
3) Потому что мы сделали максимум того что могли и не знаем иных способов с более высокой точностью. К тому же есть подстраховка в виде ручного распознавания.
EnigMan
08.02.2017 09:39+4К лету кое что здорово изменится. Все продавцы должны будут перейти на применение online кассовых аппаратов. На чеках будет QR код с основными его параметрами, в т.ч. сумой и уникальным номером.
oops1
08.02.2017 10:09А не проще/дешевле было воспользоватся сервисами распознавания
такие уже есть но заточены под капчу
первый попавший в гугле сервис распознавания капчи
7 — 9 секунд на распознавание 18 руб за 1000 капчPavel_SD
08.02.2017 10:24+1Не вижу, чем это лучше заточенного под чеки (пусть и не русские пока) OCR-сервиса которым мы пользовались.
С ними во-первых нужно договориться чтобы они принимали не каптчу размером одна строка, а некий документ. К тому же документ структурированный и результат тоже должен быть структурирован.
Если они используют ручное распознавание (что довольно распространено у них), то где гарантия что распознавать будет человек который разберет язык и поймем в каком месте какой параметр указан.oops1
08.02.2017 10:27хорошо. можно пойти другим путем, если уж так хочется приложить ручки
OpenCV замечательно отмечает блоки текста без распознавания, выдергиваете строки и скармливаете как капчу, в сумме по времени уложитесь в минуту
я так понимаю есть и русские сервисы, которые принимают русскую капчуPavel_SD
08.02.2017 10:42+1Придется решить пару вопросов:
1) В разных магазинах могут выдаваться разные слипы, в зависимости от оборудования, которое может меняться прямо по ходу акции, то есть знать где именно напечатана дата наверняка нельзя.
2) В спорных ситуациях нас здорово выручал полный текст документа, который прилетает вместе с основными параметрами, тут на него опираться не получится.
3) Иногда нам скидывали фото чека вместо слипа, не очень понятно как его обрабатывать учитывая коммент 1.
В общем, как альтернативу на следующие мероприятия этот вариант можно рассматривать. Даже интересно, какую результативность покажет.
BalinTomsk
08.02.2017 20:16На самом деле хочется иметь черную коробочку возле входной двери, имющую щелку для чека, чек всосется, отсканируется и скрутится на барабан с другими чеками.
Раз в месяц катушка с чеками снимается и кладется в пакетик на хранение.
изображение складывается на флешку с папками по месяцам и по тематике, копия автоматом в облако или на домашний ftp.
100 баксов бы отдал за готовое устройство. Ходить к сканеру или расправлять чек что снять телефоном нет желания.
klev
Тема очень интересная.
А можно узнать, какие технологии, сервисы или библиотеки были использованы?
Pavel_SD
С одной стороны наша платформа, не уверен, будет ли рекламой если я тут укажу ее название.
Сама платформа в основном самописаная, содержит очень мало заимствований и сторонних компонентов. Вся логика и БД на стороне платформы. В качестве средств ввода-вывода в данной акции подключались промо-сайт на самописной CMS и контакт-центр для «горячей линии». Еще использовался SMS-шлюз, тоже собственный, он подключается к крупным провайдерам, а те же уже напрямую к операторам.
В других акциях к ним могут добавляться мобильные приложения, платежный шлюз, социальные сети и мессенджеры.
С другой стороны использовался один из популярных OCR-сервисов, жду от них ответа, можно ли тут написать название.
vitalets
Спасибо за статью!
Да, было бы интересно узнать название OCR-сервиса!
Pavel_SD
ABBYY Cloud OCR SDK http://ocrsdk.com/
vitalets
Спасибо!