Rasa
是一個開源機器學習框架,用於構建上下文AI助手和聊天機器人。 Rasa有兩個主要模塊:html
Rasa NLU
:用於理解用戶消息,包括意圖識別和實體識別,它會把用戶的輸入轉換爲結構化的數據。Rasa Core
:是一個對話管理平臺,用於舉行對話和決定下一步作什麼。Rasa X
是一個工具,可幫助您構建、改進和部署由Rasa框架提供支持的AI Assistants。 Rasa X包括用戶界面和REST API。 python
Rasa官方文檔: Build contextual chatbots and AI assistants with Rasa git
github地址:RasaHQ/rasa github
pip安裝web
pip install rasa_nlu
pip install rasa_core[tensorflow]
複製代碼
此圖顯示了使用Rasa構建的助手如何響應消息的基本步驟: 數據庫
intents
:意圖pipeline
:story
:Core model 以訓練「stories」的形式從真實的會話數據中學習。故事是用戶和助手之間的真實對話.domain
:定義了助手所處的universe:它應該得到的用戶輸入,應該可以預測的操做,如何響應以及要存儲的信息
Rasa NLU曾經是一個獨立的庫,但它如今是Rasa框架的一部分。json
Rasa_NLU是一個開源的、可本地部署並配套有語料標註工具RASA NLU Trainer。其自己可支持任何語言,中文因其特殊性須要加入特定的tokenizer
做爲整個流程的一部分。後端
Rasa NLU
用於聊天機器人中的意圖識別和實體提取。例如,下面句子:瀏覽器
"I am looking for a Mexican restaurant in the center of town"
bash
返回結構化數據:
{
"intent": "search_restaurant",
"entities": {
"cuisine" : "Mexican",
"location" : "center"
}
}
複製代碼
Rasa_NLU_Chi 做爲 Rasa_NLU 的一個 fork 版本
,加入了jieba
做爲中文的 tokenizer,實現了中文支持。
該部分簡單介紹基於 Rasa_NLU_Chi
構建一個本地部署的特定領域的中文 NLU 系統的過程。
目標
rasa nlu 支持不一樣的 Pipeline,其後端實現可支持spaCy、MITIE、MITIE + sklearn 以及 tensorflow
,其中 spaCy 是官方推薦的,另外值得注意的是從 0.12 版本後,MITIE 就被列入 Deprecated 了。
本例使用的 pipeline 爲 MITIE+Jieba+sklearn
, rasa nlu 的配置文件爲 config_jieba_mitie_sklearn.yml
以下:
language: "zh"
pipeline:
- name: "nlp_mitie"
model: "data/total_word_feature_extractor_zh.dat" // 加載 mitie 模型
- name: "tokenizer_jieba" // 使用 jieba 進行分詞
- name: "ner_mitie" // mitie 的命名實體識別
- name: "ner_synonyms"
- name: "intent_entity_featurizer_regex"
- name: "intent_featurizer_mitie" // 特徵提取
- name: "intent_classifier_sklearn" // sklearn 的意圖分類模型
複製代碼
因爲在pipeline中使用了MITIE
,因此須要一個訓練好的MITIE模型(先進行中文分詞)。MITIE模型是非監督訓練獲得的,相似於word2vec中的word embedding
,須要大量中文語料,訓練該模型對內存要求較高,而且很是耗時,直接使用網友分享的中文的維基百科和百度百科語料生成的模型文件。
連接:pan.baidu.com/s/1kNENvlHL… 密碼:p4vx
獲得MITIE詞向量模型以後,就可使用標註好語料訓練Rasa NLU模型。 Rasa提供了數據標註平臺: rasa-nlu-trainer
那標註好的數據是什麼樣的呢?
標註好的語料存儲在json
文件中,具體格式以下所示,包含text
, intent
,entities
,實體中start
和end
是實體對應在text
中的起止index
。
以data/examples/rasa/demo-rasa_zh.json
爲例:
{
"rasa_nlu_data": {
"common_examples": [
{
"text": "你好",
"intent": "greet",
"entities": []
},
{
"text": "我想找地方吃飯",
"intent": "restaurant_search",
"entities": []
},
{
"text": "我想吃火鍋啊",
"intent": "restaurant_search",
"entities": [
{
"start": 2,
"end": 5,
"value": "火鍋",
"entity": "food"
}
]
}
]
}
}
複製代碼
到目前,已經獲取了訓練所需的標註好的語料,以及詞向量模型MITIE文件。接下來就能夠訓練Rasa_NLU模型了。
插一句 安裝:
$ git clone https://github.com/crownpku/Rasa_NLU_Chi.git // clone 源碼
$ cd Rasa_NLU_Chi
$ python setup.py install // 安裝依賴
複製代碼
模型訓練命令
python -m rasa_nlu.train -c sample_configs/config_jieba_mitie_sklearn.yml --data data/examples/rasa/demo-rasa_zh.json --path models --project nlu
複製代碼
所需參數:
-c
--data
--path
--project
模型訓練完成後,會在--path
指定的路徑下保存訓練好的模型文件,若是訓練時指定了模型名稱(即--project),模型就會存儲在models/project_name/model_**
目錄中,如models/chat_nlu_test/model_20190821-160150
結構以下:
python -m rasa_nlu.server -c sample_configs/config_jieba_mitie_sklearn.yml --path models
複製代碼
curl -XPOST localhost:5000/parse -d '{"q":"明每天氣預報", "project":"nlu", "model":"model_20190821-160150"}'
複製代碼
結果以下:
Rasa Core是用於構建AI助手的對話引擎,是開源Rasa框架的一部分。
Rasa Core消息處理流程 由前面描述的對話管理模塊瞭解到,它應該是負責協調聊天機器人的各個模塊,起到維護人機對話的結構和狀態的做用。對話管理模塊涉及到的關鍵技術包括對話行爲識別、對話狀態識別、對話策略學習以及行爲預測、對話獎勵等。下面是Rasa Core消息處理流程:
Interpreter
(NLU模塊),該模塊負責識別Message中的"意圖(intent)「和提取全部"實體」(entity)數據;Tracker
對象,該對象的主要做用是跟蹤會話狀態(conversation state);policy
記錄Tracker
對象的當前狀態,並選擇執行相應的action
,其中,這個action是被記錄在Track對象中的;Rasa Core包含兩個內容: stories
和domain
。
domain.yml
:包括對話系統所適用的領域,包含意圖集合,實體集合和相應集合story.md
:訓練數據集合,原始對話在domain中的映射。stories能夠理解爲對話的場景流程,咱們須要告訴機器咱們的多輪場景是怎樣的。Story樣本數據就是Rasa Core對話系統要訓練的樣本,它描述了人機對話過程當中可能出現的故事情節,經過對Stories樣本和domain的訓練獲得人機對話系統所需的對話模型。
Stories存儲在md文件中。story的符號說明以下:
符號 | 說明 |
---|---|
## | sotry標題 |
* | 意圖和填充的slot |
- | 動做 |
示例:
## simple_story_with_multiple_turns
* affirm OR thank_you
- utter_default
* goodbye
- utter_goodbye
> check_goodbye ## story_04649138 * greet - utter_ask_howcanhelp * inform{"location": "london", "people": "two", "price": "moderate"} - utter_on_it - utter_ask_cuisine * inform{"cuisine": "spanish"} - utter_ask_moreupdates * inform{"cuisine": "british"} - utter_ask_moreupdates * deny - utter_ack_dosearch - action_search_restaurants - action_suggest * affirm - utter_ack_makereservation * thankyou - utter_goodbye 複製代碼
如上所示,幾個須要注意的點:
> check_*
: 用於模塊化和簡化訓練數據,即story複用。OR
:用於處理同一個story中可能出現2個以上意圖,這有利於簡化story,可是相應的訓練時間等於訓練了兩個以上的故事,不建議密集使用。Rasa Core中提供了rasa_core.visualize
模塊可視化故事,有利於掌握設計故事流程。
命令:
python -m rasa_core.visualize -d domain.yml -s data/sotries.md -o graph.html -c config.yml
複製代碼
參數:
-m
:指定運行模塊-d
:指定domain.yml文件路徑-s
:指定story路徑-o
:指定輸出文件名-c
:指定Policy配置文件。最終,在項目根目錄下獲得一個graph.html
,可用瀏覽器打開。
具體實現,可參考源代碼rasa/core/visualize.py
。
domain.yml定義了對話機器人應知道的全部信息,至關於大腦框架,指定了意圖intents
, 實體entities
, 插槽slots
以及動做actions
。 其種,intents
和entities
與Rasa NLU模型訓練樣本中標記的一致。slot
與標記的entities
一致,actions
爲對話機器人對應用戶的請求做出的動做。 此外,domain.yml中的templates
部分針對utter_
類型action
定義了模板消息,便於對話機器人對相關動做自動回覆。
項 | 說明 |
---|---|
intents |
意圖 |
entities |
實體信息 |
slots |
詞槽,對話中想要跟蹤的信息 |
actions |
機器人做出的動做 |
templates |
回覆的模板語句 |
使用-
符號表示每一個意圖
intents:
- greet
- goodbye
- search_weather
複製代碼
實體,即樣本中標出的全部entity
entities:
- city
複製代碼
插槽是機器人的記憶。它們充當鍵值存儲器,其可用於存儲用戶提供的信息(例如,他們的家鄉)以及關於外部世界收集的信息(例如,數據庫查詢的結果)。 以天氣查詢爲例,對話機器人必須知道地點和日期才能夠查詢,所以在domain.yml中須要在slots部分定義兩個插槽,即city
和datatime
,而matches
則用來存儲最後查詢的結果。示例以下:
slots:
city:
type: text
initial_value:"北京"
datatime:
type:text
initial_value:"明天"
matches:
type:unfeaturized
initial_value:"none"
複製代碼
Slot Types類型:
Text Slot
:文本Boolean Slot
:布爾值Categorical Slot
:接受枚舉所列的值slots:
risk_level:
type: categorical
values:
- low
- medium
- high
複製代碼
Float Slot
:浮點型slots:
temperature:
type: float
min_value: -100.0
max_value: 100.0
複製代碼
Defaults: max_value=1.0, min_value=0.0
設置max_value和min_value後,大於max_value和小於min_value的值被設爲max_value和min_value。List Slot
:列表型數據,且長度不影響對話Unfeaturized Slot
:存儲不影響會話流程的數據。若是值自己很重要,請使用categorical
或bool
槽。還有float
和list slots
。若是您只想存儲一些數據,但不但願它影響會話流,請使用unfeaturized
的插槽。type
表示slot存儲的數據類型,initial_value
爲slot初始值,該值無關緊要(無心義)。
slots:
name:
type: text
initial_value: "human"
matches:
type:unfeaturized
複製代碼
當Rasa NLU識別到用戶輸入信息的意圖後,Rasa Core對話管理模塊會對其做出迴應,迴應的操做就是action。 Rasa Core支持三種action:
utter_
爲開頭,只發送一條信息給用戶做爲反饋的動做。 定義很簡單,只需在domain.yml文件中的actions:
字段定義以utter_
爲開頭便可。具體的回覆內容將被定義在templates
部分。若是沒有utter_
這個前綴,那麼action就會被識別爲custom actions。actions:
- utter_greet
- utter_cheer_up
複製代碼
domain.yml
文件中的actions
部分先定義,而後在指定的webserver
中實現它。其中,webserver的url
地址在endpoint.yml
文件中指定。 官方提供了一個小的python sdk來方便用戶編寫自定義的action,首先須要安裝一下對應的rasa_core_sdk
。後續再講。。actions:
- action_search_weather
複製代碼
這次定義了utter actions
具體的回覆內容,且每一個utter actions
下能夠定義多條回覆信息。當用戶發起一個意圖,好比"你好!",就觸發utter_greet
操做,Rasa Core會從該action的模板中自動選擇其中的一條信息做爲結果反饋給用戶。
templates:
utter_greet:
- text: "您好!請問我能夠幫到您嗎?"
- text: "您好!請說出您要查詢的具體業務,好比跟我說'查詢身份證號碼'"
- text: "您好!"
複製代碼
utter_default
是Rasa Core默認的action_default_fallback
,當Rasa NLU識別該意圖時,它的置信度低於設定的閾值時,就會默認執行utter_default中的模板。
除了回覆簡單的Text Message,Rasa Core還支持在Text Message後添加按鈕和圖片,以及訪問插槽中的值(若是該插槽的值有被填充的話,不然返回None)。舉個例子:
utter_introduce_self:
- text: "您好!我是您的AI機器人呀~"
image: "https://i.imgur.com/sayhello.jpg"
utter_introduce_selfcando:
- text: "我能幫你查詢天氣信息"
buttons:
- title: "好的"
payload: "ok"
- title: "不了"
payload: "no"
utter_ask_city:
- text: "請問您要查詢{ datetime }哪裏的天氣?"
utter_ask_datetime:
- text: "請問您要查詢{ city }哪天的天氣"
複製代碼
一個示例:
intents:
- greet
- goodbye
- affirm
- deny
- search_weather
slots:
city:
type: text
matches:
type: unfeaturized
entities:
- city
actions:
- utter_greet
- utter_cheer_up
- utter_did_that_help
- utter_happy
- utter_goodbye
templates:
utter_greet:
- text: "Hey! How are you?"
utter_cheer_up:
- text: "Here is something to cheer you up:"
image: "https://i.imgur.com/nGF1K8f.jpg"
utter_did_that_help:
- text: "Did that help you?"
utter_happy:
- text: "Great carry on!"
utter_goodbye:
- text: "Bye"
utter_default:
- text: "小x還在學習中,請換種說法吧~"
- text: "小x正在學習中,等我升級了您再試試吧~"
- text: "對不起,主人,您要查詢的功能小x還沒學會呢~"
複製代碼
準備好domain.yml和sotries.md數據以後,就能夠進行模型的訓練了。 模型的輸入數據是歷史對話記錄,lable是下一個決策action。模型本質上是num_actions個類別的多分類。
訓練命令以下:
python -m rasa_core.train -d domain.yml -s stories.md -o models/chat1
複製代碼
參數解釋:
-d或--domain
:指domain.yml文件的路徑-s或--stories
:指定stories.md文件路徑。能夠將故事請假保存在一個md文件中,也能夠分類保存在多個md文件中(存放到一個目錄下)-o或--out
:指對話模型的輸出路徑,保存訓練好的模型文件-c或--c
:指定Policy規範文件訓練所需數據示例:
intent:
- greet
- goodbye
- search_weather
entities:
- city
actions:
- utter_greet
- utter_goodbye
- utter_ask_city
templates:
utter_greet:
- text: "你好啊"
- text: "又見面了"
utter_goodbye:
- text: "再見"
- text: "下次再見啊"
utter_ask_city:
- text: "請問您要查詢哪裏的天氣?"
複製代碼
## search weather
* greet
- utter_greet
* search_weather{ "datatime" : "明天"}
- utter_ask_city
* goodbye
- utter_goodbye
複製代碼
訓練網絡結構:
生成模型文件以下:通過訓練,咱們已經獲得了對話模型,那如今咱們就來測試一下。
測試命令以下:
python -m rasa_core.run -d models/chat1
複製代碼
參數-d
:指定模型路徑
注:此時測試rasa_core對話模型,並無加入core_nlu模型,所以還沒法進行意圖識別,只可以根據已知的意圖(輸入意圖)返回特定的答案。所以,咱們測試的時候,須要手動輸入在domain.yml中定義好的意圖,輸入意圖以/
符號開頭。 如輸入greet意圖:/greet
經過前面的步驟,已經訓練了Rasa_nlu的意圖識別模型和Rasa_Core的對話模型。接下來就進行二者的總體的測試。
測試命令 python -m rasa_core.run -d models/chat1 -u models/nlu/model_20190820-105546
參數解釋;
-d
:modeldir 指定對話模型路徑(即Rasa_core訓練的模型路徑)-u
:Rasa NLU訓練的模型路徑--port
:指定Rasa Core Web應用運行的端口號--credentials
:指定通道(input channels)屬性endpoints
:用於指定Rasa Core鏈接其餘web server的url地址,好比nlu web-o
:指定log日誌文件輸出路徑--debug
:打印調試信息參考博文: