Share via


会話言語理解のベスト プラクティス

会話言語理解で可能な限り最適なプロジェクトを作成するには、次のガイドラインのようにしてください。

一貫性のあるスキーマを選択する

スキーマは、意図とエンティティの定義です。 意図とエンティティでは、作成する必要があるものを定義するときに使用できるアプローチが異なります。 確認する必要がある質問がいくつかあります。

  • ユーザーからどのようなアクションやクエリをキャプチャしようとしているのか?
  • 各アクションにはどのような情報が関連するのか?

通常、アクションとクエリは "意図" と考えることができるのに対し、それらのクエリを実行するために必要な情報は "エンティティ" と見なすことができます。

たとえば、自分が提供するさまざまな製品のサブスクリプションを、顧客がチャットボットで取り消せるようにするとします。 "Contoso サービスを取り消す" や "Fabrikam サブスクリプションの課金を停止する" などのさまざまな例を使って、"取り消す" 意図を作成できます。ここでのユーザーの意図は "取り消す" ことであり、"Contoso サービス" や "Fabrikam サブスクリプション" は取り消したいサブスクリプションです。 そのため、"サブスクリプション" のエンティティを作成できます。 次に、プロジェクト全体をモデル化して、アクションを意図としてキャプチャし、エンティティを使ってそれらのアクションを入力できます。 これにより、エンティティとして定義したすべてのもの (他の製品など) を取り消すことができます。 その後は、"サブスクリプション" や他のエンティティを利用するサインアップ、更新、アップグレードなどの意図を作成できます。

上のスキーマ設計により、新しいエンティティを作成することで、既存の機能 (取り消し、アップグレード、サインアップ) を新しいターゲットに簡単に拡張できます。

もう 1 つの方法は、"情報" を意図としてモデル化し、"アクション" をエンティティとしてモデル化することです。 顧客がチャットボットでサブスクリプションを取り消せるようにする同じ例を使って見てみましょう。 "Contoso を取り消す"、"Contoso サービスの課金を停止する"、"Contoso サブスクリプションをキャンセルする" のような発話での Contoso など、利用できる各サブスクリプションに対する意図を作成できます。その後、アクション "取り消す" をキャプチャするためのエンティティを作成します。アクションごとに異なるエンティティを定義するか、リスト コンポーネントを使ってアクションを 1 つのエンティティとして統合し、異なるキーでアクションを区別することができます。

このスキーマ設計を使うと、新しいアクション エンティティまたはエンティティ コンポーネントを追加することで、新しいアクションを既存のターゲットに簡単に拡張できます。

すべての概念を意図だけにまとめようとしないでください。たとえば、"Contoso を取り消す" 意図のように、その 1 つの特定のアクションの目的のみを持つ意図を作成しようとしないでください。 意図とエンティティが連携して、顧客から必要なすべての情報をキャプチャする必要があります。

また、異なるスキーマ設計を混在させるのを避ける必要もあります。 アプリケーションの半分を意図としてのアクションで作成し、残りの半分を意図としての情報で作成しないでください。 可能な結果を得るには一貫性があるようにします。

トレーニング データのバランスを取る

トレーニング データについては、常にスキーマのバランスを整えてることを心がけてください。 ある意図を大量に含めて、別の意図をほとんど含めない場合、特定の意図に大きく偏ったモデルが生成されます。

これに対処するには、トレーニング セットをダウンサンプリングするか、そこに追加する必要があります。 ダウンサンプリングは、次のいずれかの方法で行うことができます。

  • トレーニング データの一定割合をランダムに取り除く。
  • より体系的な方法でデータセットを分析し、過剰な重複エントリを削除する。

また、Language Studio の [データのラベル付け] タブで [Suggest Utterances] (発話の提案) を選んでトレーニング セットに追加することもできます。 会話言語理解から Azure OpenAI に呼び出しが送信され、似た発話が生成されます。

Language Studio の発話の提案を示すスクリーンショット。

また、トレーニング セットで意図しない "パターン" を探す必要もあります。 たとえば、特定の意図のトレーニング セットがすべて小文字の場合、または特定の語句で始まる場合です。 このような場合、トレーニングするモデルは、一般化することができず、トレーニング セットでこのような意図しない偏りを学習する可能性があります。

トレーニング セットには、大文字と小文字の区別と、句読点の多様性を導入することをお勧めします。 バリエーションの処理を想定しているモデルの場合は、必ずその多様性も反映するトレーニング セットを用意してください。 たとえば、大文字と小文字が正しい発話だけでなく、すべて小文字のものも含めます。

発話に明確にラベルを付ける

  • エンティティが参照する概念が明確に定義され、分離可能であることを確かめます。 確実に違いを簡単に特定できるかどうかを確認します。 できない場合は、学習済みコンポーネントでも困難であることを示している可能性があります。

  • エンティティ間に類似点がある場合は、それらの違いのシグナルを提供するデータの一部の側面があることを確かめます。

    たとえば、フライトを予約するモデルを構築した場合、ユーザーは "I want a flight from Boston to Seattle" のような発話を使用することがあります。このような発話の "出発地" と "目的地" は似ていることが予想されます。 "出発地" を区別するためのシグナルは、多くの場合、"from" という単語の前に置かれる可能性があります。

  • 必ず、トレーニングとテスト データの両方で、各エンティティのすべてのインスタンスにラベルを付けてください。 1 つの方法は、検索機能を使用して、データ内の単語または語句のすべてのインスタンスを見つけ、正しいラベルが付けられているかどうかを確認することです。

  • 学習済みコンポーネントがないエンティティと、あるエンティティのテスト データにラベルを付けます。 これは、評価メトリックが正確であることを確かめるのに役立ちます。

高度なトレーニングの前に標準トレーニングを使用する

標準トレーニングは無料で、高度なトレーニングより高速なので、モデルの構築中にトレーニング セットまたはスキーマを変更した場合の影響をすばやく理解するのに役立ちます。 スキーマに問題がなければ、高度なトレーニングを使用してモデルから最適な AIQ を取得することを検討します。

評価機能を使用する

アプリを構築するときは、エラーを早い段階で見つけると役に立つことがよくあります。 トレーニングと評価の結果はスキーマ内のエラーや問題を特定するのに非常に役立つので、通常はアプリの構築時にテスト セットを追加することをお勧めします。

機械学習のコンポーネントと構成

コンポーネントの種類」をご覧ください。

"none" スコアしきい値の使用

コンテキスト外の発話が有効な意図としてマークされるなど、擬陽性が多すぎる場合は、それが推論に与える影響について詳しくは、信頼度のしきい値に関する記事をご覧ください。

  • リストや正規表現などの機械学習されていないエンティティ コンポーネントは、定義上コンテキストではありません。 意図しない場所にリスト エンティティまたは正規表現エンティティが表示される場合は、機械学習コンポーネントとしてリスト同意語にラベルを付けてみてください。

  • エンティティの場合は、学習済みのコンポーネントを "必須" コンポーネントとして使用して、構成済みエンティティを起動するタイミングを制限できます。

たとえば、"Book two tickets tomorrow to Cairo" (カイロ行のチケットを 2 枚予約する) といった発話のため、フライトで予約するチケットの数を抽出する "ticket quantity" (チケット枚数) というエンティティがあるとします。

通常は、発話に含まれるすべての数値を既に抽出するようになっている Quantity.Number 用の事前構築済みコンポーネントを追加します。 ただし、エンティティが事前構築済みのコンポーネントだけで定義されている場合は、"Book two tickets tomorrow to Cairo at 3 PM." (午後 3 時のカイロ行のチケットを 2 枚予約する。) のように、ticket quantity エンティティの一部として他の数値も抽出されます。

これを解決するには、トレーニング データで ticket quantity を意味するすべての数値に学習済みコンポーネントのラベルを付けます。 エンティティには、次の 2 つのコンポーネントが含まれるようになりました:

  • すべての数値を解釈できる事前構築済みコンポーネント
  • 文内で ticket quantity の場所を予測する学習済みコンポーネント。

学習済みコンポーネントが必要な場合は、学習済みコンポーネントが正しいコンテキストでそれを予測したときにのみ、ticket quantity が返されるようにします。 事前構築済みコンポーネントも必要な場合は、返される ticket quantity エンティティが数値と正しい位置の両方であるようにすることができます。

大文字と小文字の不整合に対処する

AI の品質が低く、トレーニング データで使用される大文字と小文字がテスト データと異なると判断した場合は、normalizeCasing プロジェクト設定を使用できます。 これにより、モデルのトレーニング時とテスト時に発話の大文字と小文字が正規化されます。 LUIS から移行した場合、LUIS が既定でこれを行ったことがわかる場合があります。

{
  "projectFileVersion": "2022-10-01-preview",
    ...
    "settings": {
      "confidenceThreshold": 0.5,
      "normalizeCasing": true
    }
...

モデルの過信への対処

お客様は、モデルが誤って過信されている場合に備えて、LoraNorm レシピ バージョンを使用できます。 この例を次に示します (モデルでは、100% の信頼度で正しくない意図が予測されることに注意してください)。 これにより、信頼度しきい値のプロジェクト設定を使用できなくなります。

Text 予測された意図 信頼度スコア
"Who built the Eiffel Tower?" (エッフェル塔を建てたのは誰?) Sports 1.00
"Do I look good to you today?" (今日の私はいい感じに見える?) QueryWeather 1.00
"I hope you have a good evening." (よい夜を過ごせるよう願っています。) Alarm 1.00

これに対処するには、信頼度スコアを正規化する 2023-04-15 構成バージョンを使用します。 その後、信頼度しきい値プロジェクト設定を調整して、目的の結果を得ることができます。

curl --location 'https://<your-resource>.cognitiveservices.azure.com/language/authoring/analyze-conversations/projects/<your-project>/:train?api-version=2022-10-01-preview' \
--header 'Ocp-Apim-Subscription-Key: <your subscription key>' \
--header 'Content-Type: application/json' \
--data '{
      "modelLabel": "<modelLabel>",
      "trainingMode": "advanced",
      "trainingConfigVersion": "2023-04-15",
      "evaluationOptions": {
            "kind": "percentage",
            "testingSplitPercentage": 0,
            "trainingSplitPercentage": 100
      }
}

要求が送信されたら、通常どおり Language Studio でトレーニング ジョブの進行状況を追跡できます。

Note

confidenceThreshold プロジェクト設定を更新した後、モデルを再トレーニングする必要があります。 その後、新しいしきい値を有効にするには、アプリを再発行する必要があります。

モデル バージョン 2023-04-15 での正規化

モデル バージョン 2023-04-15 の会話言語理解では、トレーニングに影響を与えない推論レイヤーで正規化が提供されています。

正規化レイヤーでは、分類の信頼度スコアが制限された範囲に正規化されます。 現在選択されている範囲は [-a,a] であり、"a" は意図の数の平方根です。 その結果、正規化はアプリ内の意図の数に依存します。 意図の数が非常に少ない場合、正規化レイヤーの動作範囲は非常に小さくなります。 意図の数かなり多い場合は、正規化がいっそう効果的になります。

この正規化が、信頼度しきい値を使用してスコープ外の発話をフィルター処理できる範囲に対してスコープ外である意図に役に立たないと思われる場合は、アプリ内の意図の数に関連している可能性があります。 アプリにさらに意図を追加することを検討するか、オーケストレーションされたアーキテクチャを使用している場合は、同じドメインに属するアプリをマージしてまとめることを検討してください。

構成済みエンティティのデバッグ

エンティティは、関連付けられた型を持つ入力のスパンを出力する関数です。 関数は、1 つ以上のコンポーネントによって定義されます。 コンポーネントを必要に応じてマークし、"コンポーネントの結合" 設定を有効にするかどうかを決定できます。 コンポーネントを結合すると、重複するすべてのスパンが 1 つのスパンにマージされます。 この設定を使わないと、個々のコンポーネントのスパンが出力されます。

個々のコンポーネントのパフォーマンスを理解するには、この設定を無効にし、各コンポーネントを "不要" に設定できます。 これにより、出力される個々のスパンを検査し、問題のあるコンポーネントのみが生成されるようにコンポーネントの削除を試すことができます。

複数のテスト セットを使用してモデルを評価する

会話言語理解プロジェクトのデータには、2 つのデータ セットを含めることができます。 "テスト" セットと "トレーニング" セットです。 複数のテスト セットを使ってモデルを評価したい場合は、次のようにします:

  • テスト セットに異なる名前を付けます ("test1" や "test2" など)。
  • プロジェクトをエクスポートして、パラメーターと構成を含む JSON ファイルを取得します。
  • JSON を使用して新しいプロジェクトをインポートし、2 番目の目的のテスト セットの名前を "test" に変更します。
  • 2 番目のテスト セットを使用して評価を実行するようにモデルをトレーニングします。

ターゲット アプリと子アプリのカスタム パラメーター

オーケストレーションされたアプリを使用している場合、さまざまな子アプリに対してカスタム パラメーターのオーバーライドを送信したい場合があります。 targetProjectParameters フィールドを使用すると、ユーザーは各ターゲット プロジェクトのパラメーターを表す辞書を送信できます。 たとえば、CLU1 という名前の会話言語理解アプリと CQA1 という名前のカスタム質問応答アプリの間でオーケストレーションを行う Orchestrator という名前のオーケストレーター アプリについて考えます。 質問応答アプリに "top" という名前のパラメーターを送信する場合は、上記のパラメーターを使用できます。

curl --request POST \
   --url 'https://<your-language-resource>.cognitiveservices.azure.com/language/:analyze-conversations?api-version=2022-10-01-preview' \
   --header 'ocp-apim-subscription-key: <your subscription key>' \
   --data '{
     "kind": "Conversation",
     "analysisInput": {
         "conversationItem": {
             "id": "1",
             "text": "Turn down the volume",
             "modality": "text",
             "language": "en-us",
             "participantId": "1"
         }
     },
     "parameters": {
         "projectName": "Orchestrator",
         "verbose": true,
         "deploymentName": "std",
         "stringIndexType": "TextElement_V8",
"targetProjectParameters": {
            "CQA1": {
                "targetProjectKind": "QuestionAnswering",
                "callingOptions": {
                    "top": 1
                }
             }
         }
     }
 }'

言語リソース間でプロジェクトをコピーする

多くの場合、Azure Language Studio のコピー ボタンを使用して、会話言語理解プロジェクトをあるリソースから別のリソースにコピーできます。 ただし、場合によっては、API を使用してプロジェクトをコピーする方が簡単な場合があります。

まず、次の情報を特定します。

  • ソース プロジェクト名
  • ターゲット プロジェクト名
  • ソース言語リソース
  • ターゲット言語リソースのコピー先の場所。

API を呼び出してコピー アクションを承認し、後で実際のコピー操作の accessTokens を取得します。

curl --request POST \ 
  --url 'https://<target-language-resource>.cognitiveservices.azure.com//language/authoring/analyze-conversations/projects/<source-project-name>/:authorize-copy?api-version=2023-04-15-preview' \ 
  --header 'Content-Type: application/json' \ 
  --header 'Ocp-Apim-Subscription-Key: <Your-Subscription-Key>' \ 
  --data '{"projectKind":"Conversation","allowOverwrite":false}' 

API を呼び出してコピー操作を完了します。 前に取得した応答をペイロードとして使用します。

curl --request POST \ 
  --url 'https://<source-language-resource>.cognitiveservices.azure.com/language/authoring/analyze-conversations/projects/<source-project-name>/:copy?api-version=2023-04-15-preview' \ 
  --header 'Content-Type: application/json' \ 
  --header 'Ocp-Apim-Subscription-Key: <Your-Subscription-Key>\ 
  --data '{ 
"projectKind": "Conversation", 
"targetProjectName": "<target-project-name>", 
"accessToken": "<access-token>", 
"expiresAt": "<expiry-date>", 
"targetResourceId": "<target-resource-id>", 
"targetResourceRegion": "<target-region>" 
}'

ドメイン外の発話への対処

モデルの AIQ がドメイン外の発話で不適切な場合、お客様は新しいレシピ バージョン '2024-06-01-preview' を使用できます。 既定のレシピを使用した例は次のようになります。モデルには Sports、QueryWeather、Alarm という 3 つの意図があります。 テスト発話はドメイン外の発話であり、モデルによって、比較的高い信頼度スコアを持つ InDomain として分類されます。

Text 予測された意図 信頼度スコア
"Who built the Eiffel Tower?" (エッフェル塔を建てたのは誰?) Sports 0.90
"Do I look good to you today?" (今日の私はいい感じに見える?) QueryWeather 1.00
"I hope you have a good evening." (よい夜を過ごせるよう願っています。) Alarm 0.80

これに対処するには、ドメイン内発話の品質を適度に維持しながらこの問題に対処するために、特別に構築された 2024-06-01-preview 構成バージョンを使用します。

curl --location 'https://<your-resource>.cognitiveservices.azure.com/language/authoring/analyze-conversations/projects/<your-project>/:train?api-version=2022-10-01-preview' \
--header 'Ocp-Apim-Subscription-Key: <your subscription key>' \
--header 'Content-Type: application/json' \
--data '{
      "modelLabel": "<modelLabel>",
      "trainingMode": "advanced",
      "trainingConfigVersion": "2024-06-01-preview",
      "evaluationOptions": {
            "kind": "percentage",
            "testingSplitPercentage": 0,
            "trainingSplitPercentage": 100
      }
}

要求が送信されたら、通常どおり Language Studio でトレーニング ジョブの進行状況を追跡できます。

注意事項:

  • このレシピを使用する場合、アプリの None スコアしきい値 (topIntent が None としてマークされている信頼度しきい値を下回る) を 0 に設定する必要があります。 これは、この新しいレシピでは、モデルがドメイン内発話について誤って過信しないように、ドメイン内確率の特定の部分をドメイン外に帰属させるためです その結果、ユーザーは、prod レシピと比較して、ドメイン発話の信頼度スコアがわずかに低下する可能性があります。
  • このレシピは、IntentA や None など、2 つの意図のみを持つアプリには推奨されません。
  • このレシピは、意図ごとの発話数が少ないアプリには推奨されません。 意図ごとに少なくとも 25 個の発話を使用することを強くお勧めします。