https://a.storyblok.com/f/270183/961037/0cefb25bb5/classify-audio-nlp.png

Classificar automaticamente gravações de chamadas usando NLP

Publicado em April 28, 2021

Tempo de leitura: 3 minutos

A Voice API da Nexmo facilita a gravação de chamadas telefônicas recebidas e realizadas. No entanto, identificar todas as chamadas em que as pessoas estejam discutindo um determinado assunto, como “Ciência da Computação”, pode se tornar muito demorado se você tiver que ouvir cada arquivo de áudio todas as vezes.

Neste tutorial, vamos mostrar como você pode usar o Processamento de Linguagem Natural, por meio dos serviços do Google Cloud, para classificar automaticamente o conteúdo de cada gravação, de modo que você possa identificar rapidamente as chamadas de voz que trataram de assuntos específicos.

Pré-requisitos

Todo o código deste tutorial está disponível no GitHub. Ele usa o pipenv para gerenciar dependências e requer o Python 3.6.4. Você pode criar um ambiente virtual e instalar as dependências executando:

pipenv install

Vamos usar a Voice API da Nexmo, mais especificamente a record ação. Antes de continuar com este tutorial, você deve ler sobre nossos blocos de construção de voz, bem como alguns de nossos tutoriais anteriores sobre a criação de Applications de voz.

Neste tutorial, também utilizamos duas APIs dos serviços do Google Cloud: o Cloud Speech-to-Text e o Cloud Natural Language. Você deve criar um novo projeto no Google Cloud Platform (GCP) e certificar-se de habilitar o Speech-to-Text e o Natural Language.

Lembre-se de baixar as credenciais do seu projeto no GCP e armazená-las em um local ao qual seu script possa acessá-las. Eu coloquei as minhas na raiz do projeto e as nomeei google_private.json.

Há um .env.example arquivo na raiz do projeto. Esse arquivo de exemplo descreve as diferentes variáveis de ambiente que o aplicativo espera encontrar. Copie esse arquivo e renomeie-o para .env. Quaisquer valores definidos nesse arquivo são carregados automaticamente no seu ambiente quando você executa:

pipenv shell

Gravação da nossa ligação

Esperamos que, a esta altura, você já esteja familiarizado com NCCOs. Nossa primeira rota no Flask vai servir nosso arquivo NCCO, instruindo a Voice API da Nexmo a gravar todas as chamadas para o nosso número virtual:

@app.route("/", methods=["GET"])
def ncco():
    logger.info(f"New call received from {request.args['from']}")
    return jsonify(
        [
            {"action": "talk", "text": "Record your message after the beep"},
            {
                "action": "record",
                "eventUrl": [f"{os.environ['BASE_URL']}/recordings"],
                "format": "wav",
                "endOnKey": "*",
                "beepStart": True,
            },
        ]
    )

Há dois pontos principais a serem observados no código acima:

  1. A event_url aponta para o nosso servidor Flask local. O manipulador dessa rota será abordado mais adiante neste tutorial.

  2. O formato de gravação está definido como wav; por padrão, o Nexmo fornece as gravações como arquivos MP3. No entanto, o serviço Google Speech-to-Text suporta o formato WAV, portanto, precisamos definir o formato da nossa gravação para que seja compatível.

Webhook de nova gravação

Sempre que uma chamada é concluída, a Voice API da Nexmo envia uma POST solicitação para o nosso event_url. Eu extraí a maior parte do trabalho pesado do manipulador de visualização do Flask e o transferi para uma série de tarefas em segundo plano usando Huey:

pipeline = download_recording_task.then(transcribe_audio).then(classify_transcription)
huey.enqueue(pipeline)

Baixe a gravação

O get_recording método no cliente Python da Nexmo é novo; portanto, se você já instalou o cliente Python anteriormente, provavelmente precisará atualizá-lo:

@huey.task()
def download_recording(recording_url, recording_uuid):
    logger.info(f"Download recording {recording_uuid}")

    recording = nexmo_client.get_recording(recording_url)
    recordingfile = f"./recordings/{recording_uuid}.wav"
    os.makedirs(os.path.dirname(recordingfile), exist_ok=True)

    with open(recordingfile, "wb") as f:
        f.write(recording)

    return {"recording_uuid": recording_uuid}

Depois que você baixar o arquivo WAV do Nexmo, o aplicativo o salva no recordings diretório. A download_recording função retorna o recording_uuid dentro de um dicionário, já que o Huey passa quaisquer valores de retorno para a próxima função no pipeline como argumentos-chave.

Transcreva a gravação

Antes de podermos realizar qualquer Processamento de Linguagem Natural no conteúdo do nosso arquivo de áudio, precisamos convertê-lo em texto:

@huey.task()
def transcribe_audio(*args, recording_uuid):
    # Instantiates a client
    client = speech.SpeechClient()

    # The name of the audio file to transcribe
    file_name = f"./recordings/{recording_uuid}.wav"

    # Loads the audio into memory
    with io.open(file_name, "rb") as audio_file:
        content = audio_file.read()
        audio = speech_types.RecognitionAudio(content=content)

    config = speech_types.RecognitionConfig(
        encoding=speech_enums.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=16000,
        language_code="en-US",
    )

    # Detects speech in the audio file
    logger.info(f"Sending file {recording_uuid} for transcribing")
    response = client.recognize(config, audio)

    return {
        "transcription_text": response.results[0].alternatives[0].transcript,
        "recording_uuid": recording_uuid,
    }

Você pode ler mais sobre a API Speech-to-Text do Google Cloud no site deles. Agora que o arquivo de áudio foi convertido em texto, a próxima função no fluxo de trabalho é acionada.

Classificação da gravação

Screenshot of terminal showing audio classificationScreenshot of terminal showing audio classification

O aplicativo faz uma última chamada à API, desta vez para o serviço Google Cloud Language:

@huey.task()
def classify_transcription(transcription_text, recording_uuid):
    client = language.LanguageServiceClient()

    document = language_types.Document(
        content=transcription_text, type=language_enums.Document.Type.PLAIN_TEXT
    )

    logger.info(f"Classifying transcription for recording {recording_uuid}")
    categories = client.classify_text(document).categories

    for category in categories:
        print(colorful.bold_violet("=" * 20))
        print(colorful.bold_violet("{:<16}: {}".format("name", category.name)))
        print(
            colorful.bold_violet("{:<16}: {}".format("confidence", category.confidence))
        )

    return True

Essa API pode fazer muito mais do que apenas classificar textos; ela pode fornecer informações sobre o sentimento do texto fornecido ou dividir o texto em uma série de frases e tokens por meio da análise sintática. Leia a documentação para obter mais detalhes.

Leitura complementar

Esperamos que nosso tutorial tenha dado a você uma ideia do que é possível fazer combinando a Voice API da Nexmo com o Google Cloud. Se quiser mais informações sobre outras coisas interessantes que você pode realizar com a Voice API da Nexmo, estes outros tutoriais podem ser do seu interesse:

Compartilhar:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Aaron BassettEx-funcionários da Vonage

Aaron era um defensor de desenvolvedores na Nexmo. Engenheiro de software experiente e aspirante a artista digital, Aaron costuma ser visto criando coisas com código ou com eletrônica; às vezes, os dois. Geralmente, dá para perceber quando ele está trabalhando em algo novo pelo cheiro de componentes queimando no ar.