Rasa NLU部分主要是解决NER(序列建模)和意图识别(分类建模)这2个任务。Rasa NLP是一个基于DAG的通用框架,图中的顶点即组件。组件特征包括有顺序关系、可相互替换、可互斥和可同时使用。有向无环图(DAG)在很多地方都有用到,比如Spark中等。虽然问答系统类型很多,比如闲聊问答、文档问答、知识库问答、知识图谱问答、任务型问答等,但在实际场景中任务型多轮问答最实用。通过构建任务引导型人机辅助系统,在沟通前/沟通中/沟通后全链路,实时通过语音的识别、意图的检测、话术&解决方案的推荐等,辅助销售在多渠道与商家沟通提效、提高任务完成率。
一.典型Rasa NLU组件
一个典型的Rasa NLP管道包含各类组件,如下所示:
1.语言模型组件
为了加载模型文件,为后续的组件提供框架支持,如初始化spaCy和BERT。
2.分词组件
将文本分割成词,为后续的高级NLP任务提供基础数据。
3.特征提取组件
提取词语序列的文本特征,可以同时使用多个特征提取组件。
4.NER组件
根据前面提供的特征对文本进行命名实体的识别。
5.意图分类组件
按照语义对文本进行意图的分类,也称意图识别组件。
6.结构化输出组件
将预测结果整理成结构化数据并输出。这一部分功能不是以组件的形式提供的,而是流水线内建的功能,开发者不可见。
二.语言模型组件
主要是加载预训练的词向量模型或预训练模型,如下所示:
1.SpacyNLP
该组件所需的模型需要提前下载到本地,否则会出错。
2.MitieNLP
需要有预先训练好的模型。
3.预训练Tokenizer
model_tokenizer_dict: Dict[Text, Type[PreTrainedTokenizer]] = {
"bert": BertTokenizer,
"gpt": OpenAIGPTTokenizer,
"gpt2": GPT2Tokenizer,
"xlnet": XLNetTokenizer,
# "xlm": XLMTokenizer,
"distilbert": DistilBertTokenizer,
"roberta": RobertaTokenizer,
"camembert": CamembertTokenizer,
}
三.分词组件
1.jieba_tokenizer.py
这个分词器是Jieba的一个包装器(https://github.com/fxsjy/jieba)。
2.mitie_tokenizer.py
使用MitieNLP库对消息进行Tokenizer。
3.spacy_tokenizer.py
使用SpaCy库对消息进行Tokenizer。
4.whitespace_tokenizer.py
为实体提取创建特征。
四.特征提取组件
1.稀疏特征
SparseFeaturizer所有稀疏特征featurizers的基类。稀疏特征如下所示:
(1)count_vectors_featurizer.py
基于sklearn的CountVectorizer创建一系列token计数特征。所有仅由数字组成的token(例如123和99但不是ab12d)将由单个特征表示。将analyzer设置为char_wb使用了Subword Semantic Hashing的思想(https://arxiv.org/abs/1810.07150)。
(2)lexical_syntactic_featurizer.py
提取和编码词汇句法特征。给定一系列tokens,该特征提取器会生成一系列特征,其中第t个特征编码第t个token及其周围token的词汇和句法信息。
(3)regex_featurizer.py
基于正则表达式的消息特征。
2.稠密特征
DenseFeaturizer所有稠密特征featurizers的基类。稠密特征如下所示:
(1)convert_featurizer.py
使用ConveRT模型的Featurizer。从TFHub加载ConveRT(https://github.com/PolyAI-LDN/polyai-models#convert)模型,并为每个消息对象的密集可特征属性计算句子和序列级特征表示。
(2)lm_featurizer.py
基于transformer的语言模型的featurizer。这个组件从transformers库中加载预训练的语言模型,包括BERT、GPT、GPT-2、xlnet、distilbert和roberta。它还对每个消息的可特征化的密集属性进行tokenizes和featurizes。
(3)spacy_featurizer.py
使用SpaCy对消息进行特征化。
(4)mitie_featurizer.py
使用Mitie对消息进行特征化。
五.NER组件
1.crf_entity_extractor.py
实现条件随机场(CRF)来进行命名实体识别。
2.duckling_entity_extractor.py
使用duckling服务器搜索结构化实体,例如日期。
3.mitie_entity_extractor.py
一个Mitie实体提取器(它是Dlib-ml
的薄包装器)。
4.regex_entity_extractor.py
通过在训练数据中定义的查找表和正则表达式提取实体。
5.spacy_entity_extractor.py
使用SpaCy进行实体提取器。
六.意图分类组件
1.diet_classifier.py
用于意图分类和实体提取的多任务模型。DIET是双意图和实体Transformer。该架构基于Transformer,该Transformer用于两个任务。通过在与输入token序列对应的transformer输出序列上方的条件随机场(CRF)标记层预测实体标签序列。用于__CLS__
token和意图标签的transformer输出被嵌入到单个语义向量空间中。使用点积损失来最大化与目标标签的相似性,并最小化与负样本的相似性。
2.fallback_classifier.py
处理NLU置信度低的传入消息。
3.keyword_intent_classifier.py
使用简单的关键字匹配的意图分类器。分类器将关键字列表和关联的意图作为输入。输入句子将检查关键字并返回意图。
4.logistic_regression_classifier.py
使用逻辑回归的意图分类器。
5.mitie_intent_classifier.py
意图分类器使用mitie库。
6.sklearn_intent_classifier.py
使用sklearn框架的意图分类器。
除此之外,Rasa提供DIETClassifier组件,基于Rasa自行研发的DIET(Dual Intent Entity Transformer)技术,实现用户实体和意图的联合建模;对于FQA等简单的QA问题,只需要使用NLU部分就可以轻松完成,因此Rasa提供了回复选择器(ResponseSelector)组件。
个人认为LLM基本上解决了NLU和NLG的绝大部分问题,但是DM部分的表现还很邋遢。后续尝试将Rasa+LangChain+LLM+NebulaGraph技术进行融合来构建任务型多轮对话系统。对话管理(Dialog Management,DM)是指根据对话历史状态决定当前的动作或对用户的反应。DM模块是人机对话流程的控制中心,在多轮对话的任务型对话系统中有着重要的应用。DM模块的首要任务是负责管理整个对话的流程。通过对上下文的维护和解析,DM模块要决定用户提供的意图是否明确,以及实体槽的信息是否足够,以进行数据库查询或开始执行相应的任务。
当DM模块认为用户提供的信息不全或模棱两可时,就要维护一个多轮对话的语境,不断引导式地询问用户以得到更多的信息,或者提供不同的可能选项让用户选择。DM模块要存储和维护当前对话的状态、用户的历史行为、系统的历史行为、知识库中的可能结果等。当DM模块认为已经清楚得到了全部需要的信息后,就会将用户的查询变成相应的数据库查询语句去知识库(如知识图谱)中查询相应资料,或者实现和完成相应的任务(如购物下单,或者类似Siri拨打朋友的电话,或者类似智能家居去拉起窗帘等)。
因此,在新的研究中,将DM模块的状态建模成一个序列标注的监督学习问题,甚至用强化学习(reinforcement learning)加入一个用户模拟器来将DM模块训练成一个深度学习的模型。
参考文献:
[1]《Rasa实战》