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,世紀佳緣讓對話無處不在
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章