0
| 本文作者: hain | 2017-02-12 10:37 |
雷鋒網按:本文作者王海良,呤呤英語開發總監,北京JavaScript/Node.js開發者社區的運營者,曾就職IBM創新中心。本文為系列文章第二篇,由雷鋒網獨家首發。
第一篇傳送門:《聊天機器人的發展狀況與分類》。在上一篇文章中,介紹了聊天機器人目前的發展。本篇主要介紹基于規則的,檢索的聊天機器人引擎 - Bot Engine.
問題域
Speech to Text => Logic => Text to Speech
STT和TTS,目前有很多廠商提供技術產品:
Speech to Text 語音識別技術
Google Cloud Platform, IBM Watson API, 云知聲,科大訊飛
Text to Speech 語音合成技術
IBM Watson API Docs demo
經過多年的研究,尤其是深度學習的采用,在這兩項技術上取得了突破性進展。今天本文所要討論的是logic,而且是基于規則引擎的logic, 基于機器學習的部分將在以后的文章中討論。
Conversation Model
在兩個人之間的對話,可以用下面這個模型表示,雙方頭腦中所要向對方表達的目標,需要通過語言來交換意見,為了達成共識,二者需要在一個語境下。

為了支撐這個模型,在設計Bot Engine過程中,要考慮如下的要點:
低成本的構建對話
能區分不同類型的對話
規范化輸入
高效率的規則引擎
用戶畫像
回復時,考慮對話的歷史記錄
低成本的構建對話
構建聊天內容最好是不需要有開發技能,而且有的開發者也沒有很好的聊天的技能。即便像Botframework這樣的大廠的產品,在構建對話時,都不夠友好,只能面向有開發技能的人,而且是一種硬編碼。這樣對于維護對話很不利。
使用Botframework的waterfall,設計對話的人需要了解builder.Prompts接口和session.beginDialog|endDialog。這樣做很不合理。
exports.start = [(session, arg, next) => {
builder.Prompts.text(session, "Do you want to start Class now?");
}, (session, results) => {
co(function*() {
return yield watson.sentiment(results.response);
}).then(function(o) {
let reply;
switch (o.docSentiment.type.toLowerCase()) {
case 'positive':
reply = '_begin_';
break;
case 'negative':
reply = "Got it."
break;
case 'neutral':
reply = "Ok, then.";
break;
}
if (reply == '_begin_') {
session.beginDialog('/daily_lessons/vocabulary');
} else {
builder.Prompts.text(session, reply);
session.endDialog();
}
});
}];
而另外一方面,使用script的方式,顯得更合理,比如SuperScript.
+ Do you want to start Class now?
- start_class
+ ~yes
% Do you want to start Class now
- Great, ^redirectTo(/daily_lessons/vocabulary)
+ ~no
% Do you want to start Class now
- Ok, then.
還有rivescript, chatscript, 同樣類似于superscript方式進行構建對話。
能區分不同類型的對話
設計對話時,至少有三種類型的對話:
system
系統對話,只能聊一次,或者只能由系統主動發出。比如自我介紹,bot和小明進行初次對話,bot會問:“你叫什么名字?”。小明回答“小明”。那么bot就知道"id:xxx"是小明。而將來bot都不應該再問這個問題。
daily
這些是bot可以重復和用戶聊的主題,可能并不是每天,它們可以每隔一段頻率就觸發,比如:問候,節日祝福,“你在做什么”, etc.
business
和一些閑聊的機器人不同,bot應該提供一些價值,這些價值可能是個人信息助手, 導購,教育, 播放音樂。
聲明對話類型:
> topic:business (vocabulary class)
+ Do you want to start Class now?
- start_class
+ ~yes
% Do you want to start Class now
- Great, ^redirectTo(/daily_lessons/vocabulary)
+ ~no
% Do you want to start Class now
- Ok, then.
<
所以,一個對話看起來像是這個樣子。
規范化輸入
表達同樣的意思,可以有多種表示方法。
whats the color of the calanders
what is the colour of the calenders
what be the colour of the calender
在將輸入語句傳給規則引擎前,要先做規則化處理。比如:
tokenized - 分詞
stemmed - 英文單詞取詞根
lemmatized - 英文單詞變形的歸類(例如單復數歸類)
part-of-speech (POS) tagger - reads text in some language and assigns parts of speech to each word
named entity recognizer (NER) - [ labels sequences of words in a text which are the names of things] 專有名詞 - 人名、地名、組織名、URL鏈接、系統路徑等
這里需要結合很多工具庫來實現:NLTK, Stanford CoreNLP, Jieba分詞,Wordnet, ConceptNet.
比如,借助Stanford CoreNLP,可以有下面的標注:

經過規范化輸入,在規則引擎中,可以依賴詞性和函數實現更智能的回答。
高效率的規則引擎
Bot可以有大量的主題,即便是只有100主題,每個主題15個對話,那就是1500個規則。如果只是單機運行,至少要進行下面兩個優化:
排序
通過聊天的記錄和關鍵字,先給對話棧排序。

排序的思路大概是這樣:
1) 查看當前對話,是否還有下文,一個對話的下文可以對應多個規則。
如果有下文,檢測是否一個規則能匹配上輸入。如果匹配上了,回復。 如果沒有下文,或者沒有規則能匹配上,進入次優匹配。
2) 次優匹配是將聊天主題的歷史記錄,使用TF-IDF算法進行排序。
簡單說,就是使用一個函數計算用戶聊天的對應主題頻率。給不同的聊天主題加權重。在次優匹配中,都是處理用戶曾經聊過的主題。
3) 在次優匹配中,沒有命中,進入其他匹配。
其他匹配包括了以前沒有聊過的主題。
并發
在排序后,去同時處理匹配運算,將命中的規則的回復,按照排序的順序放到數組里,然后,從數組中取第一個元素。這樣就比按照順序一個一個檢測快很多。
比如,一些Node.js模塊:async。
用戶畫像
在和用戶聊天的過程中,獲取到的用戶相關的信息,有必要記錄在數據庫中,這其實是構建知識圖譜的過程。

知識圖譜所用的數據庫是存在三個字段的結構化數據:
{
"subject": "Mao",
"predict": "chairman",
"object": "China"
}
由此構建了一個關系:

而B又可以跳轉到D。
目前,較為成熟的商業產品和開源方案都有。
在Bot Engine中,可以得到相關用戶的Knowledge Graph.
this.user.memory.get( ...)
this.bot.createUserFact( ...)

使用知識圖譜,除了對實體之間完成關系構建外,還有一個原因是,搜索速度非???,搜索功能強大。
SuperScript
介紹了這么多,那么到底怎么實現一個Bot Engine呢?經過了很多比較后,我覺得基于SuperScript實現Bot Engine是可行的。主要是下面這幾點:
社區活躍:目前穩定版本v0.12.2沒有bug, 最新版v1.0.0也在快速開發。
輕便靈活: 將SuperScript的源碼讀了一遍,覺得即便是作者不維護了,我也可以維護。
功能強大:在上面討論的問題中,SuperScript都是有涉及的。
對話腳本
topic type - 話題
conversation - 對話
function - 插件和函數
Get started
npm install superscript
var superscript = require("superscript");
new superscript({ ...}, function(err, bot){
bot.reply("userId", "hello", function(err, reply){
// do your magic
})
})
Conclusion
很多人預計2017年,AI方向最可能取得成功的領域是聊天機器人。那么,在這種情況下,面向聊天機器人的架構設計,是一個熱門問題。包括Google,Facebook都有可能發布類似于微軟的Botframework平臺。而Bot Engine, 一種處理對話的引擎,起著很關鍵的作用。在開源社區,還沒有看到哪個呼聲非常高的實現,SuperScript,至少在JavaScript社區,是一個不錯的選擇。
在下一篇文章中,我將介紹使用深度學習技術,依靠聊天語料,訓練Bot Model.
Reading List
NaturalNode - General natural language facilities for node.
SuperScript - A dialog system and bot engine for conversational UI's.
Stanford CoreNLP - a suite of core NLP tools
Natural Language Toolkit - NLTK is a leading platform for building Python programs to work with human language data.
How to Cook a Graph Database in a Night - A Knowledge Graphic tool based on LevelDB.
最后
歡迎聯系我,尤其是業內人士,給予指正,一起優化。
文章封面圖來自:中國智能制造網
雷峰網特約稿件,未經授權禁止轉載。詳情見轉載須知。