最近的工程中需要对实体进行准确的识别,因此研究了一下如何在中文环境下使用正则匹配中的Lookup Tables的一种方式。
首先在domain.yml中明确对应的实体以及意图:
version: "3.0"
entities:
- line_name
intents:
- ask_train_time
以询问地铁运营时间的意图为例,在nlu.yml中填写对应的数据
version: "3.0"
nlu:
- intent: ask_train_time
examples: |
- 地铁[1号线](line_name)是否还在运营
- 地铁[1号线](line_name)还在运营吗
- 地铁[1号线](line_name)的首末班车时间
- 地铁[1号线](line_name)什么时候出发
- 地铁[1号线](line_name)什么时候截止
如果要使用Lookup Tables,在nlu中继续添加line_name对应的查找表:
- lookup: line_name
examples: |
- 1号线
- 2号线
- 3号线
- 12号线
- 月球线
- fb线
- 生命线
在config.yml的pipeline中配置RegexFeaturizer和RegexEntityExtractor:
recipe: default.v1
# Configuration for Rasa NLU.
# https://rasa.com/docs/rasa/nlu/components/
language: zh
pipeline:
- name: RegexFeaturizer
#...
#其他的一些组件
#这里我们配置多个抽取器来保证实体抽取的结果
- name: RegexEntityExtractor
use_word_boundaries: False
use_lookup_tables: True
use_regexes: True
- name: DIETClassifier
epochs: 50
#...
对rasa nlu进行测试:
可以看到因为我们在Lookup Table中也重复配置了
1号线
,因此该实体同时被两个抽取器提取到。明显可以看出,在DIETClassifier
抽取的实体中是包含confidence_entity
这个属性的;而在RegexEntityExtractor
对应的抽取结果中则并不包含该属性,这也说明这是基于正则进行匹配的,因此其对应的置信度默认为1。对Lookup Table中的其他实体名称进行测试:
当然,笔者这里也测试了utterance中需要识别两个实体一个意图的例子。
在nlu.yml中将数据进行更新
version: "3.0"
nlu:
- intent: ask_train_time
examples: |
- 地铁[1号线](line_name)[八宝山](station)站是否还在运营
- 地铁[1号线](line_name)[八宝山](station)站还在运营吗
- 地铁[1号线](line_name)[八宝山](station)站的首末班车时间
- 地铁[1号线](line_name)[八宝山](station)站什么时候出发
- 地铁[1号线](line_name)[八宝山](station)站什么时候截止
- lookup: line_name
examples: |
- 2号线
- 3号线
- 12号线
- 生命线
- lookup: station
examples: |
- 建国门
- 古城
- 月球
测试结果:可见基于正则的抽取可以完全满足实体的正确识别。而基于语义的实体识别则可能存在一些误差,在后续的自定义抽取的过程中进行取舍。
等待探索