Pull to refresh

Чат-бот для отзывов из Google Play. Опыт QuData

Reading time5 min
Views4.1K

Боты. В технических кругах о них не писал только ленивый.Мы хотим представить вам свою версию применения этой популярной и такой обсуждаемой темы.

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

Мы заметили, что поддержка пользователей по всем проектам занимает теперь огромную часть времени. И, естественно, захотели оптимизации. А кто может помочь суровым айтишникам в оптимизации? Конечно же искусственный интеллект!

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

Как строить будем?

Архитектура нашего бота будет состоять из трех основных этапов:

  1. Получение отзывов из Google Play

  2. Интерпретация намерения, комплексный анализ полученного отзыва для формирования ответа

  3. Отправка ответа на Google Play

Для начала нам нужно как-то получать наши отзывы. 

Будем использовать Google Play Developer API. Метод list возвращает список отзывов, но только за последнюю неделю. Ну нам и достаточно. Все равно будем отвечать чаще, чем раз в неделю.

В случае успеха тело ответа содержит данные со следующей структурой:

JSON representation
{
  "reviews": [
    {
      object (Review)
    }
  ],
  "tokenPagination": {
    object (TokenPagination)
  },
  "pageInfo": {
    object (PageInfo)
  }
}

Отзывы получили. Супер. Теперь, прежде, чем отдать их в нейронную сеть, нужно предусмотреть какую-то текстовую предобработку. Отзывы бывают очень разные. 

Например, такие.

Или такие.

Или вообще такие.

Боюсь, наш виртуальный помощник может быть к такому не готов.Итак, чистим все! Убираем регистр, знаки препинания, смайлы и все остальное, что отвлекает от сути отзыва.
Кстати, несмотря на все наши оптимизации смысл отзыва все равно может быть непонятен. И не только боту, но и человеку.

Даже не пытайтесь это распознать :) Что ж. Будем надеяться, такие случаи - скорее исключение.Интересно, что скажет на это бот?Давайте строить нашу сеть.

Общая схема работы представлена на картинке.

На вход мы будем подавать отзывы наших пользователей.

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

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

При обучении сети будем стремиться минимизировать функцию потерь в виде суммы косинусных произведений между двумя похожими векторами и k-непохожими. Таким образом, после обучения каждому намерению будет поставлен в соответствие некий вектор. То есть, для нас важно понимать, что слова “интересная” и “хорошая” гораздо ближе к друг другу, чем слова “банан” и “компьютер”.

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

Так, намерение получили, теперь мы знаем, что хотел сказать нам пользователь. Осталось дать ответ. Для этого мы заранее указали реакции-ответы на все наши типы намерений. Теперь, когда мы знаем тип намерения, мы просто выдаем соответствующую ему реакцию.

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

Прежде, чем начать обучение, мы провели небольшую предобработку текста.

Убрали все смайлы. Были такие отзывы, которые состояли только из смайлов, типа большого пальца вверх. Такие отзывы не попали в выборку.

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

Без знаков препинания и регистр ни к чему. Тоже в топку.

Особенная тема - повторение букв. Отзывы “крууууто”, “супееееер” встречались очень часто. Поэтому тоже почистили.

Около 20% отзывов мы оставили для валидации, остальное ушло в обучающую выборку.

Всё. теперь мы готовы начать обучение. 
В нейронную сеть отзывы поступают последовательно по одному. Например, отзыв с текстом “просто классная игра” подается на вход.
В первую очередь к нему применяется токенизация и лемматизация . Отзыв разбивается на отдельные слова и затем различные формы одного слова сводятся к одной словарной форме. Ну например, “игра” вместо “игрой”, “в игре”.

Получится что-то вроде: “просто “  “классная “  “игра”

Далее применяем к нашим токенам метод N-грамм. N-грамм это просто последовательности букв из слова. Например, если разбить слово “классная” на триграммы, получим {“кла”, “лас”, “асс”, “ссн”, “сна”, “ная”}. Для нашей задачи минимальная длина N-грамм - это две буквы, а максимальная - четыре.

Создается список признаков исходного текста и его токенов. Формируются дополнительные признаки из N-грамм. Создаются лексические и синтаксические признаки токенов текста. Их очень много. Только одних признаков N-грамм у нас получилось 14184.

Признаки формируем используя предобученную сеть BERT.

В качестве классификатора намерений применяем Transformer.Мы логически выделили разные типы намерений. Ну например: - пользователь доволен - пользователь недоволен

  •  пользователь только начал играть, пока не понятно - игра зависает - игра не запускается - пользователю понравилось последнее обновление

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

Ну и собственно, все. Когда намерение определено, нам лишь следует выдать на него соответствующий ответ.

А как же это работает на практике?

К примеру, у нас на страничке приложения в Google Play оставили такой отзыв.

От API нам придет текст с кодировкой смайлика UTF-8.“Просто классная игра 0xE2 0x9D 0xA4 0xE2 0x9D 0xA4 0xE2 0x9D 0xA4”

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

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

Мы определяем, что это намерение относится к типу “пользователь доволен” и отвечаем на него заранее подготовленным текстом для такого случая.

Ответ также публикуем на Google Play.

Замечательно. Пользователи не остались без внимания, а бот помог нам быстрее обработать все отзывы.

Конечно, бот не может заменить отдел поддержки. Человеческое общение никто не отменял. При технических неполадках или в случае низкой уверенности в ответе бот все равно отдает отзывы в отдел поддержки. Но их значительно меньше, чем было ранее. Сейчас 92% отзывов бот может обработать самостоятельно.

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

Tags:
Hubs:
Rating0
Comments2

Articles