Компонент CPD (детектор ответов)

Описание

Применяется в исходящих кампаниях для детекции ответа "живого" человека.

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

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

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

Table 1. Системные характеристики

Индекс

225

Краткое название

cpd

Типы сценариев

IVR

Стартовый модуль

era_sip_ivr_script_component_cpd

Режим

Асинхронный

Иконка

225

Характер разветвления

Разветвляющий, замыкающий

Свойства

Table 2. Свойства
Спецификация Описание

Название: Таймаут, с
Код: collectTimeSec
Усл. видимости: нет
По умолчанию: 5

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

Название: Сохранить файл записи
Код: saveRecord
Усл. видимости: нет
По умолчанию: Нет

Признак сохранения файла записи, отправленного сервису детектора ответа. Сохранение выполняется в каталог /var/lib/era_files/answer_detector_records/<domain>/<type>

  • domain - домен в рамках которого выполнялся разговор.

  • type - тип результата, который вернул детектор ответа.

Название: Результат в переменную
Код: result
Усл. видимости: нет
По умолчанию: — 

Переменная, куда заносится причина завершения работы компонента.

Название: Переход, обнаружено
Код: transferFound
Усл. видимости: нет
По умолчанию: — 

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

Название: Переход, не обнаружено
Код: transferNotFound
Усл. видимости: нет
По умолчанию: — 

Компонент, которому передается управление в случае если детектор ответа не обнаружил в записи "живого" человека.

Название: Переход, ошибка
Код: transferError
Усл. видимости: нет
По умолчанию: — 

Компонент, которому передается управление в случае возникновения ошибки.

Принцип работы

Анализ выполняет консольное приложение cpd, входящее в состав платформы (./era_env/priv/bin/cpd/cpd).
Компонент запускает cpd в режиме анализа и передает ему звук вызываемой стороны через стандартный ввод (stdin).
Приложение "слушает" начало разговора и отвечает на единственный вопрос: ответил ли на звонок живой человек.
Это позволяет автоматизированному дозвону подключать оператора только тогда, когда с высокой вероятностью на линии человек, а не тишина, факс, гудки или робот.

Компонент завершается успехом только при результате human.

Входные данные и результат

На вход cpd принимает сырые PCM-данные без заголовка: 8000 Гц, 16 бит, моно.
Данные читаются порциями по мере поступления и сразу пропускаются через анализатор.

Результат выводится в stdout одной строкой:

Результат Значение

human

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

ivr

Робот, автоответчик, голосовое меню, музыка при ожидании.

tone

Тональный сигнал: гудки, сигнал "занято", сигнал автоответчика и т. п.

fax

Факс.

silence

За время анализа не обнаружено ни одной значимой реплики.

Условия завершения

cpd завершает работу и выдает результат при первом из событий:

  1. Текущий этап анализа принял решение.

  2. Данные в stdin не поступают дольше, чем --recv-timeout (по умолчанию 3000 мс).

  3. cpd работает дольше, чем --timeout (по умолчанию 7000 мс).

  4. Поток stdin закрыт отправителем.

При завершении по таймауту результат выдается по тем данным, что успели накопиться. Если значимых реплик не было, результат silence.

Этапы анализа

Этап 1. Статистико-эвристический анализ

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

  • человек определяется после паузы, следующей за короткой приветственной репликой абонента;

  • робот или IVR определяется по длинной непрерывной реплике;

  • тональный сигнал и факс определяются по стабильной амплитуде сигнала, факс — по большей длительности;

  • тишина определяется по истечении таймаута без значимых реплик.

Алгоритм использует набор параметров. Значения по умолчанию зашиты в программу и не оптимальны. Их можно подобрать под собственные записи в режиме обучения (см. Режим обучения (learn)). Подобранные значения сохраняются в файле SettingsML.json, который передается cpd ключом --ml-settings-path.

Этап 2. Поиск характерных частот

Работает параллельно с первым этапом на тех же данных. В отличие от первого этапа, здесь ничего не подбирается автоматически: искомые признаки задает инженер. Рассмотрев запись робота в аудиоредакторе, он отмечает, на каких частотах и в каком временном интервале виден характерный всплеск, и описывает это в файле SettingsSpectrum.json (см. SettingsSpectrum.json). cpd проверяет каждый описанный интервал, как только тот полностью принят, и при совпадении немедленно завершает анализ с результатом, указанным для этого интервала.

Если файл не задан, поиск характерных частот не выполняется.

Этап 3. Поиск по базе аудиоотпечатков

Первые два этапа работают одновременно, и анализ завершается, как только один из них принял решение. Третий этап выполняется, только если это решение — human (то есть первый этап распознал человека, а второй не нашел характерных частот) и задана база отпечатков (--fingerprints-db). Цель этапа — отсеять роботов и автоответчики, которые по характеру реплик похожи на человека.

Вся принятая запись сравнивается с базой отпечатков, построенной заранее из шаблонных записей роботов (см. Режим построения базы отпечатков (rebuild-fingerprints)). Отпечатки — это подробное автоматически построенное описание характерных частот записи во времени, то есть то же, что инженер делает вручную на втором этапе, но без участия человека и с большей детализацией.

Если запись совпала с шаблоном, результат заменяется на тип этого шаблона. Если совпадений нет, результат остается human.

Если база не задана, третий этап не выполняется.

Файлы настроек

SettingsML.json

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

SettingsSpectrum.json

Описания характерных частот для второго этапа. Файл составляется инженером вручную и представляет собой JSON-массив, каждый элемент которого описывает один временной интервал:

Поле Тип Смысл

name

строка

Произвольное имя для удобства инженера.

from

число

Начало интервала в мс от начала данных, поступающих в stdin.

to

число

Конец интервала в мс от начала данных, поступающих в stdin. Должен быть больше from и меньше --timeout, иначе интервал не успеет проверяться.

spectrum

массив

Список диапазонов частот {"min": Гц, "max": Гц}, в которых ожидаются всплески. Количество элементов задает, сколько самых сильных пиков будет выделено из спектра интервала. Все они должны попасть в перечисленные диапазоны.

result

строка

Результат при совпадении: Human, IVR, Tone, Fax или Silence (регистр не важен).

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

Пример: робот, у которого в интервале 0.5…1.5 с и 1…2 с от начала данных два самых сильных пика лежат около 100 Гц и 200 Гц.

[
  {
    "name": "Robot1",
    "from": 500,
    "to": 1500,
    "spectrum": [{"min": 195, "max": 205}, {"min": 97, "max": 103}],
    "result": "IVR"
  },
  {
    "name": "Robot1-late",
    "from": 1000,
    "to": 2000,
    "spectrum": [{"min": 195, "max": 205}, {"min": 97, "max": 103}],
    "result": "IVR"
  }
]

База отпечатков

Бинарный файл cpd_fingerprint.db, формируемый cpd в режиме построения базы. Путь к нему передается ключом --fingerprints-db. Базу нужно перестраивать после любого изменения набора шаблонов.

Размещение на платформе

Файлы SettingsML.json, SettingsSpectrum.json и база отпечатков cpd_fingerprint.db располагаются в каталоге :SYNC/domains/<YOUR_DOMAIN>/data/cpd, где <YOUR_DOMAIN> — имя домена. Компонент передает пути к ним в cpd при каждом запуске.

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

Режимы работы cpd

Режим задается ключом --mode:

Режим Назначение

analyze (по умолчанию)

Анализ звука из stdin. Результат — тип источника звука.

learn

Подбор параметров этапа 1 по размеченным записям. Результат — SettingsML.json.

rebuild-fingerprints

Построение базы аудиоотпечатков из шаблонных записей. Результат — файл базы.

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

Режимы rebuild-fingerprints и learn инженер запускает вручную при каждом обновлении набора размеченных записей: базу отпечатков перестраивать необходимо, обучение повторять желательно. Полученные файлы размещаются на платформе вручную (см. Размещение на платформе).

Ключ --help выводит справку по всем параметрам.

Режим анализа (analyze)

Пример того, как компонент вызывает cpd для анализа:

cpd \
    --mode=analyze \
    --ml-settings-path=/var/lib/era_files/syncroot/domains/pbx.era-platform.ru/data/cpd/SettingsML.json \
    --spectrum-settings-path=/var/lib/era_files/syncroot/domains/pbx.era-platform.ru/data/cpd/SettingsSpectrum.json \
    --fingerprints-db=/var/lib/era_files/syncroot/domains/pbx.era-platform.ru/data/cpd/cpd_fingerprint.db \
    --timeout=7000 \
    --recv-timeout=3000
Параметр По умолчанию Описание

--ml-settings-path

не задан

Путь к SettingsML.json с параметрами этапа 1. Необязательный. Если не задан, используются зашитые (неоптимальные) значения.

--spectrum-settings-path

не задан

Путь к SettingsSpectrum.json с характерными частотами. Необязательный. Если не задан, второй этап не выполняется.

--fingerprints-db

не задан

Путь к базе аудиоотпечатков. Необязательный. Если не задан, третий этап не выполняется.

--timeout

7000

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

--recv-timeout

3000

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

--verbose

выключен

Выводить расширенный результат (см. ниже).

Вывод в stdout — одна строка с результатом. С ключом --verbose выводятся три строки:

  1. результат (human, ivr, tone, fax, silence);

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

  3. степень совпадения с шаблоном (число от 0 до 1), либо 0.

Если необходимо проверить работоспособность cpd на конкретной записи, можно воспользоваться таким bash-скриптом, который отрезает от wav-файла (PCM, 8000 Гц, 16 бит, моно) заголовок в 44 байта и подает оставшиеся сырые PCM-данные в stdin cpd:

#!/bin/bash

CPD_DIR=/var/lib/era_files/syncroot/domains/pbx.era-platform.ru/data/cpd
SAMPLE_FILE=/some/path/to/sample.wav

dd if=$SAMPLE_FILE skip=44 bs=64 status=none | \
cpd \
    --mode=analyze \
    --ml-settings-path=$CPD_DIR/SettingsML.json \
    --spectrum-settings-path=$CPD_DIR/SettingsSpectrum.json \
    --fingerprints-db=$CPD_DIR/cpd_fingerprint.db \
    --timeout=7000 \
    --recv-timeout=3000 \
    --verbose

Так можно увидеть, как cpd отработает конкретную запись, сработал ли третий этап и с каким шаблоном совпала запись.

Режим обучения (learn)

Обучение — это подбор параметров первого этапа по заранее размеченному (разложенному по папкам) набору записей с учетом биаса (приоритета). Биас задает, какая ошибка дороже: потерять живого абонента или передать оператору не-человека.

Как проходит обучение:

  1. Записи из каталога данных загружаются в память. Из каждой используются только первые 10 секунд.

  2. Первая итерация выполняется на значениях по умолчанию. Существующий SettingsML.json в режиме обучения не читается: каждый запуск начинается с нуля.

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

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

В обучении участвует только первый этап. Характерные частоты и база отпечатков в нем не используются.

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

Пример командной строки:

cpd \
    --mode=learn \
    --learn-bias=0 \
    --learn-iterations=10000 \
    --learn-data-dir-path=/some/path/to/wavs/ \
    --learn-output-file-path=/var/lib/era_files/syncroot/domains/pbx.era-platform.ru/data/cpd/SettingsML.json
Параметр По умолчанию Описание

--learn-bias

0

Приоритет от −9 до +9. −9 — допускать потерю живых ответов, +9 — допускать плохие звонки на операторов, 0 — нейтрально.

--learn-iterations

10000

Количество итераций. 1 — только вывод текущей статистики на значениях по умолчанию, 10000 — реальное обучение.

--learn-data-dir-path

Путь к каталогу с размеченными данными (см. Данные для обучения). Обязательный.

--learn-output-file-path

не задан

Путь к выходному SettingsML.json. Если не задан, результат только печатается в консоль. Существующий файл перезаписывается.

Выходной файл записывается только если найден набор параметров лучше значений по умолчанию. Если улучшения не было (в том числе при --learn-iterations=1), файл не создается.

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

Готовый SettingsML.json следует разместить в каталоге :SYNC/domains/<YOUR_DOMAIN>/data/cpd, заменив предыдущий.

Режим построения базы отпечатков (rebuild-fingerprints)

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

Пример командной строки:

cpd \
    --mode=rebuild-fingerprints \
    --templates-dir=/some/path/to/templates/ \
    --fingerprints-db=/var/lib/era_files/syncroot/domains/pbx.era-platform.ru/data/cpd/cpd_fingerprint.db
Параметр По умолчанию Описание

--templates-dir

Путь к каталогу с шаблонными записями (см. Шаблоны для базы отпечатков). Обязательный.

--fingerprints-db

Путь к создаваемому файлу базы. Обязательный. Существующий файл перезаписывается целиком.

Требования к шаблонным записям описаны в разделе Шаблоны для базы отпечатков.

По завершении в консоль выводится время построения в миллисекундах.

Готовую базу cpd_fingerprint.db следует разместить в каталоге :SYNC/domains/<YOUR_DOMAIN>/data/cpd, заменив предыдущую.

Подготовка записей

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

Формат файлов

Формат: *.wav, PCM, 8000 Гц, 16 бит, моно.

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

ffmpeg -i source.wav -ar 8000 -ac 1 -c:a pcm_s16le result.wav

Правила разметки

Файлы раскладываются по подпапкам, имя подпапки задает класс записи. Регистр имени не важен, вложенность произвольная: значение имеет только имя папки, непосредственно содержащей файл. Имена самих файлов произвольные.

Папка Что кладется

Human

Живые ответы людей: человек берет трубку и отвечает приветствием.

IVR

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

Tone

Тональные сигналы: гудки, сигнал "занято", сигнал автоответчика перед записью и т. п.

Fax

Факс.

Silence

Тишина или фоновый шум без речи и сигналов.

Класс определяется по тому, что слышно в первые секунды записи, то есть по тому результату, который cpd должен выдать для этого звонка. Если запись начинается с робота, а через несколько секунд отвечает человек, это IVR. Если человек отвечает позже, чем длится анализ (по умолчанию 7 секунд), такую запись лучше не использовать вовсе.

Каждая запись должна относиться ровно к одному классу. Записи, в которых класс неочевиден (сильные помехи, обрыв, наложение сигналов), в набор не включаются: одна неверно размеченная запись портит результат сильнее, чем ее отсутствие.

Данные для обучения

Обучение подбирает параметры под то, как реально выглядит начало звонка, поэтому записи должны воспроизводить именно поток, который cpd получает от компонента:

  • запись начинается с момента ответа на вызов (кто бы или что бы ни ответило), то есть с того момента, когда компонент начинает передавать звук в cpd. Начало не обрезается до первой реплики и не дополняется тишиной: анализатор учитывает паузу перед первым словом;

  • полезная длительность — первые 10 секунд, остальное игнорируется. Записи короче 2–3 секунд малоинформативны;

  • никаких посторонних звуков после начала анализа: речь оператора, сигналы перевода вызова и т. п. должны быть отрезаны;

  • нужны примеры всех пяти классов, в первую очередь Human и IVR. Чем разнообразнее записи внутри класса (разные люди, разные роботы, разное качество связи), тем лучше подобранные параметры переносятся на реальные звонки;

  • объем классов должен быть сопоставим. Если записей Human в десять раз больше, чем IVR, оценка качества будет искажена.

Файлы из папок с именами, не совпадающими с классами, в обучении не участвуют.

Шаблоны для базы отпечатков

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

  • запись содержит саму реплику робота от ее начала: приветствие, музыкальную заставку, голосовое меню. Тишина перед репликой не мешает, но и не нужна;

  • в шаблон не должно попасть ничего, кроме источника: ни гудков до соединения, ни речи человека, ни звуков после окончания реплики. Все лишнее отрезается в аудиоредакторе;

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

  • на каждого робота достаточно одного шаблона. Если у робота несколько разных приветствий, для каждого нужен отдельный файл;

  • в базу имеет смысл класть только записи, совпадение с которыми должно менять результат: роботов и автоответчики. Совпадение с шаблоном типа Human результат не изменит.

Тип шаблона определяется именем подпапки по тем же правилам разметки. Файлы из подпапок с другими именами получают тип IVR.