[AIM303] – 推測をやめる:AIを使って顧客の会話を理解する #reinvent

本記事は、AIM302-R - [REPEAT] Create a Q&A bot with Amazon Lex and Amazon Alexaのワークショップレポートになります。
2019.12.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、中村です。12/1 - 12/6まで開催されているAWS re:Invent 2019に参加するためラスベガスに来ています。 本記事は、AIM303 - Stop guessing: Use AI to understand customer conversationsのワークショップレポートになります。

概要

AIアプリケーションを構築するためにデータサイエンティストである必要はありません。このワークショップでは、AWS AIサービスを使用して、顧客とのやり取りを理解するために使用できるサーバーレスアプリケーションを構築する方法を示します。自動音声認識、翻訳、自然言語処理(NLP)の助けを借りて、コールセンターの録音を分析します。Amazon Connectを使用して独自の通話録音を作成することにより、実際に使用できます。このワークショップの最後のステップでは、トランスクリプションとNLP分析を自動化する処理パイプラインを設定し、結果の分析と視覚化を実行します。

You don't need to be a data scientist to build an AI application. In this workshop, we show you how to use AWS AI services to build a serverless application that you can use to understand your customer interactions. Analyze call-center recordings with the help of automatic speech recognition, translation, and natural language processing (NLP). Get hands-on by producing your own call recordings using Amazon Connect. In the last step of this workshop, set up a processing pipeline to automate transcription and NLP analysis, and run analytics and visualizations on the results.

推測をやめる:AIを使って顧客の会話を理解する

ワークショップ資料

このワークショップは、us-east-1(バージニア北部)にて構築してください。

ワークショップを始める前にCloud9を作成します。
AWS Cloud9を開き、Create environmentをクリックして各項目を入力していきます。Name以外は、通常設定通りで大丈夫です。

Lab0: Call recordings

Amazon Connect・Amazon Polly・Prepared sample(準備されていたサンプル)の中から1つ選択して用意します。Prepared sampleを利用してワークショップを実施します。下記の作業をCloud9のターミナルから行います。

  1. S3バケットの作成
  2. サンプルファイルのダウンロード
  3. サンプルファイルをバケットへアップロード
cm-nakamura.yuki:~/environment $ mkdir audio

cm-nakamura.yuki:~/environment $ cd audio/

cm-nakamura.yuki:~/environment/audio $ curl "http://d1z04l54rp7h7d.cloudfront.net/aim303/sample1.wav" --output sample1.wav
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3139k  100 3139k    0     0  47.1M      0 --:--:-- --:--:-- --:--:-- 47.1M

cm-nakamura.yuki:~/environment/audio $ curl "http://d1z04l54rp7h7d.cloudfront.net/aim303/sample2.wav" --output sample2.wav
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3833k  100 3833k    0     0  39.4M      0 --:--:-- --:--:-- --:--:-- 39.4M

cm-nakamura.yuki:~/environment/audio $ ls
sample1.wav  sample2.wav

cm-nakamura.yuki:~/environment/audio $ aws s3 mb s3://aim303-audio-1208
make_bucket: aim303-audio-1208

cm-nakamura.yuki:~/environment $ aws s3 sync audio s3://aim303-audio-1208/connect
upload: audio/sample2.wav to s3://aim303-audio-1208/connect/sample2.wav
upload: audio/sample1.wav to s3://aim303-audio-1208/connect/sample1.wav

バケットの配下にアップロードされていることが確認できました。

cm-nakamura.yuki:~/environment $ aws s3 ls s3://aim303-audio-1208/connect/
2019-12-08 13:52:18    3214764 sample1.wav
2019-12-08 13:52:18    3925804 sample2.wav

Lab1: Amazon Transcribe

アップロードした音声を実際に文字起こししてみましょう。先ほどS3アップロードしたパスを保存してください。

  • s3://aim303-audio-1208/connect/sample1.wav
  • s3://aim303-audio-1208/connect/sample2.wav

Amazon Transcribeを開き、Create jobをクリックしてジョブを作成します。Create transcription jobの下記を修正します。

  • Input data > Input file location on S3に音声をアップロードしたS3のパスを入力
  • Output data > Audio identificationをChannel identificationに変更

Createをクリックするとジョブ一覧ページに遷移し、StatusがIn progressになるはずです。

StatusがCompleteになったら、ジョブ名をクリックし詳細を確認します。Transcription previewに文字起こしデータが表示されます。サンプルの音声はAmazon Connectの録音データ同様にチャンネル分けされているのでChannel 0とChannel 1で話者の会話が分離されています。

Lab2: Amazon Translate

文字起こししたテキストをもとに、翻訳を行います。
Amazon Translateを開き、リアルタイム翻訳を起動をクリックし実行します。ソース言語をAuto(auto)にし、先ほど文字起こししたテキストを入力します。

概ね文章が正しく翻訳されているのですが、reinventなど専門用語の翻訳がおかしい箇所があります。ワークショップでは触れませんがこのような場合、カスタム用語を用いて正しい翻訳が可能です。

Lab3: Amazon Comprehend

文字起こししてテキストのインサイトや関係を見つけます。フレーズ、場所、人、ブランド、またはイベントを抽出したり、テキストがどれほどポジティブかネガティブかを認識します。トークン化と品詞を使用してテキストを分析します。トピックごとにテキストファイルのコレクションを自動的に整理します。Amazon ComprehendのAutoML機能を使用して、組織のニーズに合わせてカスタマイズされたエンティティまたはテキスト分類モデルのカスタムセットを構築することもできます。

Amazon Comprehendを開き、Launch Amazon ComprehendをクリックしてReal-time analysisを開始します。Input textに文字起こしデータを入力してAnalyzeを実行すると、検出したエンティティが表示されます。他にもSentimentのタブに切り替えることでテキストの感情も読み取ることができます。

Lab4: Processing pipline

Amazon TranscribeとAmazon Comprehendを自動実行するパイプラインをCloudformationを使って作成します。このURLをクリックしてCloudformation画面に遷移します。全て次へで進めていき、機能と変換では全項目にチェックを入れてスタックの作成を実行してください。

Cloudformationのスタック一覧ページでCREATE COMPLETEされていれば完了です。次に作成したリソースを使って実際の動作をみていきます。パイプラインは、Amazon Connectの録音データを使って実行するように設計されています、今回はデータ準備の容易さから既存のAmazon Connectの録音データを利用してパイプラインを実行してみます。Amazon Transcribeの時に利用した下記のファイルです。

  • s3://aim303-audio-1208/connect/sample1.wav
  • s3://aim303-audio-1208/connect/sample2.wav

Cloudformationの出力からS3バケット名をメモしておきます。

Cloud9を開きダウンロード済みのサンプル音声をメモしたS3バケットの仮想フォルダconnect配下にコピーします。contact-idをmetatagに追加してコマンドを実行します。

cm-nakamura.yuki:~/environment $ aws s3 cp sample1.wav s3://ec4e50ab57554d67a6cedb25d2e3252b-connect/connect/sample1.wav --metadata contact-id=aim303-sample1
upload: ./sample1.wav to s3://ec4e50ab57554d67a6cedb25d2e3252b-connect/connect/sample1.wav

AWS Step Functionsを開くとTranscribeStateMachine-xxxxxxというステートマシンが作成されてます。このパイプラインは、まずステレオファイルごとに音声を分割します。つまりエージェントと顧客の音声を別にしています。その後にAmazon Transcribeで文字起こしを開始します。Step Functionsでは各状態を認識し、状態が更新された場合次の処理(Lambda Function)を実行します。各実行の詳細ではビジュアルワークフローにて処理がどこまで実行されたかを確認できます。

今回は、Amazon Transcribeのジョブを開始し、実行待ちのタイマー、ジョブステータスを監視、完了していたらS3の特定フォルダへ保存するというフローになっています。pythonベースのLambda Functionで構築済みのAWSアカウントでは下記より確認ができます。

バケット名上のパンくずをみていただければわかりますが、Customer, Agentと同一のContact Idで音声が分離されています。

ファイルアップロードされると、S3のcreateObjectをトリガーにLambdaを実行します。

また仮想フォルダであるtranscriptionsには、文字起こし/会話分析したデータがJSONで保存されています。

まとめるとこのようになります。

  • Cloudformationで作成したバケットのconnect配下にmetatagのcontact-idを含むファイルが生成される
  • ファイルが生成されたら話者ごとに音声の分離、文字起こしがされる
  • 音声ファイルが分離されS3にアップロードされたのをトリガーに会話分析結果を保存する

Lab5: Amazon Athena

Amazon Athenaは、Amazon S3のデータを標準的なSQLを利用して分析できるサービスです。サーバーレスでありクエリ実行に課金されインフラストラクチャのマネジメントが不要になります。Amazon Athenaを使うことで、分析データを準備するための複雑なETL作業がなくすこともできます。巨大なデータセットへSQLスキルがある誰もが簡単に分析を行えます。
AWS Glue Data Catalogと統合されており、さまざまなサービスで統一されたメタデータリポジトリを作成し、データソースをクロールしてスキーマを検出し、カタログに新しいテーブルおよびパーティション定義を追加し、スキーマを維持・バージョン管理できます。また、Glueの完全に管理されたETL機能を使用して、データを変換したり、列形式に変換したりして、コストを最適化し、パフォーマンスを向上させることもできます。

それでは、NLPの結果にクエリをかけてみます。 Amazon Athenaをクリックして、クエリエディタを開きます。

名称
Data source awsdatacatalog
データベース comprehendgluedatabase-xxxxxx

に設定しておきます。クエリエディタの上に、このような記載がありますので、リンクをクリックしてLab3のCloudformationで作成したS3バケット名/query-results/で登録します。

Before you run your first query, you need to set up a query result location in Amazon S3. Learn more

登録が完了したら、クエリを実行します。

select * from sentiment_analysis;

パイプライン実行は1度だけ行っているので、contactidがaim303-sample1のものが表示されているはずです。このようにパイプライン実行データを分析することができるので文字起こしや会話分析の改善(カスタム単語の追加)などに利用しましょう。

Lab6: Amazon Quicksight

Amazon Quicksightは、組織内でデータのインサイトを簡単に共有できるクラウドBIサービスです。ブラウザまたはモバイルデバイスからアクセスできるインタラクティブなダッシュボードを作成および公開できます。またダッシュボードをアプリケーションに埋め込み、顧客に強力なセルフサービス分析を提供できます。セッションごとに課金のため、使用した分のみです。これによりシートごとのライセンスなしで、必要な情報にアクセスが可能です。

Amazon Quicksightを開きます。Amazon Quicksightにsign upしたことがない場合は、Sign up for Quicksightをクリックして設定をしていきます。今回は、Standard Editionを選択し、次に進みます。Amazon Athenaにチェックを入れて、Amazon S3かChoose S3 bucketsで通話データが保存されているバケットを選択します。

最後に、QuickSight account nameに一意のアカウント名・Notification email addressに有効なメールアドレスを入力し設定を完了してください。

ダッシュボードに移動したら、New analysisをクリックし、次にNew data setをクリックしてデータを作成します。

今回は先ほど作成したAthenaを利用します。Data sourceは、awsdatacatalogです。次にデータベースは、comprehendgluedatabase-xxxxxを選択してください。Athenaでクエリを実行した時に既存のデータでは、ネストされた配列が含まれているのでカスタムSQLを実行して各項目をカラムに分割していきます。テーブルは、sentiment_analysisが表示されると思います。チェックを入れて次に進みましょう。

最後にクエリ実行先をDirectly query your dataにチェックしてVisualizeをクリックしてください。これでQuicksightを使ってビジュアライズが可能になります。

Quicksightのダッシュボードに遷移したらFields listのtalkerをAutoGraphへドラッグアンドドロップしましょう。

AutoGraphがビジュアライズされました。TalkerとSentimentのレコードを追加するとこのような形になりました。

これで保存データを元に、Quicksightでビジュアライズできるようになりました。データを使ってビジュアライズをしてわかりやすいようにできます。

まとめ

Amazon Connectの通話録音をベースに顧客を理解する仕組みを構築しました。音声の文字起こし・分析などは主にAmazon Connectのユースケースがマッチしており、日本語での対応もされたので楽しみ!と思ったのですが、Contact Lens for Amazon Connectが登場したので簡単に導入するならそちらが良いかもしれません(笑)