Rasa系列教程(二) — Rasa NLU基础

  • Post author:
  • Post category:其他



目录


前言


一、训练数据


1.1 意图字段(intent)


1.2 同义词字段(synonym)


1.3 查找表字段(lookup)


1.4 正则表达式字段(regex)


1.5 查找表和正则表达式的使用


二、组件


2.1 语言模型组件


2.2 分词组件


2.3 特征提取组件


2.4 NER组件


2.5 意图分类组件


2.6 实体和意图联合提取组件


2.7 回复选择器


三、流水线


四、输出格式


五、如何使用Rasa NLU


六、实战:医疗机器人的NLU模块


前言

Rasa NLU负责

意图提取



实体提取

。例如,输入“明天上海的天气如何?”,Rasa NLU要提取出改句子的意图是查询天气,以及对应的实体值和类型名:明天—日期、上海—城市。

Rasa NLU使用

有监督算法

来完成功能,因此需要开发者提供适当数量的语料,包括意图信息和实体信息。

Rasa NLU在软件架构上设计的很灵活,允许开发者使用各种算法来完成功能,这些算法的具体实现被称为

组件(component)。

为了让组件灵活配置和维持正确的前后组件的依赖关系,Rasa NLU引入了

有向无环图DAG

的组件配置系统。



一、训练数据

在示例项目文件列表中的 data/nlu.yml 正是Rasa NLU的数据文件,具体内容如下:

version: "3.0"

nlu:

# 意图字段 
- intent: greet
  examples: |
    - hey!
    - hello!
    - hi!
    - hello there!
    - moin!

# 同义词字段
- synonym: 番茄
  examples: |
    - 番茄。
    - 西红柿
    - 洋柿子
    - 火柿子

# 查找表字段
- lookup: 城市
  examples: |
    - 北京
    - 上海
    - ...
    - 广州
    - 深圳

# 正则表达式字段
- regex: help
  examples: |
    - \bhelp\b

Rasa NLU的训练数据为YAML格式。从结构上说,Rasa N:U的训练数据都在

键(key)为nlu

的列表内。列表中每个元素都是一个字典,依靠字典中的键来区分功能。具有特殊含义的键有

intent



synonym



regex



lookup



除intent外,其他3个都是可选的。

1.1 意图字段(intent)

具有intent键表明当前的对象是用来存储训练样例的。intent对应的值时意图名。需要注意的是

意图名中不能包含“/”字符

,因为Rasa已经将这个字符预留了。

1.2 同义词字段(synonym)

具有synonym键表明当前的对象是用来存储同义词信息的。例如西红柿是番茄的同义词。在启动EntitySynonymMapper组件(后续章节介绍)的情况下,

推理时,会将得到的实体值的同义词替换为标准词。

即将“西红柿”、“洋柿子”全部替换为“番茄”。

1.3 查找表字段(lookup)

具有lookup键表明当前的对象是用来存储查找表的。在实体识别和意图识别的时候,如果开发者能给这些组件一些额外的特征,那么将提高这些组件的准确度。

在上述实例中,会有查找表特征[0001111101111000]。在NER时,模型会重点考虑这些查找表的特征,因此,即使训练数据中未出现车站名,模型也能在查找表特征的帮助下,正确提取出车站名。

1.4 正则表达式字段(regex)

具有regex键表明当前的对象是用来存储正则表达式的。利用正则表达式匹配某种模式后,将这种模式是否出现作为特征传给NER组件或意图识别组件,以提高组件的性能。

其优点是精度高,因此在特别规则的NER识别过程中,如身份证号码识别、电话号码识别等场景下,可以利用正则表达式特征提高识别准确率。

正则表达式同样也可以作为特征提供给NER模型做实体识别。

1.5 查找表和正则表达式的使用

在Rasa中,查找表和正则表达式主要通过2种方式使用:

  1. 作为NER组件的输入特征之一,可以与训练数据concat后,再输入神经网络中;
  2. 作为NER组件的输入,直接作为训练数据集;


二、组件

Rasa NLU是一个基于有向无环图的通用框架。

有向无环图是由组件(component)相互连接构成的。

一个NLU应用通常有实体识别、意图识别两个子任务。为了完成这些任务,一个典型的Rasa NLU配置通常包含如下各类组件。

1、

语言模型组件

:加载模型文件,为后续组件提供框架支持,如初始化spaCy和BERT;

2、

分词组件

:将文本分割成词,为后续的高级NLP任务提供基础数据;

3、

特征提取组件

:提取词语序列的文本特征,可以同时使用多个特征提取组件;

4、

NER组件

:根据前面提供的特征对文本进行命名实体识别;

5、

意图分类组件

:按照语义对文本进行意图的分类,也成意图识别组件;

6、

结构化输出组件

:将预测结果整理成结构化数据并输出。

这一部分不是以组件的形式提供的,而是流水线内建的功能,开发者不可见。

2.1 语言模型组件

语言模型组件加载

预训练的词向量模型

。目前有2个语言模型组件,如下表:


组件

备注
spaCyNLP 该组件所需的模型需要提前下载到本地,否则会出错
MitieNLP 需要预先训练好的模型

2.2 分词组件

Rasa分词组件中支持中文语言的分词器如下表:


组件

依赖

备注
JiebaTokenizer Jieba
MitieTokenizer Mitie 经过改造可以支持中文分词
spaCyTokenizer spaCy

2.3 特征提取组件

无论是实体识别还是意图分类,都需要上游的组件提供特征。Rasa的特征提取组件如下:


组件

依赖组件

备注
MitieFeaturizer MitieNLP
spaCyFeaturizer spaCyNLP
ConveRFeaturizer 分词组件 基于Poly AI的conveRT模型
LanguageModelFeaturizer 分词组件 基于HuggingFace的transformers库
RegexFeaturizer 分词组件 读取训练数据中的正则表达式配置
CountVectorsFeaturizer 分词组件 词袋模型
LexicalSynacticFeaturizer 分词组件 提供词法和语法特征,如是否句首、句尾、纯数字等

2.4 NER组件

Rasa支持多种NER组件,多数不可同时使用,少数组件可以有条件的同时使用。


组件

备注
CRFEntityExtractor
spcaCyEntityExtractor 只能使用spaCy内置的实体提取模型,不能再训练。内置实体种类为人名、地名、组织结构名等
DucklingEntityExtractor 只能使用预定义的实体,不能再训练。内置的实体种类为邮箱、距离、时间等
MitieEntityExtractor
EntitySynonymMapper 用于同义词改写,将提取到的实体标准化
DIETClassifier
RegexEntityExtractor 读取训练数据中的查找表及正则表达式,用于提取实体

2.5 意图分类组件

意图分类组件如下表所示:

组件 依赖 备注
MitieIntentClassifier Mitie
SklearnIntentClassifier Scikit-learn
KeywordIntentClassifier
DIETIntentClassifier Tensorflow
FallIntentClassifier 如果其他组件预测的intent得分过低,则该组件将intent更改为NLU fallback

2.6 实体和意图联合提取组件

Rasa提供DIETClassifier(基于Rasa自行研发的DIET技术)用户实体和意图的联合建模。

2.7 回复选择器

对于FQA等简单的QA问题,只需要使用NLU部分就可以轻松完成,因此Rasa提供了回复选择器(ResponseSelector)组件。



三、流水线

Rasa NLU基于有向无环图进行组件配置,此有向无环图在Rasa中称为流水线(pipeline)。


流水线定义了各个组件和组件之间的依赖关系,允许开发者对各个组件进行配置。

Rasa NLU的配置文件使用的是YAML格式。下面是适合

中文开发者

的,推荐流水线配置:

recipe: default.v1

language: "zh"

pipeline:
  -name: JiebaTokenizer    # 分词组件,jiba分词可能会和实体边界产生冲突,后续介绍其他分词组件
  -name: LanguageModelFeaturizer
   model_name: "bert"
   model_weights: "bert-base-chinese"
  -name: "DIETClassifier"

大体上Rasa NLU的配置文件可以分为3个主要的键:recipe、language、pipeline。


recipe:

表示当前配置文件所用的格式,当前Rasa只支持一种格式,那就是default.v1


language:

用于指定Rasa NLU将要处理的语言


pipeline:

配置文件的核心,由列表构成,每个元素都是一个字典(表现在YAML中类似于name: xxx),这些字典直接对应流水线组件



四、输出格式

NLU的输出内容主要包括text、intent、entities 3个部分。分别表示请求文本、意图识别、实体识别。实例如下:

{
    "text": "show me chinese restaurants",    # 用户输入的文本
    "intent": "restaurant_search",            # 意图字段
    "entities": [                             # 实体字段
        {    
            "start": 8,                       # 开始位置
            "end": 15,                        # 结束位置
            "value": "chinese",               # 实体值
            "entity": "cuisine",              # 实体类型
            "extractor": "CRFEntityExtractor",# 提取器信息
            "confidence": 0.854,              # 置信度
            "processors": [],                 
        }
    ]
}


五、如何使用Rasa NLU

Rasa是一种高度内聚的框架,可以使用Rasa自带的命令行工具进行模型训练和推理任务。

(1)训练模型

rasa train nlu

这条命令将会从 data/ 目录下查找训练数据,使用config.yml作为流水线配置并将训练后的模型保存在 models/ 目录中,模型的名字以nlu-为前缀

(2)命令行测试

rasa shell nlu

如果想自行制定模型,则可以使用如下命令:

rasa shell -m models/nlu-<timestamp>.tar.gz

下面是rasa shell的使用界面:

hello # 用户自己的输入

# 返回结果
{
    "text": "hello",    # 原始文本
    "entities": [],     # 实体字段
    "intent": {         # 意图字段
        "name": "greet",# 意图类型
        "confidence": 0.996844410963013    # 置信度
    },
    "intent_ranking": [    # 各意图置信度
        {
            "name": "greet",
            "confidence": 0.9968444108963013
        },
        {
            "name": "mood_greet",
            "confidence": 5.1380e-05
        },
    ]
}

(3)启动服务

Rasa NLU提供了 RESTful HTTP API的服务形式,使用如下命令开启。

rasa run — enable-api

我们可以通过向 /model/parse 路径发送请求的方式使用预测服务,如使用curl作为客户端。

curl localhos:5005/model/parse -d ‘{“text”:”hello”}’

在实际调试中,开发者可以考虑使用postman等工具发送请求,如下所示:



六、实战:医疗机器人的NLU模块

在学习完Rasa NLU模块后,检验学习效果最好的办法就是实战。本项目将构建一个简单的医疗领域机器人的NLU模块。它支持以下实体和意图识别:

  • 对药品查询或医院、科室查询的意图识别
  • 对疾病和病症的实体识别
  • 简单地打招呼

具体代码可参考:

Git



版权声明:本文为m0_37565948原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。