Недавно мы поспорили с одним из моих друзей о том, стоит ли оставлять негативные отзывы и отрицательно оценивать чью-то работу. Например, приходишь в банк, а там тебе нахамил консультант. Я убеждён, что стоит, потому что без этой оценки человек будет продолжать хамить. Друг считает, что это большой минус в твою карму, нельзя же обижать людей, они сами всё поймут со временем. Примерно в то же время у нас прошёл хакфест для партнёров, на котором я увидел решение, способное сохранить карму каждого из нас. Грех таким не поделиться. Как вы уже догадались из названия, под катом речь пойдёт о разработке на основе когнитивных сервисов.



Введение


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

Сохраняем карму, недорого


Сервис 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)


  1. frees2
    19.06.2017 19:41

    Я убеждён, что стоит, потому что без этой оценки человек будет продолжать хамить.

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

    Ибо по другому критичных комментариев в хабрахабре не будет.


  1. 4ebriking
    19.06.2017 22:04
    +5

    Вот когда несколько поколений подряд у части мужского населения одной отдельно взятой страны — такая вот «распознавалка эмоций» минуя мозг напрямую соединена с пистолетом — появляется нация «вечно улыбающихся».

    Зря вы это затеяли, ох зря…


  1. kolipass
    20.06.2017 06:34

    Интересно, вы же используете эмоции из Oxford Emotion Api? Rак вы из 7-8 значений эмоций на кадр делаете какие-то выводы? Есть публикации подробнее?


    1. MaslovAlexey
      20.06.2017 08:48

      Да, Emotions Api в том числе, выбираем основную эмоцию, полученную с достоверностью более 60%, складываем все это в эмоциональную карту диалога, но это только одна из функций сервиса. Их очень много. Подробнее пока можно почитать только на сайте, буклет продукта и промо-ролик пока ещё не готовы


      1. kolipass
        20.06.2017 13:08

        Ну вот получена эмоция грусти 61% и 30% безразличия. Это как трактуется? Как обобщается и фильтруется?Emotions Api не даёт никакой информации о национальности и психотипе, без этой информации ничего сказать нельзя.
        Мой домашний проект делает примерно тоже самое, что и ваш но для другой предметной области, от этого детальный интерес. Если есть возможность пообщаться поглубже — было бы интересно


        1. MaslovAlexey
          20.06.2017 13:22

          Думаю, на часть вопросов есть ответы ниже в комментариях. В части сотрудничества — мы будем только рады. Присылайте свой контакты на info@heedbook.com, переговорим!


  1. immaculate
    20.06.2017 07:51

    Люди всегда находят способ обмануть простые метрики. «Карма» на хабре/gt, репутация на StackOverflow — есть масса людей на этих сервисах с незаслуженно высокой репутацией. На StackOverflow можно кидаться на самые простые вопросы и агрессивно давить на автора вопроса в комментариях, чтобы ответ принимали как решение. Рекрутеры, использующие SO для поиска кандидатов, вряд ли вчитываются в ответы и способны их понять, им важно только абсолютное значение репутации.


    Для того, чтобы в комментариях на Habrahabr/Geektimes собрать максимум плюсов, достаточно максимально жестко раскритиковать Россию. Любой положительный комментарий о жизни в стране приводит к минусам, любой отрицательный, к плюсам. Чем жестче поливаешь грязью свою страну и сограждан, тем больше ставят плюсов.


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


    1. frees2
      20.06.2017 09:28
      +2

      раскритиковать Россию

      Критика власти, будь то Путина или Порошенко, не есть критика страны.

      Политота, националисты, религиозные и родноверные психи, сео-накрутчики, диванные солдатики, скептики потепления, даже товарищи с Рен-тв.
      Вся эта мелкая нечисть безобидна в принципе.

      Другое дело — качество материалов, когда берут вопросы с Тостера, и переправляют сюда, вроде XML базы данных…
      Их надо гнать в жопу, ибо засрут как жежечку.


  1. D_Lowl
    20.06.2017 09:37

    Не уловил как ложные срабатывания отсекаются. Вот скажем пришел я изначально с плохим настроением (день не задался) -> мое настроение не связано с действиями кассира.


    1. MaslovAlexey
      20.06.2017 09:52

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


      1. Schvepsss
        20.06.2017 09:56

        То есть придётся всех вручную просматривать?


        1. MaslovAlexey
          20.06.2017 10:02

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


          1. Schvepsss
            20.06.2017 10:05

            Это отлично. :)


    1. Schvepsss
      20.06.2017 09:55

      +1, тоже сразу возник такой вопрос. Может какая-то погрешность учитывается или формируется «профиль» человека — «тип с вечно недовольным лицом». :)


      1. MaslovAlexey
        20.06.2017 10:03

        Мы считаем только эмоции, в которых уверены на 60 и более процентов, остальные отбрасываем


      1. MaslovAlexey
        20.06.2017 10:04

        А что касается вечно недовольных лиц — тут вы праву, эмоциональная карта диалога в России и Италии, к примеру будет сильно отличаться. Это вопрос к устанавливаемым Kpi. Мы сейчас как раз над этим работаем


        1. Schvepsss
          20.06.2017 10:07

          Кстати, было бы интересно почитать про эмоциональные карты в разных странах. Вы будете делать своё исследование или на основе уже известных?


          1. MaslovAlexey
            20.06.2017 10:19

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


            1. Schvepsss
              20.06.2017 10:22
              +1

              Тогда будем надеяться, что увидим здесь статью от вас по этой теме. :)


              1. MaslovAlexey
                20.06.2017 10:30
                +1

                Спасибо! Будем стараться


  1. hdkr
    20.06.2017 09:40

    Недавно решил в Watch Dogs 2 поиграть. Сбор и запись всех данных о пользователе без его ведома. Что-то мне это напоминает.

    А есть ли шанс у клиента обратиться к компанию не попав под пристальный взгляд машины записывающей его эмоции, видео и голос? Не думали ли Вы что это может быть МИНУСОМ и мешать коммуникации как клиента так и оператора.


    1. stasus
      20.06.2017 09:45
      +1

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


      Сейчас и так пишут везде, ТЦ, улицы, автодороги, банки, офисы. Так почему бы не получить от этого дополнительную выгоду?


      1. hdkr
        20.06.2017 10:13
        +1

        "… о записи должны предупреждать. Если не устраивает, можно обратиться в другое место…… Сейчас и так пишут везде, ТЦ, улицы, автодороги, банки, офисы..."

        В этом и проблема не нравится ищи что-то другое, но пишут везде. Предупреждают НЕ равно спрашивают разрешения.

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


        1. Schvepsss
          20.06.2017 10:27
          -1

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


  1. murzilka
    20.06.2017 10:49

    А если на клиентском месте о оператора банально неудобный стул, или дует из кондиционера, или пахнет из мусорного ведра, или ещё что-то, что будет неудобно, неприятно большинству клиентов, оператор будет получать стабильно низкие оценки?
    А если во время беседы клиенту позвонили и сообщили о смерти любимого хомячка, система зарегистрирует слёзы и рыдания как низкую оценку оператору?


    1. frees2
      20.06.2017 11:00

      Достаточно связать эмоциональную реакцию с монологами ( предложениями) продавца-покупателя.
      Голосовая реплика -> реакция.
      Эмоциональная реплика продавца ( типо улыбка, как определённая от души...) -> реакция.
      Записывать надо и продавца и покупателя.

      Теперь точно верю в ботов продавцов…


      1. copal
        20.06.2017 11:47

        А разве уже существуют речевые синтезаторы, которые не отличимы от живых людей?


        1. frees2
          20.06.2017 13:46

          IBM вот в хабрахабр кинул ссылки на синтезаторы. Качество синтеза не ахти, бот чувствуется, но вот там можно в текст эмоции вставлять. Управлять эмоциональностью текста.
          Фейсбук работает над ботом продавцом, правда текстовым.


      1. murzilka
        20.06.2017 11:53
        +1

        Вот и первый лайфхак для это системы: сказать "улыбнитесь, пожалуйста". А дальше можно и нахамить :)


  1. dmandreev
    21.06.2017 11:09

    Можно уточнить, как видео с вебкамеры попадает в Cognitive Services для распознавания эмоций? В статье речь идет о картинках, не совсем очевидно.


    1. stasus
      21.06.2017 11:13

      В PoC который мы делали вместе (как сейчас, уже не знаю), видео резалось на последовательные картинки, которые клались в BLOB и на это событие срабатывала Azure Function, которая дёргала когнитивные сервисы с этой картинкой.


      1. dmandreev
        21.06.2017 12:59

        Было бы интересно узнать как сейчас. По тому подходу который описан получается что обработка часа видео 25 кс будет стоить $90 только на Cognitive Services.


        1. stasus
          21.06.2017 13:33

          MaslovAlexey, подскажешь, как сейчас у вас сделано?


          1. MaslovAlexey
            21.06.2017 13:46

            Если говорить про распознание лиц — то мы берём фрэймы с каждые несколько секунд, все кадры не имеет смысла распознавать, это действительно дорого


            1. dmandreev
              21.06.2017 22:04

              Если вы берете фреймы только через несколько секунд, то ни о каких замерах эмоционального состояния нельзя вести речь. Эмоции людей мимолетны. Это буквально миллисекунды. У вас будет один neutral в ваших отчетах.


              1. MaslovAlexey
                21.06.2017 22:15

                Вы неправы, от того берём ли мы все фрэймы или выборочно не зависит доля neural эмоций.


                1. dmandreev
                  21.06.2017 22:38
                  +1

                  Допустим я не прав. Но вы как правы то? У меня вот есть датасет из крупнейшего банка страны в размере 4 гигабайт, два гига датасетов где геймеры шапки надевают и им меряют энцефалограммы. Ради смеха еще вот такое видео сделал https://www.youtube.com/watch?v=nrqVXt5TeAw и это все мне доказывает что эмоции людей мерять надо в масштабах секунд. Если вы выхватите кадр из часового видео через 2-3-4 секунды — там будет недействительная информация. Потому что люди не могут улыбаться минутами. Они даже три секунды улыбаются редко.


                  1. MaslovAlexey
                    22.06.2017 08:25
                    +1

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


                  1. MaslovAlexey
                    22.06.2017 08:33
                    +1

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


  1. Olgashipa
    21.06.2017 15:34
    +1

    Интересно, а если человек придет недовольный? Или придет с нейтральным выражением лица, но уже на взводе? У нас нередка ситуация, когда люди приходят в мфц заранее обиженные )


    1. MaslovAlexey
      21.06.2017 16:00

      Оценка качества сервиса всегда имеет субъективный оттенок, как бы этот показатель не измеряли. В данном случае компания получает оценку 100% визитов клиентов, в отличие от классических систем оценки качества. Поэтому такие всплески легче отловить и исключить из статистики


      1. Olgashipa
        23.06.2017 16:39

        это есть. плюс, наверное, можно оценивать выражение лица «на входе»