Amazon Lexの分析機能で出てくる各用語を解説
はじめに
Amazon Lexの分析画面を初めて確認した際、会話(Conversation)のSuccessやDropped、発話(Utterance)のDetectedやMissedなどが何を表しているのか分かりませんでした。
Amazon Lexの分析機能を効果的に活用するためには、以下の4つの用語を理解することが重要です。本記事では、これらの用語について詳しく解説します。
- インテント
- スロット
- 会話
- 発話
先にAmazon Lexというサービス概要を解説します。
Amazon Lexは、音声やテキストによるアプリケーションの会話型インターフェースが構築できるAWSサービスです。
Lexボットは、主に 「発話(Utterances)」 と 「インテント(意図/Intent)」 で構成されています。
Lexにおける 発話とは、インテントを誘発させるユーザーの言葉のことです。 例えば、「ピザを注文したい」という発話は、「ピザ注文」のインテントを誘発します。
インテントは、ユーザーが実行したいアクションを表します。 例えば、「ピザ注文」や「注文状況確認」などがインテントとなります。ボットには少なくとも1つのインテントが必要です。
インテントは、主に以下の6つの要素で構成されています。
- サンプル発話(Sample Utterances)
- インテントを誘発させる発話のバリエーションのことです。各インテントにサンプル発話を設定することで、ユーザーの発話から適切なインテントを誘発させることができます。
- 初期応答(Initial response)
- インテント誘発後、ユーザーに送信される最初のメッセージです。このメッセージを通じて、ユーザーにインテントの目的を理解してもらい、必要な情報の入力を促すことができます。
- スロット(Slots)
- インテントを達成するために必要な、ユーザーが提供する値です。スロットプロンプトが伝えられた後、ユーザーはスロット値を入力します。
- 確認(Confirmation)
- インテントの全てのスロット値が入力された後、それらの値が正しいかどうかをユーザーに確認するプロンプトを設定できます。確認プロンプトは通常、ユーザーが「はい」または「いいえ」で回答できる質問形式です。
- フルフィルメント(達成/Fulfillment)
- インテントの全てのスロット値がユーザーによって提供されると、LexはAWS Lambdaを呼び出してユーザーのリクエストを処理できます。以下のオプションが選択可能です
- フルフィルメントコードフック:Lambda呼び出しを制御します。このオプションが無効の場合、Lambda関数を呼び出さなくてもフルフィルメントの処理は成功とみなされます。
- フルフィルメントアップデート:完了までに数秒以上かかるLambda関数の処理状況をユーザーに通知できます。この機能は、ストリーミング会話でのみ利用可能です。
- フルフィルメント応答:成功、失敗、タイムアウトの各ケースに対する応答を設定できます。フルフィルメントLambda呼び出しの結果に基づいて、適切な応答がユーザーに返されます。
- インテントの全てのスロット値がユーザーによって提供されると、LexはAWS Lambdaを呼び出してユーザーのリクエストを処理できます。以下のオプションが選択可能です
- 終了応答(Closing response)
- ユーザーのインテントが達成された後に送信されるメッセージです。会話の終了や、別のインテントに移行できることをユーザーに伝えるために使用されます。
AWSドキュメントでは、確認が完了したことを「インテントの実行準備が完了した」と表現しています。次のステップでは、設定されたフルフィルメントが実行されるか、もしくは終了応答が行われ、インテントが完了したとみなされます。
また、フルフィルメントの処理中は「インテントが実行中」、処理完了後は「インテントが達成した(実行完了した)」と表現されています。
アイドルセッションタイムアウトとは、ユーザーからの入力がなくセッションがアイドル状態となった場合に、セッションが維持される最大時間のことを指します。
デフォルトでは、アイドルセッションタイムアウトは5分に設定されていますが、0分から1,440分(24時間)の範囲内で任意の時間を指定できます。
用語解説
ボット分析の理解に不可欠な主要用語について解説します。
- インテント(Intent)
- スロット(Slot)
- 会話(Conversation)
- 発話(Utterance)
インテント
分析におけるインテントを説明する前に、インテントの分析に重要な役割を果たすLex APIの以下2つの要素について解説します。
- Intentオブジェクトのstateキー
- SessionStateオブジェクトのdialogActionオブジェクトのtypeキー
Intentオブジェクトのstate
stateは、インテントの達成状態(fulfillment state)を表す指標で、Lexのインテント処理の進行状況や結果を示します。
stateキーが取り得る値と内容は以下の通りです
InProgress
: Lexボットがインテント達成に必要なスロット値を引き出し中、または確認前の状態。- 例:一部のスロットが未入力の状態、または全スロットが入力済みで確認前の状態。
ReadyForFulfillment
: Lexボットがインテントの全スロット値が埋まり、フルフィルメント準備が整った状態。- 例:全てのスロットが入力され、確認プロンプト完了後、フルフィルメント準備が整った状態。
FulfillmentInProgress
: Lexボットがインテントのフルフィルメント処理を実行中の状態。- 例:フルフィルメント実行中の場合。
Waiting
: ボットがユーザーからの応答を待機している状態(ストリーミング会話のみ)- 例:ユーザーの次の入力を待っている状態。
Fulfilled
: Lexボットがインテントの達成を完了した状態。- 例:インテントのスロット入力、確認、終了応答が全て完了した場合。
Failed
: Lexボットがインテントの達成に失敗した状態。- 例:ユーザーが確認ステップで「いいえ」(拒否)と回答した場合。
dialogActionオブジェクトのtype
dialogActionは、Lexが次に実行すべきアクションを指定します。typeは、Lexボットがユーザーとのやり取りで実行するアクションの種類を表し、以下のものがあります
Close
: 次のアクションがないことを示す。- 例:インテントが終了する場合。
- 例:「ピザの注文が完了しました」と伝えた後、追加の応答が不要な場合。
ConfirmIntent
: ユーザーにインテントの了承または拒否を確認する。- 例:「注文しますか?」という質問に対し、「はい」または「いいえ」で回答を求める場合。
Delegate
: 次のアクションをLexボットの設定に基づいて自動的に決定する。- 例:ボットの設定に従って、スロット値の引き出しや確認プロンプトなどを自動的に行う場合。
ElicitIntent
: ユーザーからインテントを引き出す。- 例:ユーザーの意図が不明確で、新たなインテントの発話を促す場合。
ElicitSlot
: ユーザーから特定のスロット値を引き出す。- 例:「ピザのサイズを教えてください」と尋ね、ユーザーからサイズの情報を収集する場合。
ボットがユーザーとのやり取りで次に実行するアクションの例として、ConfirmIntent
を詳しく見てみましょう。
- 前提条件
- 全てのスロットが正常に入力されている
ConfirmIntent
アクションの実行- 確認プロンプトがユーザーに返される
- 例:「ヒライ ユウジでよろしいでしょうか?」
- この時点でのtypeとstateの値
- dialogActionのtype:
ConfirmIntent
- 理由:ユーザーに確認を求めているため
- インテントのstate:
InProgress
- 理由:確認が完了しておらず、インテントの処理がまだ進行中であるため
- dialogActionのtype:
- 次のステップ
- ユーザーの回答(「はい」または「いいえ」)を待つ
- 回答に基づいて、インテントの処理を続行または中断する
このConfirmIntent
アクションは、ユーザーの意図を再確認し、誤操作や誤解を防ぐ重要な役割を果たします。
{
"timestamp": "2024-07-08T22:56:23.880Z",
"messages": [
{
"contentType": "PlainText",
"content": "ヒライ ユウジでよろしいでしょうか?"
}
],
"messageVersion": "2.0",
"sessionId": "540835513398979",
"dialogEventLogs": [
{
"nextStep": {
"dialogAction": {
"type": "ConfirmIntent"
}
},
"dialogStepLabel": "Intent/yes/Slot/first_name/Success"
}
],
"requestId": "35df7df6-1e00-4362-9288-8a65c88bea83",
"isTestWorkbenchTraffic": false,
"inputMode": "Text",
"operationName": "RecognizeText",
"interpretations": [
{
"intent": {
"name": "yes",
"state": "InProgress",
"confirmationState": "None",
"slots": {
"last_name": {
"value": {
"originalValue": "ヒライ",
"interpretedValue": "ヒライ",
"resolvedValues": []
},
"shape": "Scalar"
},
"first_name": {
"value": {
"originalValue": "ユウジ",
"interpretedValue": "ユウジ",
"resolvedValues": []
},
"shape": "Scalar"
}
}
},
"interpretationSource": "Lex"
},
{
"intent": {
"name": "FallbackIntent",
"slots": {}
},
"interpretationSource": "Lex"
},
{
"nluConfidence": "0.36",
"intent": {
"name": "no",
"slots": {}
},
"interpretationSource": "Lex"
}
],
"developerOverride": false,
"bot": {
"name": "cm-hirai-yes-or-no",
"version": "DRAFT",
"id": "W2GNJPPTAK",
"aliasName": "TestBotAlias",
"aliasId": "TSTALIASID",
"localeId": "ja_JP"
},
"sessionState": {
"sessionAttributes": {},
"intent": {
"name": "yes",
"state": "InProgress",
"confirmationState": "None",
"slots": {
"last_name": {
"value": {
"originalValue": "ヒライ",
"interpretedValue": "ヒライ",
"resolvedValues": []
},
"shape": "Scalar"
},
"first_name": {
"value": {
"originalValue": "ユウジ",
"interpretedValue": "ユウジ",
"resolvedValues": []
},
"shape": "Scalar"
}
}
},
"dialogAction": {
"type": "ConfirmIntent"
},
"originatingRequestId": "746d936b-d369-4aa0-833f-4e8b297ddcad"
},
"inputTranscript": "ヒライ",
"missedUtterance": false,
"utteranceContext": {}
}
ユーザーが「はい」と回答した場合、次のようになります
- dialogActionのtype
- 値:
Close
- 理由:確認が完了し、次のアクションが不要なため
- 値:
- インテントのstate
- 値:
ReadyForFulfillment
- 理由:確認が完了し、インテント実行の準備が整ったため
- 値:
この状態は、ユーザーの確認が得られ、インテントの実行準備が完了したことを示しています。次のステップでは、設定されたフルフィルメントアクション(例:Lambda関数の呼び出し)が実行されるか、もしくはインテントが完了したとみなされます。
{
"timestamp": "2024-07-08T22:56:25.674Z",
"messageVersion": "2.0",
"sessionId": "540835513398979",
"dialogEventLogs": [
{
"nextStep": {
"dialogAction": {
"type": "EndConversation"
}
},
"dialogStepLabel": "Intent/yes/ConfirmIntent/Success"
}
],
"requestId": "d51fec37-7586-43d1-bcf2-a09e047145b6",
"isTestWorkbenchTraffic": false,
"inputMode": "Text",
"operationName": "RecognizeText",
"interpretations": [
{
"nluConfidence": "1.00",
"intent": {
"name": "yes",
"state": "ReadyForFulfillment",
"confirmationState": "Confirmed",
"slots": {
"last_name": {
"value": {
"originalValue": "ヒライ",
"interpretedValue": "ヒライ",
"resolvedValues": []
},
"shape": "Scalar"
},
"first_name": {
"value": {
"originalValue": "ユウジ",
"interpretedValue": "ユウジ",
"resolvedValues": []
},
"shape": "Scalar"
}
}
},
"interpretationSource": "Lex"
},
{
"intent": {
"name": "FallbackIntent",
"slots": {}
},
"interpretationSource": "Lex"
},
{
"nluConfidence": "0.15",
"intent": {
"name": "no",
"slots": {}
},
"interpretationSource": "Lex"
}
],
"developerOverride": false,
"bot": {
"name": "cm-hirai-yes-or-no",
"version": "DRAFT",
"id": "W2GNJPPTAK",
"aliasName": "TestBotAlias",
"aliasId": "TSTALIASID",
"localeId": "ja_JP"
},
"sessionState": {
"sessionAttributes": {},
"dialogAction": {
"type": "Close"
},
"intent": {
"name": "yes",
"state": "ReadyForFulfillment",
"confirmationState": "Confirmed",
"slots": {
"last_name": {
"value": {
"originalValue": "ヒライ",
"interpretedValue": "ヒライ",
"resolvedValues": []
},
"shape": "Scalar"
},
"first_name": {
"value": {
"originalValue": "ユウジ",
"interpretedValue": "ユウジ",
"resolvedValues": []
},
"shape": "Scalar"
}
}
},
"originatingRequestId": "746d936b-d369-4aa0-833f-4e8b297ddcad"
},
"inputTranscript": "はい",
"missedUtterance": false,
"utteranceContext": {}
}
分析:インテント
ここからは、Amazon Lexの分析機能におけるインテント、スロット、会話、発話の分類方法について詳しく解説します。
まず、インテント(Intent)の分析では、以下の4つのカテゴリーに分類されます
- 成功(Success)
- 定義:Lexボットがインテントを正常に実行完了した状態。
- 例1:インテントのstateが
ReadyForFulfillment
で、dialogActionのtypeがClose
。これは確認が完了した場合に該当します。 - 例2:インテントのstateが
Fulfilled
で、dialogActionのtypeがClose
。これはインテントを達成(実行完了)し、終了応答まで終了した場合を示します。
- 失敗(Failed)
- 定義:Lexボットがインテントの実行を完了できなかった状態。
- 例1:インテントのstateが
Failed
で、dialogActionのtypeがClose
の場合。これはユーザーが確認で拒否した場合などに発生します。 - 例2:特定のインテントから
AMAZON.FallbackIntent
に切り替わった場合。これは元のインテントが適切に処理できなかったことを示します。
- 切り替え(Switched)
- 定義:Lexボットが元のインテントの処理中に別のインテントを認識し、そちらに切り替えた状態。
- 例1:ピザ注文インテント中に、ユーザーが「注文をキャンセルしたい」と言い、キャンセルインテントに切り替わる場合。
- 除外(Dropped)
- 定義:インテントの処理が完了する前にセッションが終了した状態。
- 例1:アイドルセッションタイムアウトを超えてもユーザーが応答しない
これらの分類は、ボットのパフォーマンスを評価し、ユーザーとの対話の質を向上させるための重要な指標となります。各カテゴリーの発生率や傾向を分析することで、ボットの改善点を特定し、より効果的な対話システムを構築することができます。
分析:スロット
Amazon Lexの分析機能では、スロット(Slot)の処理結果を以下の3つのカテゴリーに分類します
-
成功(Success)
- 定義:ユーザーの応答によりスロットが正常に埋まった状態。
- 特徴
- スロット値が正常に取得される。
- 次のスロットまたは確認ステップに正常に移行する。
- 例:ピザのサイズを尋ねられ、ユーザーが「Mサイズ」と回答し、次の質問に進む。
-
失敗(Failed)
- 定義:設定された再試行回数内にスロットを埋めることができなかった状態。
- 特徴
- 再試行回数が上限に達する。
- 有効なスロット値が取得できない。
- 例:ピザのサイズを3回尋ねても、有効な回答(S、M、Lなど)が得られない場合。
-
除外(Dropped)
- 定義:スロットの処理が完了する前にセッションが終了した状態。
- 特徴
- アイドルセッションタイムアウトを超えても、ユーザーからの応答がない。
- 別のインテントに切り替わらない。
- 例:ピザのサイズを尋ねた後、ユーザーが5分間応答せず、セッションがタイムアウトする。
分析:会話
Amazon Lexにおける「会話」とは、ボットが呼び出されてから終了するまでの一連のやりとりを指します。会話の分析を理解するには、「セッション」と「会話」に関する以下の重要な概念を把握する必要があります
-
セッションと会話の識別
sessionId
: ユーザーとボットの対話セッションを識別するID。originatingRequestId
: Lexが生成する、リクエストを識別するID。セッションタイムアウト内では同じ値が維持され、タイムアウト後に同じsessionId
で再開した場合に新しい値が生成されます。会話
:sessionId
とoriginatingRequestId
の一意の組み合わせによって定義されます。
-
セッションの流れ
a. 会話開始:- ユーザーがLexを呼び出すと、新しい
sessionId
が生成され、Amazon Lex V2がoriginatingRequestId
を生成します。
b. 会話継続:
- セッションタイムアウト内でのやりとりでは、
sessionId
とoriginatingRequestId
は変わりません。
c. セッションタイムアウト:
- ユーザーが設定されたタイムアウト時間内に応答しない場合、セッションは終了します。
d. セッション再開:
- タイムアウト後にユーザーが同じ
sessionId
を使用してボットを呼び出すと、Amazon Lex V2が新しいoriginatingRequestId
を生成します。
- ユーザーがLexを呼び出すと、新しい
-
会話の分類
Amazon Lexは、会話を以下の3つのカテゴリーに分類します:
a. 成功(Success)- 定義:会話のインテントが正常に完了した状態。
- 例:ピザ注文の全プロセスが正常に完了し、注文が確定した場合。
b. 失敗(Failed)
- 定義:会話のインテントが失敗した状態。
AMAZON.FallbackIntent
が呼び出された場合も失敗とみなされます。 - 例:必要な情報が得られず、ピザ注文が完了できなかった場合。
c. 除外(Dropped)
- 定義:会話が成功または失敗と分類される前にセッションが終了した状態。
- 例:ピザのトッピングを聞いている途中でユーザーが応答せず、セッションがタイムアウトした場合。
これらの分類とsessionId
、originatingRequestId
の関係を理解することで、ボットの性能評価や改善点の特定が可能になります。例えば、除外(Dropped)の割合が高い場合、ユーザーエンゲージメントの問題や、セッションタイムアウトの設定が適切でない可能性が考えられます。
例として、インテントが誘発された場合、以下の通り、sessionId
とoriginatingRequestId
を生成します。
{
"timestamp": "2024-07-08T23:02:05.586Z",
"messages": [
{
"contentType": "PlainText",
"content": "名前を教えて下さい"
}
],
"messageVersion": "2.0",
"sessionId": "540835513398732",
"dialogEventLogs": [
{
"nextStep": {
"dialogAction": {
"type": "InvokeDialogCodeHook"
}
},
"dialogStepLabel": "Intent/yes/StartIntent"
},
{
"nextStep": {
"dialogAction": {
"type": "ElicitSlot",
"slotToElicit": "last_name"
}
},
"dialogStepLabel": "Intent/yes/StartIntent/CodeHook/Success"
}
],
"requestId": "5a1ca9e6-1868-4d07-acfc-26cd019221c6",
"isTestWorkbenchTraffic": false,
"inputMode": "Text",
"operationName": "RecognizeText",
"interpretations": [
{
"nluConfidence": "1.00",
"interpretationSource": "Lex",
"intent": {
"name": "yes",
"state": "InProgress",
"confirmationState": "None",
"slots": {
"last_name": null,
"first_name": null
}
}
},
{
"interpretationSource": "Lex",
"intent": {
"name": "FallbackIntent",
"slots": {}
}
},
{
"nluConfidence": "0.34",
"interpretationSource": "Lex",
"intent": {
"name": "no",
"slots": {}
}
}
],
"developerOverride": false,
"bot": {
"name": "cm-hirai-yes-or-no",
"version": "DRAFT",
"id": "W2GNJPPTAK",
"aliasName": "TestBotAlias",
"aliasId": "TSTALIASID",
"localeId": "ja_JP"
},
"sessionState": {
"sessionAttributes": {},
"dialogAction": {
"type": "ElicitSlot",
"slotToElicit": "last_name"
},
"originatingRequestId": "5a1ca9e6-1868-4d07-acfc-26cd019221c6",
"intent": {
"name": "yes",
"state": "InProgress",
"confirmationState": "None",
"slots": {
"last_name": null,
"first_name": null
}
}
},
"inputTranscript": "はい",
"missedUtterance": false,
"utteranceContext": {}
}
アイドルセッションタイムアウト5分間放置後、再度入力すると、sessionId
は同じ値ですが、originatingRequestId
の値が異なることが分かります。
{
"timestamp": "2024-07-08T23:08:28.462Z",
"messages": [
{
"contentType": "PlainText",
"content": "名前を教えて下さい"
}
],
"messageVersion": "2.0",
"sessionId": "540835513398732",
"dialogEventLogs": [
{
"nextStep": {
"dialogAction": {
"type": "InvokeDialogCodeHook"
}
},
"dialogStepLabel": "Intent/yes/StartIntent"
},
{
"nextStep": {
"dialogAction": {
"type": "ElicitSlot",
"slotToElicit": "last_name"
}
},
"dialogStepLabel": "Intent/yes/StartIntent/CodeHook/Success"
}
],
"requestId": "4ceae898-b31d-40bb-b37e-5058e711d807",
"isTestWorkbenchTraffic": false,
"inputMode": "Text",
"operationName": "RecognizeText",
"interpretations": [
{
"nluConfidence": "0.81",
"interpretationSource": "Lex",
"intent": {
"name": "yes",
"state": "InProgress",
"confirmationState": "None",
"slots": {
"last_name": null,
"first_name": {
"value": {
"originalValue": "ユウジ",
"interpretedValue": "ユウジ",
"resolvedValues": []
},
"shape": "Scalar"
}
}
}
},
{
"interpretationSource": "Lex",
"intent": {
"name": "FallbackIntent",
"slots": {}
}
},
{
"nluConfidence": "0.5",
"interpretationSource": "Lex",
"intent": {
"name": "no",
"slots": {}
}
}
],
"developerOverride": false,
"bot": {
"name": "cm-hirai-yes-or-no",
"version": "DRAFT",
"id": "W2GNJPPTAK",
"aliasName": "TestBotAlias",
"aliasId": "TSTALIASID",
"localeId": "ja_JP"
},
"sessionState": {
"sessionAttributes": {},
"originatingRequestId": "4ceae898-b31d-40bb-b37e-5058e711d807",
"intent": {
"name": "yes",
"state": "InProgress",
"confirmationState": "None",
"slots": {
"last_name": null,
"first_name": {
"value": {
"originalValue": "ユウジ",
"interpretedValue": "ユウジ",
"resolvedValues": []
},
"shape": "Scalar"
}
}
},
"dialogAction": {
"type": "ElicitSlot",
"slotToElicit": "last_name"
}
},
"inputTranscript": "ユウジ",
"missedUtterance": false,
"utteranceContext": {}
}
分析:発話
Amazon Lexの分析機能において、発話(Utterance)は、ユーザーがボットに対して行う入力のうち、インテントを誘発する可能性のある言葉や文を指します。これらの発話は、ボットのインテント認識能力を評価する上で重要な指標となります。
分析では、発話は以下の2つのカテゴリーに分類されます
- 検出(Detected)/ 検出された発話(Detected utterances)
- 定義:Lexがボットに設定されたインテントを正しく認識し、誘発できた発話。
- 例:「ピザを注文したい」という発話が「ピザ注文」インテントを正しく誘発した場合。
- 未検出(Missed)/ 見逃された発話(Missed utterances)
- 定義:Lexが誘発するインテントを認識できなかった発話。
- 例:「ピザを注文したい」という発話が「ピザ注文」インテントを正しく誘発できなかった場合。
最後
本記事では、Amazon Lexの分析機能を理解する上で重要な4つの用語(インテント、スロット、会話、発話)について解説しました。これらの概念を理解することで、Lexの分析機能をより効果的に活用し、ボットのパフォーマンスを適切に評価・改善することができます。
分析機能を活用する際は、これらの用語とその関係性を十分に理解した上で取り組むことをお勧めします。
参考になれば幸いです。
参考