如果训练数据集是英文,那么以pretrained_embeddings_convert
作为pipeline的起始点是不错的选择:
language: "en"
pipeline: "pretrained_embeddings_convert"
如果训练数据是多语言的,且具有丰富的领域特定的词汇表,那么可以使用supervise ed_embeddings
管道:
language: "en"
pipeline: "supervised_embeddings"
最重要的三个pipelines是:supervised_embeddings
, pretrained_embeddings_convert
和pretrained_embeddings_spacy
。pretrained_embeddings_spacy
pipeline使用 GloVe 或 fastText的预训练词向量。pretrained_embeddings_convert
使用预训练的句子编码模型ConveRT以抽取用户输入句子的整体向量表征。supervised_embeddings
pipeline不使用任何的预训练词向量或句向量,而是针对自己的数据集特别做的训练。
注意:
这些建议高度依赖于使用的数据集,因此是近似的。我们建议尝试使用不同的pipeline来训练最佳模型。
pretrained_embeddings_spacy
pipeline的优势在于当你有一个训练样本如I want to buy apples
,Rasa
会预测意图为get pears
。因为模型已经知道“苹果”和“梨”是非常相似的。如果没有足够大的训练数据,这一点尤其有用。
警告:
由于ConveRT模型仅在英语语料上进行训练,因此只有在训练数据是英语时才能够使用该pipeline。
该pipeline使用ConveRT模型抽取句子表征,并将句子表征输入到EmbeddingIntentClassifier
以进行意图分类。使用pretrained_embeddings_convert
的好处是不独立地处理用户输入句子中的每个词,而是为完整的句子创建上下文向量表征。比如,句子can I book a car?
,Rasa 会预测意图为I need a ride from my place
。由于这两个示例的上下文向量表征已经非常相似,因此对它们进行分类的意图很可能是相同的。如果没有足够大的训练数据,这也很有用。
注意:
使用pretrained_embeddings_convert
时候需要安装tensorflow-text==1.15.1
和tensorflow-hub==0.6.0
。也可以通过pip install rasa[convert]
进行安装。
supervised_embeddings
pipeline的优势是面向自己特定数据集的词向量。例如,在通用英语中,“balance(平衡)”与“symmetry(对称)”关系密切,与“cash(现金)”却有很大不同。在银行领域,“balance(余额)"和cash是密切相关的,希望模型能够捕捉到这一点。该pipeline不使用特定语言的模型,因此它可以与任何可以tokenize 化的语言一起工作(在空格上或使用自定义tokenizer)。更多关于supervised_embeddings可以看这里。
在pipeline中可以使用MITIE。MITIE后端对于小型数据集执行得很好,但是如果数据量超过几百个示例,则训练可能需要很长时间。但是,不建议您使用它,因为mitie支持在将来的版本中可能会被弃用。所以,这点要记住~
Rasa提供了在数据上直接比较两种pipeline性能的工具,参见比较NLU Pipelines。
注意:
意图分类独立于实体提取。所以有时候NLU的意图是正确的,但是实体是错误的,或者反过来。所以需要为意图和实体提供足够的数据。
如果类间存在巨大不平衡,分类算法通常不能很好地执行,例如,对于某些意图有很多训练数据,而对于其他意图只有很少的训练数据。为了缓解这个问题,rasa的supervised_embeddings
ppipeline使用了一个平衡的批处理策略。这个算法确保所有的类都在每个批处理中出现,或者至少在尽可能多的后续批处理中出现,仍然模拟某些类比其他类更频繁的事实。默认情况下使用平衡批处理。为了关闭它并使用经典的批处理策略,在配置文件中包含batch_strategy: sequence
。具体如下:
language: "en"
pipeline:
- name: "CountVectorsFeaturizer"
- name: "EmbeddingIntentClassifier"
batch_strategy: sequence
如果想要将意图分成多个标签,例如,为了预测多个意图或者为了建模层次意图结构,只能通过supervised embeddings
pipeline来实现。可以使用Whitespace Tokenizer
,并配置intent_split_symbol
(默认_
)以分割意图标签。示例如下:
language: "en"
pipeline:
- name: "WhitespaceTokenizer"
intent_split_symbol: "_"
- name: "CountVectorsFeaturizer"
- name: "EmbeddingIntentClassifier"
在Rasa NLU中,传入的消息通过一系列组件处理。这些组件在所谓的处理管道中一个接一个地执行。各种组件有用于实体提取、意图分类、响应选择、预处理等。如果想添加自己的组件,例如运行拼写检查或进行情绪分析,请查看自定义NLU组件。
每个组件处理输入并创建输出。输出可以被该组件之后管道中的任何组件使用。有些组件只生成管道中其他组件使用的信息,有些组件生成Output
属性,这些Output
属性将在处理完成后返回。例如,“I am looking For Chinese food”这句话的输出是:
{
"text": "I am looking for Chinese food",
"entities": [
{"start": 8, "end": 15, "value": "chinese", "entity": "cuisine", "extractor": "CRFEntityExtractor", "confidence": 0.864}
],
"intent": {"confidence": 0.6485910906220309, "name": "restaurant_search"},
"intent_ranking": [
{"confidence": 0.6485910906220309, "name": "restaurant_search"},
{"confidence": 0.1416153159565678, "name": "affirm"}
]
}
这是预配置管道pretrained_embeddings_spacy
中不同组件组合创建的的结果。例如,entities
属性是由CRFEntityExtractor
组件创建的。
每个组件都可以实现Component
基类中的多个方法;在管道中,这些不同的方法将按特定的顺序调用。假设,添加了以下管道到配置:"pipeline": ["Component A", "Component B", "Last Component"]
。下图为该管道训练时的调用顺序:
在使用create
函数创建第一个组件之前,将创建一个所谓的context
上下文(仅是一个python dict)。此context
上下文用于在组件之间传递信息。例如,一个组件可以计算训练数据的特征向量,将其存储在上下文中,另一个组件可以从context上下文中检索这些特征向量并进行意图分类。
解析后,实体以字典形式返回。有两个字段显示了关于管道如何影响返回的实体的信息:实体的extractor
字段z指明哪个实体提取器找到了这个特定的实体,而processors
字段包含了改变这个特定实体的组件的名称。
同义词的使用还可能导致value
字段与text
不完全匹配。相反,它将返回经过训练的同义词。
注意:
confidence
置信度将由CRF实体提取器(CRFEntityExtractor 组件)设置。 Duckling entity extractor 总是返回1。SpacyEntityExtractor
提取器不提供此信息,返回null
。
模板只是一个完整的组件列表的快捷方式。例如,这两种配置是等价的:
language: "en"
pipeline: "pretrained_embeddings_spacy"
和
language: "en"
pipeline:
- name: "SpacyNLP"
- name: "SpacyTokenizer"
- name: "SpacyFeaturizer"
- name: "RegexFeaturizer"
- name: "CRFEntityExtractor"
- name: "EntitySynonymMapper"
- name: "SklearnIntentClassifier"
下面是包含自定义信息的所有预配置管道模板的列表。
用自己需要的语种来训练Rasa模型,可以在config.yml
配置中定义supervised_embeddings
管道:
language: "en"
pipeline: "supervised_embeddings"
supervised_embeddings
pipeline支持任意能够被tokenized的语种。,默认情况下,tokenization使用的是空格。可以通过添加或更改组件自定义此管道的设置。以下是构成supervised_embeddings
管道的默认组件:
language: "en"
pipeline:
- name: "WhitespaceTokenizer"
- name: "RegexFeaturizer"
- name: "CRFEntityExtractor"
- name: "EntitySynonymMapper"
- name: "CountVectorsFeaturizer"
- name: "CountVectorsFeaturizer"
analyzer: "char_wb"
min_ngram: 1
max_ngram: 4
- name: "EmbeddingIntentClassifier"
如果选择的语言没有空格标记(单词没有空格分隔),那么可以使用自己的tokenizer
替换WhitespaceTokenizer
。目前支持许多不同的tokenizers,也可以创建自己的tokenizer
pretrained_embeddings_convert
pipeline具体组成如下:
language: "en"
pipeline:
- name: "WhitespaceTokenizer"
- name: "ConveRTFeaturizer"
- name: "EmbeddingIntentClassifier"
使用pretrained_embeddings_spacy
pipeline的配置使用:
language: "en"
pipeline: "pretrained_embeddings_spacy"
查阅 Pre-trained Word Vectors可以更多地了解加载 spacy 语言模型。pretrained_embeddings_spacy
pipeline的具体组成如下:
language: "en"
pipeline:
- name: "SpacyNLP"
- name: "SpacyTokenizer"
- name: "SpacyFeaturizer"
- name: "RegexFeaturizer"
- name: "CRFEntityExtractor"
- name: "EntitySynonymMapper"
- name: "SklearnIntentClassifier"
使用MITIE pipeline时,需要从语料中训练词向量。具体的训练方法可以参考这里。
MITIE pipeline的使用示例:
language: "en"
pipeline:
- name: "MitieNLP"
model: "data/total_word_feature_extractor.dat"
- name: "MitieTokenizer"
- name: "MitieEntityExtractor"
- name: "EntitySynonymMapper"
- name: "RegexFeaturizer"
- name: "MitieFeaturizer"
- name: "SklearnIntentClassifier"
该管道的另一种方式是使用MITIE进行特征化和它的多类分类器(multi-class classifier)。训练会非常慢, 所以针对大数据集不建议这么做。
language: "en"
pipeline:
- name: "MitieNLP"
model: "data/total_word_feature_extractor.dat"
- name: "MitieTokenizer"
- name: "MitieEntityExtractor"
- name: "EntitySynonymMapper"
- name: "RegexFeaturizer"
- name: "MitieIntentClassifier"
当然,没有必要一定使用模板,可以运行自定义的管道,简单地将你想用的组件名称添加到配置文件即可。例如:
pipeline:
- name: "SpacyNLP"
- name: "CRFEntityExtractor"
- name: "EntitySynonymMapper"
上述示例将创建一个只进行实体识别而不进行意图分类的管道。所以Rasa NLU不会预测任何意图。 关于组件的更多详细信息可以在这里找到。
如果希望在管道中使用自定义组件,请参阅自定义NLU组件。