【问题标题】:Rasa NLU:Entity Synonyms detection inconsistencyRasa NLU:实体同义词检测不一致
【发布时间】:2017-11-15 05:17:48
【问题描述】:

我和我的团队已经使用 Rasa NLU 作为 MS LUIS 的替代品已有两个多月了,到目前为止,它对我们来说效果很好。现在我们有大约 900 个条目作为实体同义词(因为我们在 LUIS 中使用列表实体)。

并且仅对于某些话语,实体被检测为同义词,而对于大多数话语,它无法检测实体同义词。为了检测同义词,我必须创建另一个简单的实体,我们再次使用所有同义词值手动训练它,一旦使用这个简单的实体训练意图,Rasa 似乎将这个意图的实体检测为简单和同义词。

还有一个简单的问题,Rasa 中的实体同义词是否设计为仅返回一个匹配的实体(不像 LUIS 用于返回所有匹配的实体值)?

在 Rasa 中是否可以从 LUIS 中列出实体?

【问题讨论】:

    标签: rasa-nlu


    【解决方案1】:

    Rasa 中的实体同义词可能会导致一些混淆。他们提供的实际功能非常简单。对于模型解析的每个实体,该实体的值都会根据实体同义词列表进行检查。如果该值与实体同义词匹配,则将其替换为同义词值。

    上述声明中的一个重要问题是,实体必须先由模型识别,然后才能用同义词替换

    所以把这个作为一个简化的例子。这是我的实体同义词定义:

    {
      "value": "New York City",
      "synonyms": ["NYC", "nyc", "the big apple"]
    }
    

    如果我的训练数据只提供了这个例子:

    {
      "text": "in the center of NYC",
      "intent": "search",
      "entities": [
        {
          "start": 17,
          "end": 20,
          "value": "New York City",
          "entity": "city"
        }
      ]
    }
    

    我的模型不太可能检测到像 In the center of the big apple. 这样的句子中的实体,正如我上面所说,如果模型没有将 the big apple 解析为实体,则它不能被实体同义词替换阅读纽约市。

    因此,您应该在带有实体标签的训练数据的实际common_examples 中包含更多示例。一旦实体的所有变体都被正确分类,然后将这些值添加到实体同义词中,它们将被替换。

    [
      {
        "text": "in the center of NYC",
        "intent": "search",
        "entities": [
          {
            "start": 17,
            "end": 20,
            "value": "New York City",
            "entity": "city"
          }
        ]
      },
      {
        "text": "in the centre of New York City",
        "intent": "search",
        "entities": [
          {
            "start": 17,
            "end": 30,
            "value": "New York City",
            "entity": "city"
          }
        ]
      }
    ]
    

    我在 Rasa 文档页面中打开了 pull request 以添加注释。

    【讨论】:

    • 感谢朋友的回答。那么还有其他类似 LUIS 的列表实体的东西吗?我有大约 900 个值要添加为同义词,有什么建议吗?
    • 我们使用一个简单的脚本(我们的在 node 中,但你的可能在 python 等中)交换值,计算开始/结束位置,并将其推送到 common_examples 数组.值得注意的是,在common_examples 中,您不必标记意图。如果您的对象只有textentities,那么它只会影响实体分类而不影响意图分类。
    • 嘿@caleb keller 很抱歉再次打扰您,我有一个自动脚本,正如您建议的那样,它正在构建条目以供我添加到 common_examples 中。所以我有大约 900 个名字,我想要的只是将它们检测为自定义的“人”实体(总共有一些同义词,使其大约有 2000 个实体)。即使在训练了所有实体之后,Rasa 也无法检测到所有名称。关于如何优化检测的任何建议。
    • @HariGovind 你解决了你的问题吗?
    【解决方案2】:

    首先,我为此下载了一些 LUIS 模型 JSON,如下图所示:

    接下来,我编写了一个示例 C# 控制台应用程序,用于将 LUIS 模型架构转换为 RASA。

    这是 LUISModel 模型类。

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    
        namespace JSONConversion.Models
        {
    
            public class LuisSchema
            {
                public string luis_schema_version { get; set; }
                public string versionId { get; set; }
                public string name { get; set; }
                public string desc { get; set; }
                public string culture { get; set; }
                public List<Intent> intents { get; set; }
                public List<entity> entities { get; set; }
                public object[] composites { get; set; }
                public List<Closedlist> closedLists { get; set; }
                public List<string> bing_entities { get; set; }
                public object[] actions { get; set; }
                public List<Model_Features> model_features { get; set; }
                public List<regex_Features> regex_features { get; set; }
                public List<Utterance> utterances { get; set; }
            }
    
    
            public class regex_Features
            {
                public string name { get; set; }
                public string pattern { get; set; }
                public bool activated { get; set; }
            }
            public class Intent
            {
                public string name { get; set; }
            }
    
            public class entity
            {
                public string name { get; set; }
            }
    
            public class Closedlist
            {
                public string name { get; set; }
                public List<Sublist> subLists { get; set; }
            }
    
            public class Sublist
            {
                public string canonicalForm { get; set; }
                public List<string> list { get; set; }
            }
    
            public class Model_Features
            {
                public string name { get; set; }
                public bool mode { get; set; }
                public string words { get; set; }
                public bool activated { get; set; }
            }
    
            public class Utterance
            {
                public string text { get; set; }
                public string intent { get; set; }
    
                [JsonProperty("entities")]
                public List<Entities> Entities { get; set; }
            }
    
            public class Entities
            {
                [JsonProperty("entity")]
                public string Entity { get; set; }
                public int startPos { get; set; }
                public int endPos { get; set; }
            }
        }
    

    这是 RASAModel 模型类:

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    
    namespace JSONConversion.Models
    {
        public class RASASchema
        {
            public Rasa_Nlu_Data rasa_nlu_data { get; set; }
        }
    
        public class Rasa_Nlu_Data
        {
            public List<Entity_Synonyms> entity_synonyms { get; set; }
    
            public List<Regex_Features> regex_features { get; set; }
            public List<Common_Examples> common_examples { get; set; }
    
        }
    
        public class Entity_Synonyms
        {
            public string value { get; set; }
            public List<string> synonyms { get; set; }
        }
    
        public class Common_Examples
        {
            public string text { get; set; }
            public string intent { get; set; }
            public List<Entity> entities { get; set; }
        }
    
    
        public class Entity
        {
            public string entity { get; set; }
            public string value { get; set; }
            public int start { get; set; }
            public int end { get; set; }
        }
    
        public class Regex_Features
        {
            public string name { get; set; }
            public string pattern { get; set; }
        }
    }
    

    我编写了 2 个方法,它们从短语列表部分解析 LUISModel 模型类的同义词,并将它们添加到 RASA_NLU 训练对象的 common_examples 对象中。

    using JSONConversion.Models;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace JSONConversion.Services
    {
        public static class JSONHelper
        {
            public static Task<string> ReadFromFile(string FilePath)
            {
                try
                {
                    Task<string> readFromFileTask = Task.Run<string>(() => 
                    {
                        return File.ReadAllText(FilePath);
                    });
                    return readFromFileTask;
                }
                catch(Exception ex)
                {
                    throw;
                }
            }
    
            public static RASASchema ConvertLUISJSON(string StringifiedLUISJson)
            {
                try
                {
                    LuisSchema luisSchema = JsonConvert.DeserializeObject<LuisSchema>(StringifiedLUISJson);
    
                    RASASchema rasaSchema = new RASASchema();
                    rasaSchema.rasa_nlu_data = new Rasa_Nlu_Data();
                    rasaSchema.rasa_nlu_data.common_examples = new List<Common_Examples>();
                    rasaSchema.rasa_nlu_data.entity_synonyms = new List<Entity_Synonyms>();
                    rasaSchema.rasa_nlu_data.regex_features = new List<Regex_Features>();
    
    
                    luisSchema.closedLists.ForEach(x =>
                    {
                        x.subLists.ForEach(y =>
                        {
                            rasaSchema.rasa_nlu_data.entity_synonyms.Add(new Entity_Synonyms()
                            {
                                value = y.canonicalForm,
                                synonyms = y.list
                            });
                        });
                    });
    
                    luisSchema.model_features.ForEach(x =>
                    {
                        rasaSchema.rasa_nlu_data.entity_synonyms.Add(new Entity_Synonyms()
                        {
                            value = x.name,
                            synonyms = x.words.Split(',').ToList()
                        });
                    });
    
                    luisSchema.regex_features.ForEach(x =>
                    {
                        rasaSchema.rasa_nlu_data.regex_features.Add(new Regex_Features()
                        {
                            name = x.name,
                            pattern = x.pattern
                        });
                    });
    
                    luisSchema.utterances.ForEach(x =>
                    {
                        Common_Examples rasaUtterances = new Common_Examples();
                        rasaUtterances.text = x.text;
                        rasaUtterances.intent = x.intent;
    
                        List<Entity> listOfRASAEntity = new List<Entity>();
    
                        x.Entities.ForEach(y =>
                        {
                            listOfRASAEntity.Add(new Entity()
                            {
                                start = y.startPos,
                                end = y.endPos,
                                entity = y.Entity,
                                value = x.text.Substring(y.startPos, (y.endPos - y.startPos) + 1)
                            }); 
                        });
    
                        rasaUtterances.entities = listOfRASAEntity;
                        rasaSchema.rasa_nlu_data.common_examples.Add(rasaUtterances);
                    });
    
                    return rasaSchema;
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
        }
    }
    

    只是调用了那些 JSON 转换方法将 LUIS 模型转换为 RASA 模型。

    using System.Text;
    using JSONConversion.Services;
    using System.IO;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    
    namespace JSONConversion
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                string json = JsonConvert.SerializeObject(JSONConversion.Services.JSONHelper.ConvertLUISJSON(JSONHelper.ReadFromFile(@"C:\Users\xyz\Documents\luis.json").Result), new JsonSerializerSettings()
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver(),
                    Formatting = Formatting.Indented
                });
    
                File.WriteAllText(@"C:\Users\xyz\Desktop\RASA\data\examples\RasaFormat.json", json, Encoding.UTF8);
    
            }
        }
    }
    

    获得 RASA 模型后,您可以简单地训练 RASA 的同义词。

    【讨论】:

    • 嘿@kunal 感谢您的回答,但在我的场景中,我有大约 980 个值作为实体同义词,我已经编写了将数据从 LUIS 加载到 Rasa 的方法,但我的问题是检测的不一致的同义词。
    • @Caleb Keller 目前我被困在如何将同义词提供给 RASA,MITIE 管道没有安装在我的 Windows Server 机器上。如果您有任何线索,请告诉我。我已经使用 Cmake 和 Visual Studio 2015 从他们的 Git 链接构建 MITIE nlp。但我无法将 MITIE 管道集成为 python PyPi 包。
    • @HariGovind 你为 RASA 使用什么样的设置,你使用的是 Windows 服务器机器并在 docker 或 Ubuntu VM 上运行它?
    • @HariGovind 您将实体同义词称为 LUIS“短语列表”还是什么?请解释一下。
    • 嘿@kunal,我说的是 LUIS 中的 List 实体行中的一些内容,它具有规范形式和同义词。我的配置是 Windows Server 上的 SkLearn + Spacy。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多