title: Rasa NLU 详解subtitle: 转载自https://github.com/km1994/nlp_paper_study/blob/master/dialogue_system_study/rasa/rasa系列/rasa_nlu.md
date: 2020-12-14
author: NSX
catalog: true
tags:
- Rasa NLU

目录

在人机对话中,首先需要 让 机器 理解 用户所说的 内容,才能 帮助 机器 知道用户意图,并作出 适当 的 反馈。那么 这个时候 需要怎么做呢?

答案:自然语言理解(NLU)

三、什么是 自然语言理解?

  • 英文:(NLU,natural language understanding)
  • 介绍:指机器能够理解执行人类所期望的某些语言功能,换句话说就是人与机器交流的桥梁;

四、自然语言理解 的 工作 是什么?

  1. 理解句子的正确次序规则和概念,又能理解不含规则的句子;
  2. 知道词的确切含义、形式、词类及构词法;
  3. 了解词的语义分类、词的多义性、词的歧义性;
  4. 指定和不定特性及所有特性;
  5. 问题领域的结构知识和实践概念;
  6. 语言的语气信息和韵律表现;
  7. 有关语言表达形式的文字知识;
  8. 论域的背景知识;

五、自然语言理解 三层次,你知道么?

  • 三层次:

    • 词法分析:自然语言理解过程的第一层,它的性能直接影响到后面句法和语义分析的成果,主要包括自动分词、词性标注、中文命名实体标注三方面内容;
    • 句法分析的目标是自动推导出句子的句法结构,实现这个目标首先要确定语法体系,不同的语法体系会产生不同的句法结构,常见语法体系有短语结构语法、依存关系语法;
    • 语义分析就是指分析话语中所包含的含义,根本目的是理解自然语言。分为词汇级语义分析、句子级语义分析、段落/篇章级语义分析,即分别理解词语、句子、段落的意义。

2020-12-14-Rasa NLU 详解 - 图1

参考:自然语言理解技术NLU

六、自然语言理解 一般理解 你知道么?

2020-12-14-Rasa NLU 详解 - 图2

该图来源于【自然语言处理(NLP)的一般处理流程】,还提供了【百度脑图查看点击链接】。

七、NLU 训练数据如何准备?

7.1 NLU 训练样本数据格式?

注:将NLU训练数据保存到单独的文件或者多个文件的目录

  • markdown:

    • Common Examples:(唯一必须,NLU模型核心,也是训练NLU模型基础)

      • intent:某个意图,它应于某些text相对应;
      • text:用户自然语言文本,即用户Message(text中可以不包括实体,但如果包含需要用entityText进行标志);
      • entities:将要被提取的目标实体,我们需要在text文本中标出(如果该text存在实体的话);
    • synonyms:同义词,在实体提取时会统一被解析成同一个意思;

      • 举例说明:NLU 能够将(余额、话费、话费余额、账号余额)-映射-> 余额;
      • 注:需要pipeline中包含EntitySynonmMapper组件,才能使用
    • Regular Expression Features:

      • 介绍:有助于意图分类和实体提取,但是它并不参与实体和意图的定义,仅仅是提供规则来协助意图分类和实体提取,因此,在训练文本text中,该添加的实体和意图样本需要照样添加
      • 举例:当需要用户输入的手机号实体时,我们可以再nlu.md文件中添加正则表达式特征支持,当用户输入的Message包含符合手机号正则表达式规则的内容时,Rasa可以更加容易地将其提取出来;
      • 说明:phone_number表示的既不是实体名也不是意图名,它只是一个便于我们阅读的标志而已。除了实体识别,我们还可以编写符合意图分类的正则表达式,这里就不演示了。
      • 对于实体提取来说,目前只有CRFEntityExtractor 实体提取器支持正则特征,像``MitieEntityExtractor和SpacyEntityExtractor目前还不支持
      • 对于意图分类器目前均已支持正则特征
      • 注:需要pipeline中包含RegexFeaturizer组件,才能使用 正则特性
    • lookup tables:

      • 查找表有利于在加载训练数据时,生成与Regular Expression Features相同的正则特征。当在训练数据中提供查找表时,内容被组合成一个大型、不区分大小写的regex模式,该模式在训练示例中查找精确匹配。这些正则表达式匹配多个token,其处理与训练数据中直接指定的正则表达式模式相同。查找表可以包括在训练数据中,如果外部提供的数据必须要以换行进行分隔;
      • 注:mobile_data_package表示实体名。为了查找表能够有效的被使用,训练数据中必须要有一些示例被匹配上。否则,模型不会使用查找表特征向查找表添加数据时必须小心,比如如果表中有误报或其他噪声,就会影响性能,因此请确保查找表包含干净的数据 【eg:查下腾讯视频流量包被匹配时,才会去 查找 data/lookup_tables/DataPackage.txt 表】
  1. # data/lookup_tables/DataPackage.txt 格式
  2. 腾讯视频流量包
  3. ...
  1. <!--Common Examples-->
  2. ## intent:你的意图名称
  3. - text
  4. ## intent:request_phone_business
  5. - 查个手机号
  6. - 查电话号码[19800222425](phone_number)
  7. - [余额](business)
  8. - 查下[腾讯视频流量包](mobile_data_package)
  9. - 你好!请帮我查询一下电话[12260618425](phone_number)的[账户余额](business)
  10. - 帮我查个手机号[19860612222](phone_number)的[话费](business)
  11. - 查下号码[19860222425](phone_number)的[抖音免流包](mobile_data_package)
  12. <!--synonyms-->
  13. ## synonym:余额
  14. - 余额
  15. - 话费
  16. ...
  17. <!--Regular Expression Features-->
  18. ## regex:phone_number
  19. - ((\d{3,4}-)?\d{7,8})|(((\+86)|(86))?(1)\d{10})
  20. ## lookup: mobile_data_package
  21. data/lookup_tables/DataPackage.txt
  • JSON:

markdown 类似

  1. {
  2. "rasa_nlu_data": {
  3. "common_examples": [
  4. {
  5. "text": "帮我查一下我的流量有多少",
  6. "intent": "request_search",
  7. "entities": [
  8. {
  9. "start": 7,
  10. "end": 9,
  11. "value": "流量",
  12. "entity": "item"
  13. }
  14. ]
  15. },
  16. ],
  17. "regex_features": [
  18. {
  19. "name": "inform_package",
  20. "pattern": "套餐[0-9一二三四五六七八九十百俩两]+"
  21. },
  22. {
  23. "name": "inform_time",
  24. "pattern": "([0-9一二三四五六七八九十百俩两]+)月份?的?"
  25. }
  26. ],
  27. "entity_synonyms": [{
  28. "value": "消费",
  29. "synonyms": ["话费", "钱"]
  30. }]
  31. },
  32. "lookup_tables": [{
  33. "value": "constellation",
  34. "ookup": "data/lookup_tables/constellation.txt"
  35. }]
  36. }
  37. }

7.2 NLU 训练样本数据格式如何验证?

  • 动机:对于 domian.yml、NLU data和Story data,如何检查这些文件是否有错误呢?
  • 使用命令:
  1. python -m rasa data validate

参数说明:

  1. usage: rasa data validate [-h] [-v] [-vv] [--quiet] [--fail-on-warnings]
  2. [-d DOMAIN] [--data DATA]
  3. optional arguments:
  4. -h, --help show this help message and exit
  5. --fail-on-warnings Fail validation on warnings and errors. If omitted
  6. only errors will result in a non zero exit code.
  7. (default: False)
  8. -d DOMAIN, --domain DOMAIN
  9. Domain specification (yml file). (default: domain.yml)
  10. --data DATA Path to the file or directory containing Rasa data.
  11. (default: data)
  12. Python Logging Options:
  13. -v, --verbose Be verbose. Sets logging level to INFO. (default:
  14. None)
  15. -vv, --debug Print lots of debugging statements. Sets logging level
  16. to DEBUG. (default: None)
  17. --quiet Be quiet! Sets logging level to WARNING. (default:
  18. None)
  • 代码:
  1. import logging
  2. from rasa import utils
  3. from rasa.core.validator import Validator
  4. logger = logging.getLogger(__name__)
  5. utils.configure_colored_logging('DEBUG')
  6. validator = Validator.from_files(domain_file='domain.yml',
  7. nlu_data='data/nlu_data.md',
  8. stories='data/stories.md')
  9. validator.verify_all()

八、Rasa NLU Components

8.1 词向量资源(Word Vector Sources)

(一)MitieNLP (做中文任务时,一般选用做一个,因为他是基于中文的词向量)

2020-12-14-Rasa NLU 详解 - 图3

  • configs.yml 配置
  1. pipeline:
  2. - name: "MitieNLP"
  3. # 语言模型
  4. model: "data/total_word_feature_extractor_zh.dat"

(二)SpacyNLP (英文)

2020-12-14-Rasa NLU 详解 - 图4

  • configs.yml 配置
  1. pipeline:
  2. - name: "SpacyNLP"
  3. # 指定语言模型
  4. model: "en_core_web_md"
  5. # 设定在检索单词向量时,这将决定单词的大小写是否相关
  6. # 当为false时,表示不区分大小写。比如`hello` and `Hello`
  7. # 检索到的向量是相同的。
  8. case_sensitive: false

8.2 分词(Tokenizers)

(一)WhitespaceTokenizer

2020-12-14-Rasa NLU 详解 - 图5

  • configs.yml 配置
  1. pipeline:
  2. - name: "WhitespaceTokenizer"
  3. # 指定是否大小写敏感,默认true为敏感
  4. case_sensitive: false

(二)JiebaTokenizer

2020-12-14-Rasa NLU 详解 - 图6

  • configs.yml 配置
  1. pipeline:
  2. - name: "JiebaTokenizer"
  3. # 指定自定义词典
  4. dictionary_path: "path/to/custom/dictionary/dir"

(三)MitieTokenizer

2020-12-14-Rasa NLU 详解 - 图7

  • configs.yml 配置
  1. pipeline:
  2. - name: "MitieTokenizer"

(四)SpacyTokenizer

2020-12-14-Rasa NLU 详解 - 图8

  • configs.yml 配置
  1. pipeline:
  2. - name: "SpacyTokenizer"

(五)ConveRTTokenizer

2020-12-14-Rasa NLU 详解 - 图9

  • configs.yml 配置
  1. pipeline:
  2. - name: "ConveRTTokenizer"

8.3 文本特征化(Text Featurizers)

(一)MitieFeaturizer

2020-12-14-Rasa NLU 详解 - 图10

  • configs.yml 配置
  1. pipeline:
  2. - name: "MitieFeaturizer"

(二)SpacyFeaturizer

2020-12-14-Rasa NLU 详解 - 图11

  • configs.yml 配置
  1. pipeline:
  2. - name: "SpacyFeaturizer"

(三)ConveRTFeaturizer

2020-12-14-Rasa NLU 详解 - 图12

  • configs.yml 配置
  1. pipeline:
  2. - name: "ConveRTFeaturizer"

(四)RegexFeaturizer

2020-12-14-Rasa NLU 详解 - 图13

  • configs.yml 配置
  1. pipeline:
  2. - name: "RegexFeaturizer"

(五)CountVectorsFeaturizer

2020-12-14-Rasa NLU 详解 - 图14

  • configs.yml 配置
  1. pipeline:
  2. - name: "CountVectorsFeaturizer"
  3. "use_shared_vocab": False,
  4. analyzer: 'word'
  5. token_pattern: r'(?u)\b\w\w+\b'
  6. strip_accents: None
  7. stop_words: None
  8. min_df: 1
  9. max_df: 1.0
  10. min_ngram: 1
  11. max_ngram: 1
  12. max_features: None
  13. lowercase: true
  14. OOV_token: None
  15. OOV_words: []

8.4 意图分类(Intent Classifiers)

(一)MitieIntentClassifier

2020-12-14-Rasa NLU 详解 - 图15

  • configs.yml 配置
  1. pipeline:
  2. - name: "MitieIntentClassifier"
  • 输出格式:
  1. {
  2. "intent": {"name": "greet", "confidence": 0.98343}
  3. }

(二)SklearnIntentClassifier

2020-12-14-Rasa NLU 详解 - 图16

  • configs.yml 配置
  1. pipeline:
  2. - name: "SklearnIntentClassifier"
  3. # 指定SVM训练时要尝试的参数
  4. # 通过运行超参数搜索,以找到最佳的参数集
  5. C: [1, 2, 5, 10, 20, 100]
  6. # 指定C-SVM使用的内核
  7. # 它与GridSearchCV中的“C”超参数一起使用
  8. kernels: ["linear"]
  • 输出格式:
  1. {
  2. "intent": {"name": "greet", "confidence": 0.78343},
  3. "intent_ranking": [
  4. {
  5. "confidence": 0.1485910906220309,
  6. "name": "goodbye"
  7. },
  8. {
  9. "confidence": 0.08161531595656784,
  10. "name": "restaurant_search"
  11. }
  12. ]
  13. }

(三)EmbeddingIntentClassifier

2020-12-14-Rasa NLU 详解 - 图17

  • configs.yml 配置
  1. pipeline:
  2. - name: "EmbeddingIntentClassifier"
  3. # Embedding算法的控制参数非常多
  4. # 具体参照官方文档,这里以指定训练次数为例
  5. epochs: 500
  • 输出格式:
  1. {
  2. "intent": {"name": "greet", "confidence": 0.8343},
  3. "intent_ranking": [
  4. {
  5. "confidence": 0.385910906220309,
  6. "name": "goodbye"
  7. },
  8. {
  9. "confidence": 0.28161531595656784,
  10. "name": "restaurant_search"
  11. }
  12. ]
  13. }

(四)KeywordIntentClassifier

2020-12-14-Rasa NLU 详解 - 图18

  • configs.yml 配置
  1. pipeline:
  2. - name: "KeywordIntentClassifier"
  3. case_sensitive: True
  • 输出格式:
  1. {
  2. "intent": {"name": "greet", "confidence": 1.0}
  3. }

8.5 选择器(Selectors)

(一)Response Selector

2020-12-14-Rasa NLU 详解 - 图19

  • configs.yml 配置
  1. pipeline:
  2. - name: "KeywordIntentClassifier"
  3. # 算法支持很多参数配置,详情见文档
  4. case_sensitive: True
  • 输出格式:
  1. {
  2. "text": "What is the recommend python version to install?",
  3. "entities": [],
  4. "intent": {"confidence": 0.6485910906220309, "name": "faq"},
  5. "intent_ranking": [
  6. {"confidence": 0.6485910906220309, "name": "faq"},
  7. {"confidence": 0.1416153159565678, "name": "greet"}
  8. ],
  9. "response_selector": {
  10. "faq": {
  11. "response": {"confidence": 0.7356462617, "name": "Supports 3.5, 3.6 and 3.7,
  12. +"recommended version is 3.6"},
  13. "ranking": [
  14. {"confidence": 0.7356462617, "name": "Supports 3.5, 3.6 and 3.7,
  15. +"recommended version is 3.6"},
  16. {"confidence": 0.2134543431, "name": "You can ask me about how
  17. +"to get started"}
  18. ]
  19. }
  20. }
  21. }

8.6 实体提取(Entity Extractors)

2020-12-14-Rasa NLU 详解 - 图20

(一)MitieEntityExtractor

2020-12-14-Rasa NLU 详解 - 图21

  • configs.yml 配置
  1. pipeline:
  2. - name: "MitieEntityExtractor"
  • 输出格式:
  1. {
  2. "entities": [{"value": "New York City",
  3. "start": 20,
  4. "end": 33,
  5. "confidence": null,
  6. "entity": "city",
  7. "extractor": "MitieEntityExtractor"}]
  8. }

(二)SpacyEntityExtractor

2020-12-14-Rasa NLU 详解 - 图22

  • configs.yml 配置
  1. pipeline:
  2. - name: "SpacyEntityExtractor"
  3. # dimensions to extract
  4. dimensions: ["PERSON", "LOC", "ORG", "PRODUCT"]
  • 输出格式:
  1. {
  2. "entities": [{"value": "New York City",
  3. "start": 20,
  4. "end": 33,
  5. "entity": "city",
  6. "confidence": null,
  7. "extractor": "SpacyEntityExtractor"}]
  8. }

(三)EntitySynonymMapper

2020-12-14-Rasa NLU 详解 - 图23

  • configs.yml 配置
  1. pipeline:
  2. - name: "EntitySynonymMapper"
  • 训练数据与实体提取示例:
  1. [{
  2. "text": "I moved to New York City",
  3. "intent": "inform_relocation",
  4. "entities": [{"value": "nyc",
  5. "start": 11,
  6. "end": 24,
  7. "entity": "city",
  8. }]
  9. },
  10. {
  11. "text": "I got a new flat in NYC.",
  12. "intent": "inform_relocation",
  13. "entities": [{"value": "nyc",
  14. "start": 20,
  15. "end": 23,
  16. "entity": "city",
  17. }]
  18. }]

说明:在上述例子中,该组件将实体New York City和NYC映射到nyc。即使消息包含NYC,实体提取将返回nyc。当该组件更改现有实体时,它将自己附加到该实体的处理器列表中。

(四)CRFEntityExtractor

2020-12-14-Rasa NLU 详解 - 图24

  • configs.yml 配置
  1. pipeline:
  2. - name: "CRFEntityExtractor"
  3. features: [["low", "title"], ["bias", "suffix3"], ["upper", "pos", "pos2"]]
  4. # 决定是否使用BILOU_flag
  5. BILOU_flag: true
  6. # 在训练前将该参数设定给sklearn_crfcuite.CRF tagger
  7. max_iterations: 50
  8. # 指定L1正则化系数
  9. # 在训练前将该参数设定给sklearn_crfcuite.CRF tagger
  10. L1_c: 0.1
  11. # 指定L2正则化系数
  12. # 在训练前将该参数设定给sklearn_crfcuite.CRF tagger
  13. L2_c: 0.1
  • 实体提取示例:
  1. {
  2. "entities": [{"value":"New York City",
  3. "start": 20,
  4. "end": 33,
  5. "entity": "city",
  6. "confidence": 0.874,
  7. "extractor": "CRFEntityExtractor"}]
  8. }

(五)DucklingHTTPExtractor

2020-12-14-Rasa NLU 详解 - 图25

  • configs.yml 配置
  1. pipeline:
  2. - name: "DucklingHTTPExtractor"
  3. # duckling server的url
  4. url: "http://localhost:8000"
  5. # 指定提取哪些维度,即实体类型
  6. dimensions: ["time", "number", "amount-of-money", "distance"]
  7. # 配置语言环境
  8. locale: "de_DE"
  9. # 指定时区
  10. timezone: "Europe/Berlin"
  11. # 访问ducking server超时时间
  12. timeout : 3
  • 实体提取示例:
  1. {
  2. "entities": [{"end": 53,
  3. "entity": "time",
  4. "start": 48,
  5. "value": "2017-04-10T00:00:00.000+02:00",
  6. "confidence": 1.0,
  7. "extractor": "DucklingHTTPExtractor"}]
  8. }

九、Rasa NLU Pipline

9.1 动机

  • 动机:前面介绍了怎么多 组件(Component),问题来了:怎么多 招式,我们需要怎么搭配 才能 治敌呢?
  • 解答:本节将继续讲解如何使用这些组件将准备好的样本数据(nlu.md)训练得到NLU模型

9.2 介绍

在Rasa NLU模块中,提供了一种名为Pipline(管道)配置方式,传入的消息(Message)通过管道中一系列组件处理后得到最终的模型。管道(Pipline)由多个组件(Component)构成,每个组件有各自的功能,比如实体提取、意图分类、响应选择、预处理等,这些组件在管道中一个接着一个的执行,每个组件处理输入并创建输出,并且输出可以被该组件之后管道中任何组件使用。当然,有些组件只生成管道中其他组件使用的信息,有些组件生成Output属性,这些Output属性将在处理完成后返回。下图为”pipeline”: [“Component A”, “Component B”, “Last Component”]训练时调用顺序:

2020-12-14-Rasa NLU 详解 - 图26

在Rasa NLU模块中,已为我们提供了几种模板(Template) Pipline,比如pretrained_embeddings_spacy、supervised_embeddings等,每一种Pipline组件构成不同,可以根据训练数据的特性选择使用。当然,Pipline的配置非常的灵活,我们可以自定义Pipline中的组件,实现不同特性的Pipline。

9.3 使用Template Pipline

(一)pretrained_embeddings_spacy

在config.yaml文件中配置如下:

  1. language: "en"
  2. pipeline: "pretrained_embeddings_spacy"

当然,上述配置等价于:

  1. language: "en"
  2. pipeline:
  3. - name: "SpacyNLP" # 预训练词向量
  4. - name: "SpacyTokenizer" # 文本分词器
  5. - name: "SpacyFeaturizer" # 文本特征化
  6. - name: "RegexFeaturizer" # 支持正则表达式
  7. - name: "CRFEntityExtractor" # 实体提取器
  8. - name: "EntitySynonymMapper" # 实体同义词映射
  9. - name: "SklearnIntentClassifier" # 意图分类器

pretrained_embeddings_spacy管道使用GloVe或 fastText的预训练词向量,因此,它的优势在于当你有一个训练样本如I want to buy apples,Rasa会预测意图为get pears。因为模型已经知道“苹果”和“梨”是非常相似的。如果没有足够大的训练数据,这一点尤其有用。

(二)supervised_embeddings

在config.yaml文件中配置如下:

  1. language: "en"
  2. pipeline: "supervised_embeddings"

当然,上述配置等价于:

  1. language: "en"
  2. pipeline:
  3. - name: "WhitespaceTokenizer" # 分词器
  4. - name: "RegexFeaturizer" # 正则
  5. - name: "CRFEntityExtractor" # 实体提取器
  6. - name: "EntitySynonymMapper" # 同义词映射
  7. - name: "CountVectorsFeaturizer" # featurizes文本基于词
  8. - name: "CountVectorsFeaturizer" # featurizes文本基于n-grams character,保留词边界
  9. analyzer: "char_wb"
  10. min_ngram: 1
  11. max_ngram: 4
  12. - name: "EmbeddingIntentClassifier" # 意图分类器

supervised_embeddings 管道不使用任何的预训练词向量或句向量,而是针对自己的数据集特别做的训练。它的优势是面向自己特定数据集的词向量(your word vectors will be customised for your domain),比如,在通用英语中,单词“balance” (平衡)与单词 “symmetry”(对称)意思非常相近,而与单词”cash”意思截然不同。但是,在银行领域(domain),“balance”与”cash”意思相近,而supervised_embeddings训练得到的模型就能够捕捉到这一点。该pipline不需要任何指定的语言模型,因此适用于任何语言,当然,需要指定对应的分词器。比如默认使用WhitespaceTokenizer,对于中文可以使用Jieba分词器等等,也就是该Pipline的组件是可以自定义的。

(三)pretrained_embeddings_convert

在config.yaml文件中配置如下:

  1. language: "en"
  2. pipeline: "pretrained_embeddings_convert"

当然,上述配置等价于:

  1. language: "en"
  2. pipeline:
  3. - name: "ConveRTTokenizer"
  4. - name: "ConveRTFeaturizer"
  5. - name: "EmbeddingIntentClassifier"

pretrained_embeddings_convert使用预训练的句子编码模型ConveRT以抽取用户输入句子的整体向量表征。该pipeline使用ConveRT模型抽取句子表征,并将句子表征输入到EmbeddingIntentClassifier以进行意图分类。使用pretrained_embeddings_convert的好处是不独立地处理用户输入句子中的每个词,而是为完整的句子创建上下文向量表征。比如,句子can I book a car?Rasa 会预测意图为I need a ride from my place。由于这两个示例的上下文向量表征已经非常相似,因此对它们进行分类的意图很可能是相同的。如果没有足够大的训练数据,这也很有用。需要注意的是,由于ConveRT模型仅在英语语料上进行训练,因此只有在训练数据是英语时才能够使用该pipeline。

(四)MITIE

在config.yaml文件中配置如下:

  1. language: "en"
  2. # 1. 使用SklearnIntentClassifier意图分类器
  3. # 这里的模型为英文
  4. pipeline:
  5. - name: "MitieNLP" # 预训练词向量
  6. model: "data/total_word_feature_extractor.dat"
  7. - name: "MitieTokenizer" # 分词器
  8. - name: "MitieEntityExtractor" # 实体提取器
  9. - name: "EntitySynonymMapper" # 同义词映射
  10. - name: "RegexFeaturizer" # 正则
  11. - name: "MitieFeaturizer" # 特征化
  12. - name: "SklearnIntentClassifier" # 意图分类器
  13. # 2. 使用MitieIntentClassifier意图分类器
  14. # 数据量大的时候,训练非常慢(不推荐)
  15. # pipeline:
  16. # - name: "MitieNLP"
  17. # model: "data/total_word_feature_extractor.dat"
  18. # - name: "MitieTokenizer"
  19. # - name: "MitieEntityExtractor"
  20. # - name: "EntitySynonymMapper"
  21. # - name: "RegexFeaturizer"
  22. # - name: "MitieIntentClassifier"

Rasa NLU模块支持在Pipline中使用Mitie,但是在使用前需要训练词向量,然后使用MitieNLP组件指定。MITIE后端对于小型数据集执行得很好,但是如果数据量超过几百个示例,则训练可能需要很长时间。Rasa官网不建议使用它,因为mitie支持在将来的版本中可能会被弃用。

9.4 使用Custome Pipline

(一)zh_jieba_mitie_sklearn

在config.yaml文件中配置如下:

  1. language: "zh"
  2. pipeline:
  3. - name: "MitieNLP" # 使用中文词向量模型
  4. model: "data/total_word_feature_extractor_zh.dat"
  5. - name: "JiebaTokenizer" # 使用jieba分词
  6. - name: "MitieEntityExtractor"
  7. - name: "EntitySynonymMapper"
  8. - name: "RegexFeaturizer"
  9. - name: "MitieFeaturizer"
  10. - name: "SklearnIntentClassifier"

当然,上述配置等价于:

  1. Received user message '"广州明天的天气怎么样"' with
  2. intent
  3. '{'name': 'request_weather', 'confidence': 0.5182071733645418}'
  4. and entities
  5. '[{'entity': 'address', 'value': '广州', 'start': 1, 'end': 3,
  6. 'confidence': None, 'extractor': 'MitieEntityExtractor'},
  7. {'entity': 'date-time', 'value': '明天', 'start': 3, 'end': 5, 'confidence':
  8. None,'extractor': 'MitieEntityExtractor'}]'
  9. confidence': None, 'extractor': 'MitieEntityExtractor'}
  10. ]'

由于Rasa NLU模块提供的模板Pipline主要适用于英文,假如我们需要训练中文NLU模型的话,就需要使用中文分词器,比如jieba分词器,因此,我们修改MITIE Pipline将分词器改为Jieba,并修改MitieNLP预训练词向量模型为中文模型,其他不变,如MitieEntityExtractor,SklearnIntentClassifier等。根据NLU识别结果可知,输入文本经过处理后输出的intent和entities,从而可知,intent意图识别和entities实体识别是相互独立的。

(二)zh_crf_supervised_embeddings

在config.yaml文件中配置如下:

  1. language: "zh"
  2. pipeline:
  3. - name: "JiebaTokenizer" # 使用jieba分词
  4. - name: "RegexFeaturizer"
  5. - name: "CRFEntityExtractor"
  6. - name: "EntitySynonymMapper"
  7. - name: "CountVectorsFeaturizer"
  8. - name: "CountVectorsFeaturizer"
  9. analyzer: "char_wb"
  10. min_ngram: 1
  11. max_ngram: 4
  12. - name: "EmbeddingIntentClassifier"
  • NLU识别结果示例1:
  1. Received user message '"广州明天的天气怎么样"' with
  2. intent
  3. '{'name': 'request_weather', 'confidence': 0.9965207576751709}'
  4. and entities
  5. '[{'start': 1, 'end': 3, 'value': '广州', 'entity': 'address',
  6. 'confidence': 0.4974091477686857, 'extractor': 'CRFEntityExtractor'},
  7. {'start': 3, 'end': 5, 'value': '明天', 'entity': 'date-time',
  8. 'confidence': 0.8807040793780636, 'extractor': 'CRFEntityExtractor'}]'
  • NLU识别结果示例2:
  1. Received user message '"查下138383834381的账户余额"' with
  2. intent
  3. '{'name': 'request_phone_business', 'confidence': 0.9994893074035645}'
  4. and entities
  5. '[{'start': 3, 'end': 15, 'value': '138383834381', 'entity': 'phone_number',
  6. 'confidence': 0.5848492378103071, 'extractor': 'CRFEntityExtractor'},
  7. {'start': 16, 'end': 20, 'value': '余额', 'entity': 'business',
  8. 'confidence': 0.9023286498337025, 'extractor': 'CRFEntityExtractor',
  9. 'processors': ['EntitySynonymMapper']}]'

注:该Pipline修改自模板管道supervised_embeddings,由于该模板默认支持英文,为了实现支持中文,我们将分词器由WhitespaceTokenizer改为JiebaTokenizer,其他配置不变。经过测试可知,在意图分类方面,CountVectorsFeaturizer、EmbeddingIntentClassifier组合意图提取置信度高于MitieFeaturizer、SklearnIntentClassifier组合;在实体提取方面。CRFEntityExtractor也优于MitieEntityExtractor。另外,supervised_embeddings不需要任何指定的语言模型,因此适用于任何语言,并且完全依赖于训练数据,因此训练得到的模型拥有更好的适应性,训练的时间也非常快。但是,目前我遇到的有一点就是,有可能在训练数据不足时,在实体提取时可能会出现无法提取到实体的问题,当然,这只是我的推测,有待进一步验证。

当然,除了对已有的模板Pipline进行重新组合,我们完全可以自定义Pipline中的组件,定制你想要的功能和改进每个环节,这或许就是Rasa的优秀之处,非常灵活。比如,我们只希望支持实体识别,不做意图分类,那么我们可以这样自定义一个Pipline:

  1. pipeline:
  2. - name: "SpacyNLP"
  3. - name: "CRFEntityExtractor"
  4. - name: "EntitySynonymMapper"

参考资料

  1. Rasa中文聊天机器人开发指南(2):NLU篇