Rasa入门——AI助手和聊天机器人

简介

Rasa是一套开源机器学习框架,用于构建基于上下文的聊天机器人

Rasa有两个主要模块:Rasa NLU用于理解用户消息;Rasa Core用于管理对话

Rasa提供了一套交互工具RasaX,帮助用户部署聊天机器人




安装

pip install rasa-x -i https://pypi.rasa.com/simple

直接pip会报错:pip install rasa-x

Rasa使用TensorFlow2,请谨慎安装。

Rasa需要Python 3.5.3+

Rasa版本1.7到1.8区别较大,具体查看迁移指南




初试

创建项目:rasa init --no-prompt

在这里插入图片描述

启动对话:rasa shell

在这里插入图片描述
退出:/stop

新一轮对话:/restart

带置信度:rasa shell nlu

Next message:
Hi
{
  "intent": {
    "name": "greet",
    "confidence": 0.9438605904579163
  },
  "entities": [],
  "intent_ranking": [
    {
      "name": "greet",
      "confidence": 0.9438605904579163
    },
    {
      "name": "bot_challenge",
      "confidence": 0.023507937788963318
    },
    {
      "name": "deny",
      "confidence": 0.015569652430713177
    },
    {
      "name": "mood_unhappy",
      "confidence": 0.006939413491636515
    },
    {
      "name": "affirm",
      "confidence": 0.004430832341313362
    },
    {
      "name": "mood_great",
      "confidence": 0.0033575778361409903
    },
    {
      "name": "goodbye",
      "confidence": 0.0023339807521551847
    }
  ],
  "text": "Hi"
}

Debug模式:rasa shell --debug

可视化:rasa x
在这里插入图片描述

启动Rasa API服务:rasa run --enable-api

允许跨域:rasa run --enable-api --cors "*"

Python调用Rasa API服务(不要命名为test.py)

import json
import requests

url = "http://localhost:5005/model/parse"
data = {"text": "hello"}
data = json.dumps(data, ensure_ascii=False)
data = data.encode(encoding="utf-8")  # 如果text带中文需要转编码
r = requests.post(url=url, data=data)
print(json.loads(r.text))

结果

{'intent': {'name': 'greet', 'confidence': 0.9930983185768127}, 'entities': [], 'intent_ranking': [{'name': 'greet', 'confidence': 0.9930983185768127}, {'name': 'mood_unhappy', 'confidence': 0.0036425672005861998}, {'name': 'bot_challenge', 'confidence': 0.002293727360665798}, {'name': 'mood_great', 'confidence': 0.00035825479426421225}, {'name': 'goodbye', 'confidence': 0.00032570294570177794}, {'name': 'affirm', 'confidence': 0.00022301387798506767}, {'name': 'deny', 'confidence': 5.849302760907449e-05}], 'text': 'hello'}

启动Action:rasa run actions




其他命令

查看所有命令:rasa -h

交互式运行:rasa interactive,运行过程中可视化查看到哪一步http://localhost:5006/visualization.html

在这里插入图片描述

转换为JSON格式:rasa data convert nlu --data data/nlu.md --out data/nlu.json -f json




项目文件

在这里插入图片描述

文件 用途
data/nlu.md Rasa NLU训练数据
data/stories.md 对话管理训练数据
models/xxx-xxx.tar.gz 机器学习模型
__init__.py 帮助查找的空文件
actions.py 自定义操作
config.yml Rasa NLU和Rasa Core的配置文件
credentials.yml 连接到其他服务的信息,如接口证书
domain.yml 聊天机器人的定义
endpoints.yml 对接外部服务的信息,如fb messenger




nlu.md

部分NLU训练数据如下,intent指划分好的意图(即短文本分类的类),训练数据的格式默认使用Markdown,还可使用JSON格式

## intent:greet
- hey
- hello
- hi
- good morning
- good evening
- hey there

## intent:goodbye
- bye
- goodbye
- see you around
- see you later




stories.md

对话管理训练数据,由Rasa Code处理
Rasa Code从真实的对话数据中学习,是用户和聊天机器人之间的真实对话。
意图(intent)和实体(entity)反映用户的输入,操作(action)显示助理应如何响应。

一个简单的story:

## story1
* greet
   - utter_greet

greet是用户输入中的意图,utter_greet是助理响应的操作




config.yml

Rasa NLU和Rasa Core的配置文件,定义模型使用的NLU和Core组件,如NLU使用的pipeline(传递过程)是supervised_embeddings,也可以选择其他pipeline

language: en
pipeline: supervised_embeddings
policies:
- name: MemoizationPolicy
- name: KerasPolicy
- name: MappingPolicy




domain.yml

聊天机器人的定义

能够理解哪些意图和实体,用什么对话或自定义动作来响应,在对话过程中应该记住哪些信息,在特定上下文中使用这些信息

intents:
- greet
templates:
  utter_greet:
  - text: Hey! How are you?
actions:
- utter_greet
构成 含义
intents 意图
actions 操作
templates 回答模板
entities 实体
slots 词槽

Rasa Core在每一步对话选择正确的操作

示例中的操作是反馈一条消息,聊天机器人会根据templates返回一条消息

除发消息外,还可构建其他操作,参阅自定义操作

忽略实体

intents:
- greet:
    use_entities:
      - name
      - first_name
    ignore_entities:
      - location
      - age

触发动作

intents:
  - greet: {triggers: action_greet}
  - bye
  - thank
  - faq
  - contact_sales
  - inform

actions:
  - action_greet




actions.py

  1. 官方提供了sdk方便用户编写自定义action
  2. actions.py自定义操作
from rasa_sdk import Action
from rasa_sdk.events import SlotSet


class ActionAskWeather(Action):
    def name(self):
        return 'action_ask_weather'

    def run(self, dispatcher, tracker, domain):
        dispatcher.utter_message(f'您问的天气地点是哪里呢')
        return [SlotSet('city', '深圳')]
  1. domain.yml添加意图、实体、槽位、模板和操作
intents:
- ask_weather
- weather_state
entities:
- city
slots:
  city:
    type: text
templates:
  utter_weather_good:
    - text: "{city}天气很好呢"
actions:
- action_ask_weather
- utter_weather_good
  1. nlu.md添加数据
## intent:ask_weather
- 今天天气怎么样
- 今天天气

## intent:weather_city
- 深圳
  1. stories.md添加数据
## story_ask_weather 
* ask_weather
  - action_ask_weather
* weather_city
  - utter_weather_good
  1. endpoints.yml开启服务
action_endpoint:
  url: "http://localhost:5055/webhook"
  1. config.yml设为中文
language: zh
pipeline: tensorflow_embedding
  1. 重新训练rasa train
  2. 启动rasa shell --endpoints endpoints.yml




训练模型

每当添加新的NLU或Core,或更新domains、config时,都需要重新训练

训练模型:rasa train

数据增强:rasa train --augmentation 20




Rasa组成

1. Rasa NLU

实现自然语言理解(即NLU)功能,本质上就是识别句子的意图和实体。

如“买一张去北京的票”,那么可以定义意图是“购票”,实体是“北京”和“一张”。

Rasa NLU主要使用各种开源技术,并没有追求SOTA,包括Spacysklearn-crfsuite



2. Rasa Code

Rasa的核心部分,主要完成基于故事的对话管理,包括解析故事并生成对话系统中的对话管理模型(Dialog Management),输出系统决策(System Action/System Policy)。

这部分包含两个模型:

  1. 对话状态跟踪(Dialog State Tracking / Belief Tracking)
  2. 对话策略(Dialog Policy / Policy Optimization)

对于1,Rasa实现很简单,就是简单地基于策略的槽状态替换。
对于2,Rasa使用基于LSTM的排序学习,大体上是将当前轮用户意图、上一轮系统行为、当前槽值状态向量化,然后与所有系统行为做相似度学习,以此决定当前轮次的一个或多个系统行为

在这里插入图片描述

3. Rasa X

Rasa的可视化编辑工具

传递过程

在这里插入图片描述

  1. 用户输入,送入Rasa NLU
  2. NLU给出结果
  3. Tracker用于跟踪对话状态,输出Embedding
    用户意图的Embedding
    上一步系统动作的Embedding
    实体的Embedding
  4. Policy输出系统行为
  5. Tracker记录系统行为,下一次提供给Policy使用
  6. 返回消息给用户






综合示例

  1. Python Rasa构建天气查询机器人
  2. Rasa官方示例综合解析









自然语言处理组件

pipeline定义了输入到输出经过哪些处理,如:

在这里插入图片描述

词向量

  1. MitieNLP
  2. SpacyNLP
  3. HFTransformersNLP

分词器

  1. WhitespaceTokenizer:空格分词器
  2. JiebaTokenizer:结巴分词器
  3. MitieTokenizer:MITIE分词器
  4. SpacyTokenizer:spaCy分词器
  5. ConveRTTokenizer:ConveRT分词器
  6. LanguageModelTokenizer

特征提取器

  1. MitieFeaturizer:MITIE特征提取器
  2. SpacyFeaturizer:spaCy特征提取器
  3. ConveRTFeaturizer:ConveRT特征提取器
  4. LanguageModelFeaturizer
  5. RegexFeaturizer:正则表达式特征提取器
  6. CountVectorsFeaturizer:词袋模型特征提取器,结合用户消息、意图和响应
  7. LexicalSyntacticFeaturizer:词法语法特征提取器

意图分类器

  1. MitieIntentClassifier:MITIE意图分类器
  2. SklearnIntentClassifier:Sklearn意图分类器
  3. EmbeddingIntentClassifier:嵌入意图分类器(即将被DIETClassifier替代)
  4. KeywordIntentClassifier:关键词意图分类器,适合小项目
  5. DIETClassifier:意图分类和实体提取的双向转换器

实体提取器

  1. MitieEntityExtractor:MITIE实体提取器
  2. SpacyEntityExtractor:spaCy实体提取器
  3. EntitySynonymMapper:同义词匹配实体提取器
  4. CRFEntityExtractor:条件随机场实体提取器
  5. DucklingHTTPExtractor:常见实体提取器
  6. DIETClassifier:意图分类和实体提取的双向转换器

选择器

  1. ResponseSelector:响应选择器

合并的实体提取器和意图分类器

  1. DIETClassifier:意图分类和实体提取的双向转换器




对话策略

1. Memoization Policy

记忆策略只记录训练数据中的对话

若训练数据存在这样的对话,则以置信度1.0预测下一个动作,否则以0.0预测

一般不单独使用

2. Mapping Policy

映射策略将意图映射为操作

无视之前对话,一旦触发意图就操作

映射是传递intent属性给triggers实现的,修改domain.yml

intents:
  - ask_is_bot:
    triggers: action_is_bot

一般不单独使用

3. Keras Policy

Keras策略使用神经网络预测下一步操作,默认基于LSTM

4. Embedding Policy (TEDP)

Rasa的最新技术,在多轮对话中表现比Keras Policy好

与其他RNN机器学习算法不同,它利用transformer学习模式并进行预测。能更好处理不同语料库间的低纠缠,能更好地处理意外的用户输入,如闲聊

5. Form Policy

表单策略,收集指定信息,如性别年龄地址

需要实现FormAction,在domain.yml中指定,在stories.md中使用

from rasa_sdk import Tracker
from rasa_sdk.forms import FormAction
from typing import Dict, Text, Any, List
from rasa_sdk.executor import CollectingDispatcher


class FacilityForm(FormAction):
    def name(self) -> Text:
        return "facility_form"

    @staticmethod
    def required_slots(tracker: Tracker) -> List[Text]:
        return ["facility_type", "location"]

    def slot_mappings(self) -> Dict[Text, Any]:
        return {"facility_type": self.from_entity(entity="facility_type", intent=["inform", "search_provider"]),
                "location": self.from_entity(entity="location", intent=["inform", "search_provider"])}

    def submit(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict]:
        location = tracker.get_slot('location')
        facility_type = tracker.get_slot('facility_type')
        dispatcher.utter_button_message("Here is home health agency near you")
        return []
forms:
- facility_form

6. Fallback Policy

回退策略,聊天机器人不可避免需要的回退情况,例如用户问了让机器人理解不了的东西时需要回退

需要提供阈值

policies:
  - name: FallbackPolicy
    nlu_threshold: 0.3
    ambiguity_threshold: 0.1
    core_threshold: 0.3
    fallback_action_name: 'action_default_fallback'
参数 含义
nlu_threshold 接受的最低置信度
ambiguity_threshold 最高置信度的意图超过第二意图的最小值
core_threshold 进行操作的最低置信度
fallback_action_name 置信度低于阈值要调用的回退操作

7. Two-Stage Fallback Policy

不直接回退而是让用户选,尝试消除用户输入的歧义,从而在多个阶段处理NLU可信度较低的问题。

nlu.md和domain.yml意图要有out_of_scope

在这里插入图片描述
需要提供阈值

policies:
  - name: TwoStageFallbackPolicy
    nlu_threshold: 0.3
    ambiguity_threshold: 0.1
    core_threshold: 0.3
    fallback_core_action_name: "action_default_fallback"
    fallback_nlu_action_name: "action_default_fallback"
    deny_suggestion_intent_name: "out_of_scope"
参数 含义
nlu_threshold 接受的最低置信度
ambiguity_threshold 最高置信度的意图超过第二意图的最小值
core_threshold 进行操作的最低置信度
fallback_core_action_name 置信度低于core_threshold调用的回退操作,这个动作指出识别的意图
fallback_nlu_action_name 置信度低于nlu_threshold调用的回退操作,当用户第二次拒绝时调用
deny_suggestion_intent_name 用户拒绝的意图的名称




验证模型

交叉验证rasa test nlu -u data/nlu.md --config config.yml --cross-validation

2020-01-22 15:18:54 INFO     rasa.test  - CV evaluation (n=5)
2020-01-22 15:18:54 INFO     rasa.test  - Intent evaluation results
2020-01-22 15:18:54 INFO     rasa.nlu.test  - train Accuracy: 1.000 (0.000)
2020-01-22 15:18:54 INFO     rasa.nlu.test  - train F1-score: 1.000 (0.000)
2020-01-22 15:18:54 INFO     rasa.nlu.test  - train Precision: 1.000 (0.000)
2020-01-22 15:18:54 INFO     rasa.nlu.test  - test Accuracy: 0.605 (0.156)
2020-01-22 15:18:54 INFO     rasa.nlu.test  - test F1-score: 0.584 (0.131)
2020-01-22 15:18:54 INFO     rasa.nlu.test  - test Precision: 0.622 (0.101)

更多详情查看Evaluating Models




标注工具

RASA NLU Trainer

在这里插入图片描述
下载为JSON格式




槽位类型

  1. Text:文本
  2. Boolean:布尔型
  3. Categorical:多个值中的一个
  4. Float:浮点数
  5. List:
  6. Unfeaturized:不影响对话的数据




中文系统

Rasa构建中文系统




遇到的坑

  1. 训练数据JSON格式实体entity为中文,报错UnicodeEncodeError: 'ascii' codec can't encode characters,entity命名应使用英文
  2. 根目录不要有文件test.py,启动API服务时会运行该文件,可能会报错
  3. 项目名不要带中文,启动Rasa X时可能报错
  4. YAML文件涉及字符串最好用"包围起来,特别为了调用Rasa API时。如- payload: "/inform{\"gender\": \"男\"}"
  5. 一个Form激活时输入了无关数据报错Failed to extract slot xxx with action xxx_form,可在Stories中添加action_deactivate_form停止




官方视频

  1. Rasa官方教程——构建上下文聊天机器人




参考文献

  1. Rasa Tutorial
  2. Rasa介绍 对话系统、产品与技术
  3. rasa对话系统踩坑记
  4. Rasa使用指南01
  5. Rasa使用指南02
  6. Rasa 入坑指南一:初识 Rasa
  7. Learn how to Build a Chatbot in Minutes using Rasa
  8. Rasa 入门教程 NLU 系列
  9. Rasa Masterclass Developing Contextual AI assistants with Rasa tools
  10. 使用 Rasa NLU 构建一个中文 ChatBot
  11. 基于rasa的对话系统搭建(上)
  12. 使用 Rasa 构建天气查询机器人
  13. 使用rasa构建任务型聊天机器人
  14. python - How to send POST request?
  15. NLU server - ParsingError · Issue #4024
  16. Configuring the HTTP API
  17. Rasa HTTP API
  18. Rasa中文聊天机器人开发指南(2):NLU篇
  19. 默认动作




相关产品

  1. Wit.ai,自然语言处理接口
  2. Dialogflow,Google建立自然和丰富的对话体验
  3. LUIS,Microsoft语言理解
  4. UNIT,百度智能对话定制与服务平台
  5. 一个AI,世纪佳缘让对话无处不在
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章