1

假设我有这样的话语:“我的名字是 John James Doe

{
    "rasa_nlu_data": {
        "common_examples": 
        [
          {
             "text": "My name is John James Doe",
             "intent": "Introduction",
             "entities": [
                           {
                              "start": 11,
                              "end": 25,
                              "value": "John James Doe",
                              "entity": "Name"
                           }
                         ]
                    }
        ],
        "regex_features" : [],
        "entity_synonyms": []
    }
}

这里的子字符串是具有 3 个简单实体 ( , , )John James Doe的复合实体类型,如下所示:NameFirst NameMiddle NameLast Name

  • 约翰 - 名字(简单实体)
  • 詹姆斯 - 中间名(简单实体)
  • Doe - 姓氏(简单实体)

那么,在 RASA 中是否有任何内容可供我制作一种可以处理这些复合类型实体的训练格式。

任何帮助表示赞赏,谢谢。

4

2 回答 2

0

我为此编写了一个自定义组件,因为我也需要复合实体。以下是其工作原理的摘要。

假设您的训练数据看起来像这样:


    "rasa_nlu_data": {
        "common_examples": 
        [
          {
             "text": "My name is John James Doe",
             "intent": "Introduction",
             "entities": [
                           {
                              "start": 11,
                              "end": 15,
                              "value": "John",
                              "entity": "first_name"
                           },
                           {
                              "start": 16,
                              "end": 21,
                              "value": "James",
                              "entity": "middle_name"
                           },
                           {
                              "start": 22,
                              "end": 25,
                              "value": "Doe",
                              "entity": "last_name"
                           },
                         ]
                    }
        ],
        "regex_features" : [],
        "entity_synonyms": []
    }
}

因此,不是将全名训练为将被拆分的实体,而是训练将分组为全名的名称部分。

现在的基本思想是使用实体占位符定义复合模式。对于您的示例,您可以定义此模式:

full_name = "@first_name @middle_name @last_name"

对于您的例句,Rasa NLU 将像这样识别其中的三个实体:

My name is    John       James       Doe
               ^           ^          ^
           first_name middle_name last_name

您获取输入句子并将每个已识别的实体替换为其实体类型:

My name is @first_name @middle_name @last_name

您现在可以执行一个简单的检查,您定义的模式是否包含在此字符串中。

My name is @first_name @middle_name @last_name
                            ^
                            | Pattern matches
                            |
           "@first_name @middle_name @last_name"

如果包含它,您将获取属于包含部分的所有实体值,并将它们组合到一个 full_name 中。

My name is John           James        Doe           
                            ^
                            | Pattern matches
                            |
           @first_name @middle_name @last_name


-> full_name = ["John", "James", "Doe"]

如果你使用正则表达式而不是简单的字符串匹配,你可以使这个系统更加灵活。例如,您可以通过将模式更改为

full_name = "@first_name (@middle_name )?@last_name"
于 2019-06-04T16:17:02.197 回答
0

我相信,如果您继续使用 Name 实体类型进行训练,该实体类型会为所有名称提取一段文本,然后尝试从返回的实体文本中处理各个复合部分,我相信您将会有更轻松的时间。原因是如果您尝试在组件上进行训练,您很快就必须在训练数据中提供大量组合,而这将变得无效。

还要记住,随着您深入,这不是一个微不足道的问题。如果您单独使用位置来确定第一个/中间/最后一个,您在日本可能会遇到问题(https://www.sljfaq.org/afaq/names-for-people.html)并且如果您尝试训练以识别基于名称的名称在内容上(即选择 Doe 作为姓氏)很容易出现问题:美国人的名字在其他地方被认为是姓氏(杰克逊、亨特等)并不陌生,中间名也有很大差异(https://en.m.wikipedia.org/wiki/Middle_name

于 2018-02-28T23:55:10.040 回答