【问题标题】:Retrieve complete LUIS DateTimeV2 entity from recognizer从识别器中检索完整的 LUIS DateTimeV2 实体
【发布时间】:2018-11-03 02:39:00
【问题描述】:

我正在使用 Microsoft Bot Framework v4 进行一些相当基本的日期和日期范围识别。

大多数示例使用并在企业模板中使用的 LUIS 识别器最直接的用法不会返回完整的 DateTimeV2 结构。下面的示例是对应于日期范围的“上周”。这些结果在recognizer.result.entities 中:

{
  "$instance": {
    "datetime": [
      {
        "startIndex": 8,
        "endIndex": 17,
        "text": "last week",
        "type": "builtin.datetimeV2.daterange"
      }
    ]
  },
  "datetime": [
    {
      "type": "daterange",
      "timex": [
        "2018-W43"
      ]
    }
  ]
}

请注意,日期范围没有开始/结束标签。这似乎是 DateTime2 规范的不完整版本。 https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/luis-reference-prebuilt-datetimev2

如果我使用特定的 DateTime 解析器,我会得到我想要的更详细的开始和结束信息。

[timex, 2018-W43]
[type, daterange]
[start, 2018-10-22]
[end, 2018-10-29]

看起来这些步骤几乎是多余的,因为更通用的方法返回包含开始和结束信息但不是易于使用的格式的 Timex 格式字符串。

我认为我缺少有关配置 LUIS 和识别器的基本知识。

下面的代码 sn-p 是 csharp_dotnetcore / 12.nlp-with-luis 示例的修改版本 (https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/12.nlp-with-luis)

我在 luis.ai 中添加了单个预构建的 DateTimeV2 实体。

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
    IList<Dictionary<string, string>> resolutionValues = null;

    if (turnContext.Activity.Type == ActivityTypes.Message)
    {

        // Use the more generic approach.
        var recognizerResult = await _services.LuisServices[LuisKey].RecognizeAsync(turnContext, cancellationToken);
        var topIntent = recognizerResult?.GetTopScoringIntent();
        if (topIntent != null && topIntent.HasValue && topIntent.Value.intent != "None")
        {
            await turnContext.SendActivityAsync($"==>LUIS Top Scoring Intent: {topIntent.Value.intent}, Score: {topIntent.Value.score}\n");
            if (recognizerResult.Entities != null)
            {
                await turnContext.SendActivityAsync($"==>LUIS Entities Found: {recognizerResult.Entities.ToString()}\n");
            }
        }
        else
        {
            var msg = @"No LUIS intents were found. Try show me last week.";
            await turnContext.SendActivityAsync(msg);
        }

        // Check LUIS model using specific DateTime Recognizer.
        var culture = Culture.English;
        var r = DateTimeRecognizer.RecognizeDateTime(turnContext.Activity.Text, culture);
        if (r.Count > 0 && r.First().TypeName.StartsWith("datetimeV2"))
        {
            var first = r.First();
            resolutionValues = (IList<Dictionary<string, string>>)first.Resolution["values"];
            var asString = string.Join(";", resolutionValues[0]);
            await turnContext.SendActivityAsync($"==>LUIS: resolutions values: {asString}\n");
            var subType = first.TypeName.Split('.').Last();
            if (subType.Contains("date") && !subType.Contains("range"))
            {
                // a date (or date & time) or multiple
                var moment = resolutionValues.Select(v => DateTime.Parse(v["value"])).FirstOrDefault();
                await turnContext.SendActivityAsync($"==>LUIS DateTime Moment: {moment}\n");
            }
            else if (subType.Contains("date") && subType.Contains("range"))
            {
                // range
                var from = DateTime.Parse(resolutionValues.First()["start"]);
                var to = DateTime.Parse(resolutionValues.First()["end"]);
                await turnContext.SendActivityAsync($"==>LUIS DateTime Range: from: {from} to: {to}\n");
            }
        }
    }
    else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate)
    {
        // Send a welcome message to the user and tell them what actions they may perform to use this bot
        await SendWelcomeMessageAsync(turnContext, cancellationToken);
    }
    else
    {
        await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected", cancellationToken: cancellationToken);
    }
}

有没有一种直接的方法可以从更通用的识别器中获取更完整的 DateTimeV2 实体?可能链接识别器?

【问题讨论】:

    标签: botframework azure-language-understanding


    【解决方案1】:

    为了查看整个 API 结果,可以在创建 Luis 识别器时设置一个选项。 includeApiResults 默认为 false,因此将该参数设置为 true 会导致整个 API 结果包含在 luis 结果中。

    因此,在创建 Luis 服务时,在 BotServices.cs 中将如下所示:

    case ServiceTypes.Luis:
         {
            var luis = service as LuisService;
            var luisApp = new LuisApplication(luis.AppId, luis.SubscriptionKey, luis.GetEndpoint());
            LuisServices.Add(service.Id, new TelemetryLuisRecognizer(luisApp, includeApiResults:true));
            break;
        }
    

    所以现在 luis 对象中的属性包含情绪分析和整个 luis 响应。

    {{
      "query": "show me orders for last week",
      "alteredQuery": null,
      "topScoringIntent": {
        "intent": "Shopping.CheckOrderStatus",
        "score": 0.619710267
      },
      "intents": null,
      "entities": [
        {
          "entity": "last week",
          "type": "builtin.datetimeV2.daterange",
          "startIndex": 19,
          "endIndex": 27,
          "resolution": {
            "values": [
              {
                "timex": "2018-W43",
                "type": "daterange",
                "start": "2018-10-22",
                "end": "2018-10-29"
              }
            ]
          }
        }
      ],
      "compositeEntities": null,
      "sentimentAnalysis": {
        "label": "negative",
        "score": 0.241115928
      }
    }}
    

    【讨论】:

      猜你喜欢
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多