对话语言理解的最佳做法

使用以下准则创建对话语言理解方面可能的最佳项目。

选择一致的架构

架构是意向和实体的定义。 定义应创建的意向与实体时,可以采用不同的方法。 询问自己以下问题:

  • 我要尝试从用户捕获哪些操作或查询?
  • 每个操作中有哪些信息是相关的?

通常可以将操作和查询视为“意向”,而满足这些查询所需的信息为“实体”

例如,假设你希望客户取消通过聊天机器人提供的各种产品的订阅。 可以使用各种示例创建“取消”意向,例如“取消 Contoso 服务”,或“停止向我收取 Fabrikam 订阅的费用”。用户在此处的意向是“取消”,而“Contoso 服务”或“Fabrikam 订阅”是他们想要取消的订阅

若要继续,请为订阅创建实体。 然后,可以对整个项目建模,以将操作捕获为意向,并使用实体填充这些操作。 这样就可以取消定义为实体的任何内容,例如其他产品。 然后,可以有注册、续订、升级的意向,这些意向都使用“订阅”和其他实体

使用上述架构设计,可以通过创建新实体轻松地将现有功能(取消、升级、注册)扩展到新目标。

另一种方法是将“信息”建模为意向,将“行为”建模为实体。 让我们以同样的例子为例,允许客户通过聊天机器人取消订阅。

可以为每个可用的订阅创建一个意向,例如“Contoso”,其中包含“取消 Contoso”、“停止向我收取 contoso 服务费用”和“取消 Contoso 订阅”等语句。然后创建一个实体来捕获“取消”操作。 可以为每个操作定义不同的实体,也可以使用列表组件将操作合并为一个实体,以区分具有不同键的操作。

使用此架构设计,可以通过添加新操作实体或实体组件,轻松地将新操作扩展到现有目标。

确保避免尝试将所有概念汇集到意向中。 例如,不要尝试创建仅具有该特定操作目的的“取消 Contoso”意向。 意向和实体应协同工作,以捕获客户所需的所有信息。

你还希望避免混合不同的架构设计。 不要将操作作为意向构建一半的应用程序,将信息作为意向构建另一半应用程序。 确保其一致性以获得可能的结果。

平衡训练数据

在训练数据方面,应尽量保持架构均衡。 如果具有大量某一个意向,而只有极少数另一个意向,则会导致模型严重偏向于特定意向。

若要解决此问题,可能需要缩减训练集样本。 或者可能需要补充训练集样本。 若要缩减采样,可以:

  • 随机删除特定百分比的训练数据。
  • 分析数据集并删除过多的重复条目,这是一种更系统的方式。

若要补充训练集,请在 Language Studio 中的“数据标签”选项卡上选择“建议语句”

显示 Language Studio 中的语句建议的屏幕截图。

还应在训练集中查找意外的“模式”。 例如,检查特定意向的训练集是否全为小写,或以特定短语开头。 在这种情况下,训练的模型可能会学习训练集中的这些意外偏差,而不是变得通用化。

建议在训练集中引入大小写和标点符号多样性。 如果期望模型预期处理变体,请确保有一个也反映这种多样性的训练集。 例如,添加一些采用正确大小写的语句,再添加一些全部小写的语句。

清楚地标记语句

  • 确保实体引用的概念定义清晰且可分离。 检查是否可以轻松可靠地确定差异。 否则,不区分大小写可能表明习得的组件也会遇到问题。

  • 如果实体之间存在相似性,请确保数据的某些方面提供了它们之间的差异标志。

    例如,如果你生成了一个模型来预订航班,用户可能会使用此类语句:“我想要预订从波士顿飞往西雅图的航班。”此类语句的“出发地城市”和“目的地城市”应该类似。 区分“出发地城市”的一个信号可能是,它的前面经常出现“从”一词

  • 确保在训练数据和测试数据中标记每个实体的所有实例。 一种方法是使用搜索函数查找数据中某个字词或短语的所有实例,以检查是否正确标记。

  • 为没有习得组件的实体标记测试数据,同时也为具有习得组件的实体标记测试数据。 这种做法有助于确保评估指标准确。

先使用标准训练,再使用高级训练

标准训练是免费的,而且比高级训练更快。 它可以帮助你在生成模型时快速了解更改训练集或架构的效果。 对架构感到满意后,请考虑使用高级训练以获取最佳模型质量。

使用评估功能

生成应用时,尽早发现错误通常会很有帮助。 在生成应用时添加测试集通常是良好的做法。 训练和评估结果有助于识别架构中的错误或问题。

机器学习组件和组合

有关详细信息,请参阅组件类型

使用 None 分数阈值

如果看到过多的误报,例如将非上下文语句标记为有效意向,请参阅置信度阈值,了解它如何影响推理。

  • 非机器学习实体组件(如列表和正则表达式)是依据定义而不是上下文。 如果在意外的位置看到列表或正则表达式实体,请尝试将列表同义词标记为机器学习组件。
  • 对于实体,可以使用习得组件作为“必需”组件,以限制应何时触发组合实体。

例如,假设有名为“机票数量”的实体,它尝试在诸如“预订两张明天飞往开罗的机票”这样的语句中提取要为预订航班预留的机票数量

通常你会为已提取语句中所有数字的 Quantity.Number 添加预生成组件。 但是,如果实体仅由预生成组件定义,它还将提取其他数字作为“机票数量”实体的一部分,例如“预订两张明天下午 3 点飞往开罗的机票”

若要解决此问题,请在训练数据中为所有应该是“机票数量”的数字标记习得组件。 实体现在有两个组件:

  • 可以解释所有数字的预生成组件。
  • 可以预测句子中机票数量所在位置的习得组件。

如果需要习得组件,请确保只有当习得组件在正确的上下文中预测机票数量时,才会返回“机票数量”。 如果还需要预生成组件,那么可以保证返回的“机票数量”实体既是数字又位于正确的位置

解决模型不一致问题

如果模型对小型语法更改过于敏感,例如大小写或变音符号,则可以直接在 Language Studio 中系统地操作数据集。 若要使用这些功能,请选择左侧窗格中的“设置”选项卡,找到“高级项目设置”部分

显示“高级项目设置”示例的屏幕截图。

首先,可以启用“启用大小写数据转换”设置,以便在训练、测试和实现模型时规范化语句的大小写。 如果你是从 LUIS 迁移过来的,则可能会发现 LUIS 默认执行此规范化操作。 若要通过 API 访问此功能,请将 normalizeCasing 参数设置为 true。 请参阅以下示例:

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

其次,还可以启用“启用变音符号数据扩充”设置,以生成训练数据的变体,从而适应自然语言中可能使用的变音符号变体。 此功能适用于所有语言。 它特别适用于德语和斯拉夫语言,其用户通常使用经典英语字符而不是正确的字符来编写单词。 例如,法语中的短语“导航到体育频道”是“Accédez à la chaîne sportive”。启用此功能后,短语“Accedez a la chaine sportive”(不含变音字符)也会包含在训练数据集中。

如果启用此功能,训练集的语句数量将会增加。 因此,可能需要相应地调整训练数据的大小。 扩充后的当前最大言语计数为 25,000。 若要通过 API 访问此功能,请将 augmentDiacritics 参数设置为 true。 请参阅以下示例:

{
  "projectFileVersion": "2022-10-01-preview",
    ...
    "settings": {
      ...
      "augmentDiacritics": true
      ...
    }
...

解决模型置信度过高的问题

如果模型置信度过高,客户可使用 LoraNorm 训练配置版本。 以下场景就是这种行为的一个示例,其中的模型以 100% 的置信度预测错误的意向。 此分数使得置信度阈值项目设置不可用。

文本 预测意向 置信度分数
“谁建造了埃菲尔铁塔?” Sports 1.00
“今天你觉得我好看吗?” QueryWeather 1.00
“我希望你有一个美好的夜晚。” Alarm 1.00

若要解决此问题,请使用 2023-04-15 配置版本来规范置信度分数。 然后,可以调整置信度阈值项目设置以实现所需的结果。

curl --location 'https://<your-resource>.cognitiveservices.azure.cn/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 中跟踪训练作业的进度。

注意

在更新 confidenceThreshold 项目设置后必须重新训练模型。 之后,需要重新发布应用才能使新阈值生效。

模型版本 2023-04-15 中的规范化

模型版本 2023-04-15 对话语言理解在不影响训练的推理层中提供规范化。

规范化层将分类置信度分数规范化为受限范围。 当前选择的范围来自 [-a,a],其中“a”是意向数的平方根。 因此,规范化取决于应用中的意向数。 如果意向数很小,则规范化层要处理的范围也很小。 如果意向数很大,规范化将更为有效。

如果这种规范化对范围以外的意向的帮助程度似乎不足以使用置信度阈值来筛选超出范围的话语,则它可能与应用中的意向数有关。 请考虑向应用添加更多意向。 或者,如果使用经协调的体系结构,请考虑将属于同一域的应用合并在一起。

调试组合实体

实体是可发出输入中具有关联类型的跨度的函数。 有一个或多个组件会定义函数。 可以根据需要标记组件,并决定是否启用“合并组件”设置。 合并组件时,重叠的所有跨度都将合并为单个跨度。 如果未使用该设置,将发出每个单独组件跨度。

若要更好地了解各个组件的性能,可以禁用设置并将每个组件设置为“不需要”。 此设置使你可以检查发出的单独跨度,并尝试删除组件,以便只生成有问题的组件。

使用多个测试集评估模型

对话语言理解项目中的数据可以有两个数据集:测试集和训练集。 如果要使用多个测试集来评估模型,可以:

  • 为测试集指定不同的名称(例如“test1”和“test2”)。
  • 导出项目以获取 JSON 文件及其参数和配置。
  • 使用 JSON 导入新项目。 将第二个所需测试集重命名为“test”。
  • 使用第二个测试集训练模型以运行评估。

自定义目标应用和子应用的参数

如果使用协调应用,则建议为各种子应用发送自定义参数替代。 targetProjectParameters 字段允许用户发送表示每个目标项目参数的字典。 例如,假设一个名为 Orchestrator 的业务流程协调程序应用在名为 CLU1 的对话语言理解应用与名为 CQA1 的自定义问答应用之间进行协调。 如果要将名为“top”的参数发送到问答应用,可以使用上述参数。

curl --request POST \
   --url 'https://<your-language-resource>.cognitiveservices.azure.cn/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
                }
             }
         }
     }
 }'

跨语言资源复制项目

通常,可以使用 Language Studio 中的“复制”按钮将对话语言理解项目从一个资源复制到另一个资源。 在某些情况下,使用 API 复制项目可能更容易。

首先,需要确定:

  • 源项目名称。
  • 目标项目名称。
  • 源语言资源。
  • 目标语言资源,即要将其复制到的位置。

调用 API 以授权复制操作,并在稍后获取实际复制操作的 accessTokens

curl --request POST \ 
  --url 'https://<target-language-resource>.cognitiveservices.azure.cn//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.cn/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>" 
}'

处理域外语句

如果模型对域外语句的质量较差,客户可使用最近更新的训练配置版本 2024-08-01-preview(之前为 2024-06-01-preview)。 使用默认训练配置的示例如下所示,其中的模型有三个意向:SportsQueryWeatherAlarm。 测试语句是域外语句,模型将其分类为置信度分数相对较高的 InDomain 语句。

文本 预测意向 置信度分数
“谁建造了埃菲尔铁塔?” Sports 0.90
“今天你觉得我好看吗?” QueryWeather 1.00
“我希望你有一个美好的夜晚。” Alarm 0.80

若要解决此问题,请使用专为解决此问题而生成的 2024-08-01-preview 配置版本,同时保持合理的 InDomain 语句质量。

curl --location 'https://<your-resource>.cognitiveservices.azure.cn/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-08-01-preview",
      "evaluationOptions": {
            "kind": "percentage",
            "testingSplitPercentage": 0,
            "trainingSplitPercentage": 100
      }
}

发送请求后,可以像往常一样在 Language Studio 中跟踪训练作业的进度。

注意:

  • 使用此训练配置时,应用的 None 分数阈值(置信度阈值,如果低于该阈值,则会将 topIntent 标记为 None)应设置为 0。 之所以使用此设置,是因为这个新的训练配置将域内概率的某一部分归因于域外,以便模型不会错误地过度置信于域内语句。 因此,与生产训练配置相比,用户可能会发现域内语句的置信度分数略有下降。
  • 对于只有两个意向(例如 IntentANone)的应用,我们不建议使用此训练配置。
  • 对于每个意向的语句数量较少的应用,我们不建议使用此训练配置。 强烈建议为每个意向至少提供 25 个语句。