意图与实体:理解Rasa NLU Pipeline

目录

  • The NLU Pipeline
  • 组件
    • 分词器
    • 特征化器
    • 意图分类器
    • 实体提取器
  • 交互:消息传递
  • 预测行为(Predicting Actions)
  • 总结
  • 参考

在Rasa项目中,NLU管道定义了处理步骤,将非结构化用户消息转换为意向和实体。它由一系列组件组成,可以由开发人员配置和定制。

本指南的目的是解释组件在Rasa NLU管道中扮演的角色,以及它们如何相互作用。

The NLU Pipeline

在Rasa中,NLU管道是在config.yml文件中定义的。此文件描述了,Rasa通过使用管道检测意图和实体的所有步骤。它以文本作为输入开始,并一直解析,直到有实体和意图作为输出。
意图与实体:理解Rasa NLU Pipeline_第1张图片
在管道中可以找到不同类型的组件。主要有:

  1. 分词器(Tokenizers)
  2. 特征化器(Featurizers)
  3. 意图分类器(Intent Classifiers)
  4. 实体提取器(Entity Extractors)

在讨论这些组件如何相互作用之前,我们将讨论它们各自的作用。

组件

分词器

第一步是将话语分成更小的文本块,称为tokens。这必须在为机器学习对文本进行特征化之前发生,这就是为什么通常在管道的开头会首先列出一个分词器。
在这里插入图片描述
分词器的详细信息。
意图与实体:理解Rasa NLU Pipeline_第2张图片
分词器将话语中的每个单词分割成一个单独的标记(token),通常分词器的输出是一个单词列表。我们也可能会得到单独的标点符号,这取决于分词器和我们的设置。

对于英语,我们通常使用WhiteSpaceTokenizer,但是对于非英语,通常选择其他的。比如,对于非英语的欧洲语言,通常选择SpaCy;对于汉语则通常选择Jieba。
请注意,分词器不会更改基础文本,它们只将文本分隔为标记(token)。例如,这意味着首字母大写仍然没有受到影响。可能您只希望为管道编码小写文本,但添加此类信息是Featureizer的工作,我们将在下一步讨论。

特征化器

特征化器为机器学习模型生成数字特征,即将文本转化为数字。下图显示了单词“Hi”的编码方式。
意图与实体:理解Rasa NLU Pipeline_第3张图片
特征有两种类型:

  • **稀疏特征:**通常由CountVectorizer生成。注意,这些计数也可以表示子词。我们还有一个LexicalSyntacticFeaturizer,它生成window-based的特征,用于实体识别。当与spaCy结合使用时,LexicalSyntacticFeaturizer还可以配置词性特征。
  • **密集特征:**这些由许多预先训练的嵌入件组成。通常来自SpaCyFeaturizers或通过LanguageModelFeaturizers来自huggingface。如果您想让它们工作,还应该在管道中包含适当的分词器。更多细节见文档。

意图与实体:理解Rasa NLU Pipeline_第4张图片
除了标记(token)的特征,我们还为整个句子生成特征。这有时也称为CLS token

句子特征的细节
CLS token的稀疏特征是标记(token)中所有稀疏特征的总和。密集特征要么是词向量的和/平均值(在spaCy的情况下),要么是整个文本的语境化表示(在huggingface模型的情况下)。

请注意,您可以完全自由地使用自定义特征化工具添加自己的组件。作为一个例子,有一个社区维护的项目叫做rasa-nlu-examples,它有许多非英语语言的实验特性化工具。它并没有得到Rasa的官方支持,但是它可以帮助很多用户,因为它拥有超过275种语言。

意图分类器

一旦我们为所有标记和整个句子生成了特征,我们就可以将其传递给意图分类模型。我们建议使用Rasa的DIET模型,它可以处理意图分类和实体提取。它还能够从标记和句子特征中学习。
意图与实体:理解Rasa NLU Pipeline_第5张图片

DIET细节
我们应该理解DIET算法是特殊的。过去,Rasa所承载的大多数算法要么是实体检测,要么是意图分类,它们并没有同时进行。这通常也意味着意向分类模型只关注管道的句子特征,而忽略了token特征。

实体提取器

即使DIET能够学会如何检测实体,我们也不一定推荐对每一种实体都使用它。例如,遵循结构化模式的实体(如电话号码)实际上不需要算法来检测它们。你可以用RegexEntityExtractor来处理它。
这就是为什么管道中有多个实体提取程序的常见原因。
意图与实体:理解Rasa NLU Pipeline_第6张图片
现在我们已经大概了解NLU管道中不同类型的组件,我们可以继续解释这些组件如何相互共享信息。

交互:消息传递

Rasa管道中的组件相互依赖,所以它们是如何相互作用的。为了理解这是如何工作的,可以拆解一个config.yml文件。
意图与实体:理解Rasa NLU Pipeline_第7张图片
NLU管道是一系列组件。这些组件按照在管道中列出的顺序进行训练和处理。这意味着管道配置可以被认为是数据需要通过的一系列线性步骤。

每当用户与助手交谈时,Rasa都会通过一个Message对象在内部跟踪话语的状态。此对象由管道中的每个步骤处理。下图概述了处理消息时发生的情况。
意图与实体:理解Rasa NLU Pipeline_第8张图片
在这个图表中有几点需要指出:

  1. 消息首先作为一个容器开始,只有简单的用户话语。
  2. 消息通过分词器后,它被拆分为Token。请注意,我们在图中将标记表示为字符串,而在内部它们由Token对象表示。
  3. 当消息通过CountVectorsFeaturer时,您会注意到稀疏特性被添加。序列和整个句子的特征是有区别的。另外,请注意,经过第二个特征化器后,稀疏特征的大小会增加。
  4. DIETClassifier将在消息中查找sparse_featuresdense_features,以便进行预测。处理完成后,它将把意图预测附加到消息对象。

每次消息通过管道步骤时,消息对象都将获得新信息。这也意味着,如果要向消息中添加信息,可以继续向管道中添加步骤。这也是为什么可以附加额外的实体提取模型。
意图与实体:理解Rasa NLU Pipeline_第9张图片
如您所见,管道中的每一步都可以向消息中添加信息。这意味着您可以添加多个实体提取步骤,并且可以并行地将实体添加到消息中。

自己检查消息对象
如果您自己对查看消息状态感兴趣,可以通过下面的代码检查模型的输出。

from rasa.cli.utils import get_validated_path
from rasa.model import get_model, get_model_subdirectories
from rasa.core.interpreter import RasaNLUInterpreter
from rasa.shared.nlu.training_data.message import Message

def load_interpreter(model_dir, model):
    path_str = str(pathlib.Path(model_dir) / model)
    model = get_validated_path(path_str, "model")
    model_path = get_model(model)
    _, nlu_model = get_model_subdirectories(model_path)
    return RasaNLUInterpreter(nlu_model)

# Loads the model
mod = load_interpreter(model_dir, model)
# Parses new text
msg = Message({TEXT: text})
for p in interpreter.interpreter.pipeline:
    p.process(msg)
    print(msg.as_dict())

预测行为(Predicting Actions)

通过NLU管道,我们可以检测意图和实体。但这条管道并不能预测对话中的下一步行动。这就是策略管道的目的。策略利用NLU的预测以及目前为止的对话状态来预测下一步要采取什么行动。
意图与实体:理解Rasa NLU Pipeline_第10张图片
如果您对这些策略如何生成操作感兴趣,您可能会喜欢我们在这里就这个主题撰写的博客文章。

总结

在这篇博文中,我们回顾了Rasa NLU管道中的组件是如何相互作用的。了解组件在管道中如何交互是很好的,因为它将帮助您确定哪些组件与助手相关。
同样重要的是要理解您可以完全定制管道。如果您不需要组件,您可以删除它们;如果您想使用自己的工具,您甚至可以编写自己的组件。如果您使用的是非英语语言,并且希望使用熟悉的自定义语言工具,我们建议您查看rasa-nlu-examples库。该存储库有许多分词器、特性化器和模型,您可以自由地从中获得灵感,用于自己的项目。

参考

  1. Intents & Entities: Understanding the Rasa NLU Pipeline

你可能感兴趣的:(Rasa)