Rasa NLU:Entity 同义词检测不一致
Rasa NLU:Entity Synonyms detection inconsistency
我和我的团队已经使用 Rasa NLU 替代 MS LUIS 两个多月了,到目前为止它对我们来说效果很好。现在我们有大约 900 个条目作为实体同义词(因为我们在 LUIS 中使用列表实体)。
并且仅对于某些话语,实体被检测为同义词,而对于大多数话语,它无法检测实体同义词。为了检测同义词,我必须创建另一个简单的实体,我们再次用所有同义词值手动训练,一旦用这个简单的实体训练了意图,Rasa 似乎检测到这个意图的实体作为简单和同义词。
另一个简单的问题,Rasa 中的实体同义词是否设计为 return 只有一个匹配的实体(不像 LUIS 曾经 return 所有匹配的实体值)?
是否有其他方法可以在 Rasa 中列出来自 LUIS 的实体?
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
未被模型解析为实体,则它不能被实体同义词替换为 New York City。
因此,您应该在训练数据的实际 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 模型 JSON,如以下屏幕截图所示:
接下来,我编写了一个示例 C# 控制台应用程序,用于将 LUIS 模型架构转换为 RASA。
这里是LUISModel模型class。
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模型class:
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 模型 class 中的短语列表部分的同义词,并将它们添加到 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的同义词了。
我和我的团队已经使用 Rasa NLU 替代 MS LUIS 两个多月了,到目前为止它对我们来说效果很好。现在我们有大约 900 个条目作为实体同义词(因为我们在 LUIS 中使用列表实体)。
并且仅对于某些话语,实体被检测为同义词,而对于大多数话语,它无法检测实体同义词。为了检测同义词,我必须创建另一个简单的实体,我们再次用所有同义词值手动训练,一旦用这个简单的实体训练了意图,Rasa 似乎检测到这个意图的实体作为简单和同义词。
另一个简单的问题,Rasa 中的实体同义词是否设计为 return 只有一个匹配的实体(不像 LUIS 曾经 return 所有匹配的实体值)?
是否有其他方法可以在 Rasa 中列出来自 LUIS 的实体?
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
未被模型解析为实体,则它不能被实体同义词替换为 New York City。
因此,您应该在训练数据的实际 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 模型 JSON,如以下屏幕截图所示:
接下来,我编写了一个示例 C# 控制台应用程序,用于将 LUIS 模型架构转换为 RASA。
这里是LUISModel模型class。
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模型class:
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 模型 class 中的短语列表部分的同义词,并将它们添加到 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的同义词了。