Rasa2 NLU 架構及源碼解析(三)
神州信息
李丹 鄭飛 杜昕宸 韓彤 秦帥帥
Rasa是當前智能機器人中最流行的的聊天機器人框架,是基于機器學(xué)習和自然語(yǔ)言處理技術(shù)開(kāi)發(fā)的系統,用于構建上下文AI助手和聊天機器人。
1.
背景
近年來(lái),聊天機器人受到了學(xué)術(shù)界和工業(yè)界的廣泛關(guān)注。人工智能技術(shù)的快速發(fā)展突破了聊天機器人原有的技術(shù)瓶頸,并且實(shí)踐證明,聊天機器人的使用不僅能夠為企業(yè)減少一大筆人力成本,而且能夠明顯提高工作效率,國內外多家企業(yè)紛紛布局聊天機器人行業(yè)。微軟推出了基于情感計算的聊天機器人小冰,百度推出了用于交互式搜索的聊天機器人小度,進(jìn)而推動(dòng)了聊天機器人產(chǎn)品化的發(fā)展。聊天機器人系統可以看作是機器人產(chǎn)業(yè)與“互聯(lián)網(wǎng)+”的結合,符合國家的科研及產(chǎn)業(yè)化發(fā)展方向。
隨著(zhù)人工智能在銀行和金融科技的客戶(hù)服務(wù)方面取得了重大改進(jìn),客戶(hù)越來(lái)越習慣于獲得快速響應。金融機構必須全天候回答客戶(hù)問(wèn)題和進(jìn)行交易。金融機構業(yè)務(wù)擴展的加速使人工客服的成本大幅攀升的同時(shí)又無(wú)法持續滿(mǎn)足服務(wù)質(zhì)量,人工智能機器人通過(guò)金融機構長(cháng)期積累的業(yè)務(wù)經(jīng)驗和數據培訓聊天機器人,可明顯改善客戶(hù)體驗?;谏鲜鐾袋c(diǎn)和需求,各類(lèi)聊天機器人框架應運而生。根據社區活躍度、技術(shù)的成熟完備度及被引用、點(diǎn)贊等指標,我們采用Rasa作為人機交互對話(huà)機器人基本框架。
2.
Rasa簡(jiǎn)介
Rasa Open Source有兩個(gè)主要模塊:
●Rasa NLU :用于理解用戶(hù)消息,包括意圖識別和實(shí)體識別。以pipeline的方式處理用戶(hù)對話(huà),可在config.yml中配置。
●Rasa Core:主要負責對話(huà)管理。根據NLU輸出的信息、以及Tracker記錄的歷史信息,得到上下文的語(yǔ)境,從而預測用戶(hù)當前步最可能執行哪一個(gè)action。
其中,Rasa NLU主要依賴(lài)自然語(yǔ)言處理技術(shù),是可以獨立的、與整體框架解耦的模塊,可支持大量NLP前沿技術(shù),以組件的形式,可以靈活與其他開(kāi)源、自研框架搭配使用。
3.
Rasa NLU架構及源碼解析
3.3 Custom Component案例
3.3.1自定義組件方式
●拆分方式:將分詞、特征化、模型等部分進(jìn)行解耦,以TextCNN意圖識別模型為例
●整體打包方式:將模型的各部分封裝一起,只對外暴露個(gè)別接口,以JointBert意圖和實(shí)體聯(lián)合識別模型為例
3.3.2拆分方式
3.3.2.1簡(jiǎn)介
TextCNN做意圖識別,以拆分的方式進(jìn)行自定義組件,以字作為單位,不用分詞。只需拆分成:featurizer和 classifier兩部分。
3.3.2.2組件介紹
●Featurizer:
components.user_featurizer.UserFeaturizer
主要功能:構建字典,獲取字到id的映射,得到句子的id 列表。
主要參數:
訓練流程:
components的train函數 -> 構建字典:基于最小詞頻和詞典最大容量 -> 遍歷所有的訓練數據 -> 得到句子的id列表 -> 實(shí)例化特征類(lèi)Features - > message設置
預測流程:
components的process函數 -> 獲取句子id列表 -> 實(shí)例化Features設置message
●Classifier:
components.user_intent.UserIntentClassifier
主要功能:利用TextCNN進(jìn)行意圖分類(lèi)
主要參數:
訓練流程:
components的train函數 -> 過(guò)濾掉空的examples -> 獲取字典大小 -> 獲取label -> 構建label2id dict-> 構建模型網(wǎng)絡(luò ) -> model.train
預測流程:
components的process函數 -> 獲取句子id list -> 調用predict函數預測 -> _get_ranking 對結果進(jìn)行排序 -> 保存到message
注意:兩個(gè)組件之間的依賴(lài)關(guān)系,相關(guān)信息的傳遞,例如:詞典大小,無(wú)法在classifier中當作參數配置,只能根據featurizer中構建詞典的結果得到。這里通過(guò)在featurizer中構建字典之后保存到message中,在classifier中通過(guò)message獲取。
3.3.2.3使用樣例
注意:樣例僅配置了NLU部分,訓練時(shí)使用rasa train nlu,測試時(shí)使用rasa shell nlu。
domain中的意圖:
配置文件config:
運行樣例:
{
"text": "收不到余額變動(dòng)提醒怎么辦",
"intent": {
"name": "personal_bank",
"confidence": 0.9055530429
},
"entities": [],
"intent_ranking": [
{
"intent": "personal_bank",
"confidence": 0.9055530429
},
{
"intent": "finance_investment",
"confidence": 0.0601818413
},
{
"intent": "personal_finance",
"confidence": 0.033517994
},
{
"intent": "corporate_bank",
"confidence": 0.0006058206
},
{
"intent": "other",
"confidence": 0.0001413494
}
]
}
3.3.3整體打包方式
3.3.3.1簡(jiǎn)介
JointBert意圖和詞槽聯(lián)合識別,以整體打包的方式進(jìn)行自定義組件,包放在src/smartintslotpretrain,對外暴露三個(gè)函數即可,分別為:訓練train, 預測eval, 模型加載load_model。
3.3.3.2組件介紹
聯(lián)合識別組件:
components.jointbert_intent_slot.JointBertIntentSlot
主要功能:進(jìn)行意圖和詞槽的聯(lián)合識別
主要參數:
訓練流程:
JointBert作為外部包,提供三個(gè)接口,訓練train, 加載load_model,預測eval。
component的train函數 -> 通過(guò)transfer_data進(jìn)行數據格式轉換,將rasa的nlu數據轉化為JointBert所需要的數據格式(具體為:過(guò)濾空文本, auto_mark進(jìn)行實(shí)體標注,注意實(shí)體標注可能存在group和role的區分,save format data 保存為特定格式的文件)-> 調用JointBert的train.train_model進(jìn)行訓練。
數據轉化樣例:
nlu.yml中的數據:
轉換之后的數據格式:
auto_mark關(guān)鍵代碼:
注:這里只標注了存在role的情況,如果存在group可按同樣的方式進(jìn)行添加。
預測流程:
components的process函數 -> 文本和JointBert的模型傳入 eval.preditce_online中進(jìn)行預測,得到 intent_dict, slot_dict -> format_entity 格式化成rasa需要的entity格式-> _sort_intent_ranking 對intent進(jìn)行排序 -> message.set 進(jìn)行保存結果。
注:format_entity 為 auto_mark的逆過(guò)程,這兩部分需要對齊。
以打包方式進(jìn)行組件編寫(xiě)的方式關(guān)鍵有三點(diǎn):
●合理的提供模型的三個(gè)接口:訓練、模型加載、預測
●rasa數據到模型數據的轉換,不同模型訓練源碼需要的數據格式都不太相同。
●模型預測結果到rasa需要結果格式的轉換
3.3.3.3使用樣例
注意:樣例僅配置了NLU部分,訓練時(shí)使用rasa train nlu,測試時(shí)使用rasa shell nlu。
domain中的intent和entity:
配置文件config:
運行樣例:
{
"text": "今天黃金的價(jià)格是多少",
"intent": {
"name": "gold_price",
"confidence": 0.999890089
},
"entities": [
{
"entity": "date",
"value": "今天",
"start": 0,
"end": 2,
"extractor": "JointBertIntentSlot"
}
],
"intent_ranking": [
{
"intents": "gold_price",
"confidence": 0.999890089
},
{
"intents": "UNK",
"confidence": 3.54958e-05
},
{
"intents": "consume_check",
"confidence": 2.15434e-05
},
{
"intents": "currency_exchange",
"confidence": 2.13388e-05
},
{
"intents": "card_requirement",
"confidence": 1.93974e-05
},
{
"intents": "card_meterial",
"confidence": 1.20613e-05
}
]
{
"text": "10美元能兌換多少人民幣",
"intent": {
"name": "currency_exchange",
"confidence": 0.9999859333
},
"entities": [
{
"entity": "money",
"value": "10",
"start": 0,
"end": 2,
"extractor": "JointBertIntentSlot"
},
{
"entity": "currency_type",
"value": "美元",
"start": 2,
"end": 4,
"extractor": "JointBertIntentSlot",
"role": "from"
},
{
"entity": "currency_type",
"value": "人民幣",
"start": 9,
"end": 12,
"extractor": "JointBertIntentSlot",
"role": "to"
}
],
"intent_ranking": [
{
"intents": "currency_exchange",
"confidence": 0.9999859333
},
{
"intents": "UNK",
"confidence": 4.3686e-06
},
{
"intents": "gold_price",
"confidence": 3.5197e-06
},
{
"intents": "consume_check",
"confidence": 2.3771e-06
},
{
"intents": "card_meterial",
"confidence": 1.879e-06
},
{
"intents": "card_requirement",
"confidence": 1.8156e-06
}
]
}
{
"text": "6.1的黃金價(jià)格是多少",
"intent": {
"name": "gold_price",
"confidence": 0.9998868704
},
"entities": [
{
"entity": "date",
"value": "6.1",
"start": 0,
"end": 3,
"extractor": "JointBertIntentSlot"
}
],
"intent_ranking": [
{
"intents": "gold_price",
"confidence": 0.9998868704
},
{
"intents": "UNK",
"confidence": 3.81634e-05
},
{
"intents": "consume_check",
"confidence": 3.09156e-05
},
{
"intents": "currency_exchange",
"confidence": 2.11939e-05
},
{
"intents": "card_requirement",
"confidence": 1.48951e-05
},
{
"intents": "card_meterial",
"confidence": 7.9957e-06
}
]
}
3.3.4優(yōu)缺點(diǎn)
References
1. Rasa官方文檔
https://rasa.com/docs/rasa/2.x/components
2. diet介紹
https://www.yiyibooks.cn/nlp/diet/index.html
3. spaCy官方文檔
https://spacy.io/api/architectures#parser
4. Greedy transition-based parsing
https://explosion.ai/blog/parsing-english-in-python
5. spaCy v2.0命名實(shí)體識別解析
https://www.bilibili.com/video/av16282127
6.NLU自定義組件
https://puluwen.github.io/2018/12/rasa-nlu/