Введение
Здесь должен быть текст из серии «вы же знаете, как для любой компании важно оценивать качество обслуживания — это основа развития». На мой взгляд, это вполне банальные истины, поэтому опустим их.
Сохраняем карму, недорого
Сервис Heedbook, о котором я расскажу сегодня, обладает одним очень крутым преимуществом перед другими способами оценки работы сотрудников с клиентами — это автоматическая оценка эмоций клиента в режиме реально времени. То есть, возвращаясь к моему другу, его толерантность не спасёт консультанта от реальной оценки работы. И волки сыты, и овцы целы, и карма друга тоже.
Как это работает:
1. Сотрудник фронт-линии банка (или аптеки, или МФЦ, или магазина, или тому подобных предприятий) в начале рабочего дня входит в систему через браузер.
2. К нему приходит клиент, например, мой друг.
3. Система получает и анализирует видеопоток с веб-камеры в режиме реального времени в фоновом режиме.
4. Информация обрабатывается системами интеллектуального распознания эмоций, речи и других параметров клиента.
5. По результатам анализа система предоставляет детальную аналитику по структуре эмоций и доле положительных/отрицательных эмоций клиента, вниманию клиента к сотруднику, содержание диалога, использование скрипта обслуживание или запрещенных фраз.
6. Руководитель офиса и сотрудники головной компании получают в детальную информацию о качестве клиентского сервиса в разрезе менеджеров и клиентов. (И тут мы видим, как наш консультант начинает нервничать. ))
Помимо описанного выше, для каждого сотрудника определяется среднее время обслуживания клиентов, количество обслуженных клиентов, структуру клиентской базы по демографическим показателям.
Ещё одна интересная фишка, директор может подключиться к видео-стриму от рабочих мест сотрудников фронт-линии, а также просматривать видео-записи диалогов позже с детальной аналитикой по ним. То есть в нашу историю добавляется новый сценарий, когда консультант начинает хамить моему другу, а потом внезапно у него округляются глаза и он становится милым и вежливым. )
Ну и последняя интересная деталь, в Heedbook есть рейтинговая система для сотрудников.
Как это работает: глазами разработчика
Микросервисная архитектура Azure Functions
Мы вместе с Димой Сошниковым частично помогали ребятам в проектировании решения. Первое, что сделали — решили уйти от монолитной архитектуры и сделать систему построенную на микросервисах (как вы могли заметить по моим последним статьям, на мой взгляд это очень интересная тема). Для этого использовали Azure Functions. На самом деле мы также думали про WebJob, но у него есть ограничения по производительности и ценообразование идёт не от количества совершенных операций.
Основная среда разработки AF — онлайн редактор функций на портале Azure. Также с конца мая 2017 можно создавать AF с помощью Visual Studio 2017 UPD 3.
Так как AF — новый продукт Microsoft, по нему пока нет полной документации, поэтому ниже разберем пример одной AF проекта Heedbook. Это позволит сэкономить время, если вы решите построить микросервисную архитектуру на базе Azure.
Триггером запуска AF может стать Http запрос, появление Blob в Azure Blob storage, действия в OneDrive или просто таймер. В проекте реализованы практически все представленные выше варианты триггеры для AF. Также мы реализовали каскады AF, когда работа одной AF запускает другую, таким образом обеспечивая единый бизнес процесс анализа данных.
Пример нашей AF триггерится появлением блоба — картинки. При помощи данной AF мы с вами определим количество людей на картинке и их эмоции. Сделаем это с помощью когнитивного сервиса Microsoft Face API.
Сначала необходимо подключить необходимые библиотеки когнитивных сервисов. Для онлайн редактора AF сделать это придётся вручную, создав файл project.json и прописав туда все необходимые зависимости:
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.ProjectOxford.Common": "1.0.324",
"Microsoft.ProjectOxford.Face": "1.2.5"
}
}
}
}
В случае с созданием AF в Visual Studio 2017 UPD 3 просто подключаем необходимые зависимости с помощью Nuget.
Дальше нам нужно прописать триггер AF и выходные параметры. В нашем случае — это появление блоба в определенном контейнере и запись результатов распознания в таблицу Azure MsSql. Делается это в файле function.json:
{
"bindings": [
{
"name": "InputFace",
"type": "blobTrigger",
"direction": "in",
"path": "frames/{name}",
"connection": "heedbookhackfest_STORAGE"
},
{
"type": "apiHubTable",
"name": "FaceData",
"dataSetName": "default",
"tableName": "FaceEmotionGuid",
"connection": "sql_SQL",
"direction": "out"
}
],
"disabled": false
}
Итак, сам код Azure Functions!
#r "System.IO"
using System.IO;
using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Common.Contract;
public static async Task Run(Stream InputFace, string name, IAsyncCollector<FaceEmotion> FaceData, TraceWriter log)
{
log.Info($"Processing face {name}");
var namea = Path.GetFileNameWithoutExtension(name).Split('-');
var cli = new FaceServiceClient(<Face_Api_Key>);
var res = await cli.DetectAsync(InputFace,false,false,new FaceAttributeType[] { FaceAttributeType.Age, FaceAttributeType.Emotion, FaceAttributeType.Gender});
var fc = (from f in res
orderby f.FaceRectangle.Width
select f).FirstOrDefault();
if (fc!=null)
{
var R = new FaceEmotion();
R.Time = DateTime.ParseExact(namea[1],"yyyyMMddHHmmss",System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat);
R.DialogId = int.Parse(namea[0]);
var t = GetMainEmotion(fc.FaceAttributes.Emotion);
R.EmotionType = t.Item1;
R.FaceEmotionGuidId = Guid.NewGuid();
R.EmotionValue = (int)(100*t.Item2);
R.Sex = fc.FaceAttributes.Gender.ToLower().StartsWith("m");
R.Age = (int)fc.FaceAttributes.Age;
await FaceData.AddAsync(R);
log.Info($" - recorded face, age={fc.FaceAttributes.Age}, emotion={R.EmotionType}");
}
else log.Info(" - no faces found");
}
public static Tuple<string,float> GetMainEmotion(EmotionScores s)
{
float m = 0;
string e = "";
foreach (var p in s.GetType().GetProperties())
{
if ((float)p.GetValue(s)>m)
{
m = (float)p.GetValue(s);
e = p.Name;
}
}
return new Tuple<string,float>(e,m);
}
public class FaceEmotion
{
public Guid FaceEmotionGuidId { get; set; }
public DateTime Time { get; set; }
public string EmotionType { get; set; }
public float EmotionValue { get; set; }
public int DialogId { get; set; }
public bool Sex { get; set; }
public int Age { get; set; }
}
В данном случае это асинхронная процедура в связке с Cognitive Services Face API. AF получает Stream блоба и передает его в CS:
var res = await cli.DetectAsync(InputFace,false,false,new FaceAttributeType[] { FaceAttributeType.Age, FaceAttributeType.Emotion, FaceAttributeType.Gender});
Далее выбирает самое крупное лицо в кадре:
var fc = (from f in res
orderby f.FaceRectangle.Width
select f).FirstOrDefault();
И записывает результаты распознания в базу данных:
await FaceData.AddAsync(R);
Всё просто, не правда ли? Будущее за микросервисами. )
О проблемах
Ладно, не всё так просто, на самом деле.
AF, к сожалению, на текущий момент имеет ряд ограничений (не работает биндинг имен, есть конфликты библиотек). К счастью, в мире разработки на .Net всегда есть множество walkarround — и если у вас не получается решить проблему по базовому сценарию, можно найти несколько обходных вариантов.
Съемка видео и аудио в фоновом режиме
Как известно, современные ОС стараются максимально экономить ресурс батареи, прекращая проактивную работу всех приложений, находящихся в фоновом режиме. Это касается и стрима в веб-, мобильном или десктопном приложением. Проведя длительную изыскательскую работу по данному поводу. мы сделали выбор в пользу веб-решения.
Видео- и аудиопоток от веб-камеры получаем с помощью
GetUserMedia()
. Далее мы должны записать полученный видео- и аудиопоток и извлекать оттуда данные для передачи на бэкенд. Это работает, если окно браузера будет постоянно активным, как только вы делаете закладку браузера неактивной — становится недоступным для записи данных. Наша задача была сделать систему, которая будет работать в фоновом режиме и не будет мешать сотруднику осуществлять свои прямые обязанности. Поэтому решением стало создание собственной стримовой переменной, куда мы записываем и извлекаем данные видео- и аудиопотока. Качество распознания русского языка
В будущем сервис будет двигаться к созданию своих собственных моделей распознания аудио, но на текущий момент приходится использовать внешних провайдеров услуг распознавания русского языка. Было сложно выбрать хороший сервис, обеспечивающий качественное распознание речи на русском. Текущая конфигурация системы использует комбинацию систем распознания речи, для русской речи используется Goolge Speech Api, в тестировании показавший лучшие результаты качества распознания.
Возвращаемся в реальность
На самом деле это решение — не просто сказки о будущем. В ближайшее время Heedbook начнёт работать в подмосковных МФЦ и крупнейшем банке страны.
Команда Heedbook будет признательна за комментарии по поводу их решения, а также будет рада сотрудничеству с профессионалами в области ML, анализа данных, SEO и работе с крупными клиентами. Пишите свои мысли в комментариях или на почту info@heedbook.com.
Комментарии (42)
4ebriking
19.06.2017 22:04+5Вот когда несколько поколений подряд у части мужского населения одной отдельно взятой страны — такая вот «распознавалка эмоций» минуя мозг напрямую соединена с пистолетом — появляется нация «вечно улыбающихся».
Зря вы это затеяли, ох зря…
kolipass
20.06.2017 06:34Интересно, вы же используете эмоции из Oxford Emotion Api? Rак вы из 7-8 значений эмоций на кадр делаете какие-то выводы? Есть публикации подробнее?
MaslovAlexey
20.06.2017 08:48Да, Emotions Api в том числе, выбираем основную эмоцию, полученную с достоверностью более 60%, складываем все это в эмоциональную карту диалога, но это только одна из функций сервиса. Их очень много. Подробнее пока можно почитать только на сайте, буклет продукта и промо-ролик пока ещё не готовы
kolipass
20.06.2017 13:08Ну вот получена эмоция грусти 61% и 30% безразличия. Это как трактуется? Как обобщается и фильтруется?Emotions Api не даёт никакой информации о национальности и психотипе, без этой информации ничего сказать нельзя.
Мой домашний проект делает примерно тоже самое, что и ваш но для другой предметной области, от этого детальный интерес. Если есть возможность пообщаться поглубже — было бы интересноMaslovAlexey
20.06.2017 13:22Думаю, на часть вопросов есть ответы ниже в комментариях. В части сотрудничества — мы будем только рады. Присылайте свой контакты на info@heedbook.com, переговорим!
immaculate
20.06.2017 07:51Люди всегда находят способ обмануть простые метрики. «Карма» на хабре/gt, репутация на StackOverflow — есть масса людей на этих сервисах с незаслуженно высокой репутацией. На StackOverflow можно кидаться на самые простые вопросы и агрессивно давить на автора вопроса в комментариях, чтобы ответ принимали как решение. Рекрутеры, использующие SO для поиска кандидатов, вряд ли вчитываются в ответы и способны их понять, им важно только абсолютное значение репутации.
Для того, чтобы в комментариях на Habrahabr/Geektimes собрать максимум плюсов, достаточно максимально жестко раскритиковать Россию. Любой положительный комментарий о жизни в стране приводит к минусам, любой отрицательный, к плюсам. Чем жестче поливаешь грязью свою страну и сограждан, тем больше ставят плюсов.
И систему из поста ловкие личности тоже быстро научатся обходить.
frees2
20.06.2017 09:28+2раскритиковать Россию
Критика власти, будь то Путина или Порошенко, не есть критика страны.
Политота, националисты, религиозные и родноверные психи, сео-накрутчики, диванные солдатики, скептики потепления, даже товарищи с Рен-тв.
Вся эта мелкая нечисть безобидна в принципе.
Другое дело — качество материалов, когда берут вопросы с Тостера, и переправляют сюда, вроде XML базы данных…
Их надо гнать в жопу, ибо засрут как жежечку.
D_Lowl
20.06.2017 09:37Не уловил как ложные срабатывания отсекаются. Вот скажем пришел я изначально с плохим настроением (день не задался) -> мое настроение не связано с действиями кассира.
MaslovAlexey
20.06.2017 09:52К сожалению, любая оценка качества носит субъективный характеристик. При телефонных опросах, sms и прочих системах оценки удовлетворенности есть несоотвестствующие реальному обслуживанию результаты. В колл-центрах для этого прослушивают диалоги, если клиент неадекватен, принимают решение не учитывать оценку. Здесь аналогичная ситуация, можно посмотреть запись диалога с детальной аналитикой по нему
Schvepsss
20.06.2017 09:56То есть придётся всех вручную просматривать?
MaslovAlexey
20.06.2017 10:02только всплески, все просматривать не нужно. Как говорится, для работы над ошибками и сбора лучших практик
Schvepsss
20.06.2017 09:55+1, тоже сразу возник такой вопрос. Может какая-то погрешность учитывается или формируется «профиль» человека — «тип с вечно недовольным лицом». :)
MaslovAlexey
20.06.2017 10:03Мы считаем только эмоции, в которых уверены на 60 и более процентов, остальные отбрасываем
MaslovAlexey
20.06.2017 10:04А что касается вечно недовольных лиц — тут вы праву, эмоциональная карта диалога в России и Италии, к примеру будет сильно отличаться. Это вопрос к устанавливаемым Kpi. Мы сейчас как раз над этим работаем
Schvepsss
20.06.2017 10:07Кстати, было бы интересно почитать про эмоциональные карты в разных странах. Вы будете делать своё исследование или на основе уже известных?
MaslovAlexey
20.06.2017 10:19Как сложится клиентская работа с зарубежными компаниями, конечно, хотелось бы не только разработку вести данного сервиса, но осуществлять консалтинг в этой сфере. Будем стремиться к этому
hdkr
20.06.2017 09:40Недавно решил в Watch Dogs 2 поиграть. Сбор и запись всех данных о пользователе без его ведома. Что-то мне это напоминает.
А есть ли шанс у клиента обратиться к компанию не попав под пристальный взгляд машины записывающей его эмоции, видео и голос? Не думали ли Вы что это может быть МИНУСОМ и мешать коммуникации как клиента так и оператора.stasus
20.06.2017 09:45+1Насколько я знаю, о записи должны предупреждать. Если не устраивает, можно обратиться в другое место. Но обычно, скорее предпочитают с камерой, так как это гарантирует некоторый уровень обслуживания, не из-за записи как таковой, а просто из-за самого факта наличия камеры.
Сейчас и так пишут везде, ТЦ, улицы, автодороги, банки, офисы. Так почему бы не получить от этого дополнительную выгоду?
hdkr
20.06.2017 10:13+1"… о записи должны предупреждать. Если не устраивает, можно обратиться в другое место…… Сейчас и так пишут везде, ТЦ, улицы, автодороги, банки, офисы..."
В этом и проблема не нравится ищи что-то другое, но пишут везде. Предупреждают НЕ равно спрашивают разрешения.
Мне например не особо это нравится и у меня не спрашивали разрешения хочу я чтобы записывали меня на видео, аудио и составляли шаблоны реакций на те или иные слова как я реагирую. Это из разряда сильно навязчивого сервиса. Так же как есть сильно навязчивый маркетинг. Это бесит.Schvepsss
20.06.2017 10:27-1По-моему это из разряда паранойи, а не сильно навязчивого маркетинга. В конце концов, всегда можно надеть на голову шапочку из фольги и уехать подальше от человеков и этой вашей техники.
murzilka
20.06.2017 10:49А если на клиентском месте о оператора банально неудобный стул, или дует из кондиционера, или пахнет из мусорного ведра, или ещё что-то, что будет неудобно, неприятно большинству клиентов, оператор будет получать стабильно низкие оценки?
А если во время беседы клиенту позвонили и сообщили о смерти любимого хомячка, система зарегистрирует слёзы и рыдания как низкую оценку оператору?frees2
20.06.2017 11:00Достаточно связать эмоциональную реакцию с монологами ( предложениями) продавца-покупателя.
Голосовая реплика -> реакция.
Эмоциональная реплика продавца ( типо улыбка, как определённая от души...) -> реакция.
Записывать надо и продавца и покупателя.
Теперь точно верю в ботов продавцов…
copal
20.06.2017 11:47А разве уже существуют речевые синтезаторы, которые не отличимы от живых людей?
frees2
20.06.2017 13:46IBM вот в хабрахабр кинул ссылки на синтезаторы. Качество синтеза не ахти, бот чувствуется, но вот там можно в текст эмоции вставлять. Управлять эмоциональностью текста.
Фейсбук работает над ботом продавцом, правда текстовым.
murzilka
20.06.2017 11:53+1Вот и первый лайфхак для это системы: сказать "улыбнитесь, пожалуйста". А дальше можно и нахамить :)
dmandreev
21.06.2017 11:09Можно уточнить, как видео с вебкамеры попадает в Cognitive Services для распознавания эмоций? В статье речь идет о картинках, не совсем очевидно.
stasus
21.06.2017 11:13В PoC который мы делали вместе (как сейчас, уже не знаю), видео резалось на последовательные картинки, которые клались в BLOB и на это событие срабатывала Azure Function, которая дёргала когнитивные сервисы с этой картинкой.
dmandreev
21.06.2017 12:59Было бы интересно узнать как сейчас. По тому подходу который описан получается что обработка часа видео 25 кс будет стоить $90 только на Cognitive Services.
stasus
21.06.2017 13:33MaslovAlexey, подскажешь, как сейчас у вас сделано?
MaslovAlexey
21.06.2017 13:46Если говорить про распознание лиц — то мы берём фрэймы с каждые несколько секунд, все кадры не имеет смысла распознавать, это действительно дорого
dmandreev
21.06.2017 22:04Если вы берете фреймы только через несколько секунд, то ни о каких замерах эмоционального состояния нельзя вести речь. Эмоции людей мимолетны. Это буквально миллисекунды. У вас будет один neutral в ваших отчетах.
MaslovAlexey
21.06.2017 22:15Вы неправы, от того берём ли мы все фрэймы или выборочно не зависит доля neural эмоций.
dmandreev
21.06.2017 22:38+1Допустим я не прав. Но вы как правы то? У меня вот есть датасет из крупнейшего банка страны в размере 4 гигабайт, два гига датасетов где геймеры шапки надевают и им меряют энцефалограммы. Ради смеха еще вот такое видео сделал https://www.youtube.com/watch?v=nrqVXt5TeAw и это все мне доказывает что эмоции людей мерять надо в масштабах секунд. Если вы выхватите кадр из часового видео через 2-3-4 секунды — там будет недействительная информация. Потому что люди не могут улыбаться минутами. Они даже три секунды улыбаются редко.
MaslovAlexey
22.06.2017 08:25+1Конечно, если брать 24 фрэйма в секунду вы уловить все оттенки эмоций, но этого и не надо для изменения удовлетворенности, это, возможно потребуется для понимания врёт ли человек или анализа психо-эмоционального состояния.
MaslovAlexey
22.06.2017 08:33+1То, о чем вы пишите — это микровыражения. Пока мы их не стремимся поймать, в будущем, возможно будем и их анализировать. Спасибо за предложение
Olgashipa
21.06.2017 15:34+1Интересно, а если человек придет недовольный? Или придет с нейтральным выражением лица, но уже на взводе? У нас нередка ситуация, когда люди приходят в мфц заранее обиженные )
MaslovAlexey
21.06.2017 16:00Оценка качества сервиса всегда имеет субъективный оттенок, как бы этот показатель не измеряли. В данном случае компания получает оценку 100% визитов клиентов, в отличие от классических систем оценки качества. Поэтому такие всплески легче отловить и исключить из статистики
frees2
У кармы с некого порога единицей измерения должно выступать значение логарифма переменной.
Притом зависеть от кармы того кто минусует или плюсует, чем больше минусует или плюсует тем пропорционально ( с коэффициентом возможным) хуже карма — Обратная связь кармы.
Ибо по другому критичных комментариев в хабрахабре не будет.