0
本文作者: hain | 2017-02-12 10:37 |
雷鋒網(wǎng)按:本文作者王海良,呤呤英語開發(fā)總監(jiān),北京JavaScript/Node.js開發(fā)者社區(qū)的運營者,曾就職IBM創(chuàng)新中心。本文為系列文章第二篇,由雷鋒網(wǎng)獨家首發(fā)。
第一篇傳送門:《聊天機器人的發(fā)展狀況與分類》。在上一篇文章中,介紹了聊天機器人目前的發(fā)展。本篇主要介紹基于規(guī)則的,檢索的聊天機器人引擎 - Bot Engine.
問題域
Speech to Text => Logic => Text to Speech
STT和TTS,目前有很多廠商提供技術(shù)產(chǎn)品:
Speech to Text 語音識別技術(shù)
Google Cloud Platform, IBM Watson API, 云知聲,科大訊飛
Text to Speech 語音合成技術(shù)
IBM Watson API Docs demo
經(jīng)過多年的研究,尤其是深度學習的采用,在這兩項技術(shù)上取得了突破性進展。今天本文所要討論的是logic,而且是基于規(guī)則引擎的logic, 基于機器學習的部分將在以后的文章中討論。
Conversation Model
在兩個人之間的對話,可以用下面這個模型表示,雙方頭腦中所要向?qū)Ψ奖磉_的目標,需要通過語言來交換意見,為了達成共識,二者需要在一個語境下。
為了支撐這個模型,在設(shè)計Bot Engine過程中,要考慮如下的要點:
低成本的構(gòu)建對話
能區(qū)分不同類型的對話
規(guī)范化輸入
高效率的規(guī)則引擎
用戶畫像
回復(fù)時,考慮對話的歷史記錄
低成本的構(gòu)建對話
構(gòu)建聊天內(nèi)容最好是不需要有開發(fā)技能,而且有的開發(fā)者也沒有很好的聊天的技能。即便像Botframework這樣的大廠的產(chǎn)品,在構(gòu)建對話時,都不夠友好,只能面向有開發(fā)技能的人,而且是一種硬編碼。這樣對于維護對話很不利。
使用Botframework的waterfall,設(shè)計對話的人需要了解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方式進行構(gòu)建對話。
能區(qū)分不同類型的對話
設(shè)計對話時,至少有三種類型的對話:
system
系統(tǒng)對話,只能聊一次,或者只能由系統(tǒng)主動發(fā)出。比如自我介紹,bot和小明進行初次對話,bot會問:“你叫什么名字?”。小明回答“小明”。那么bot就知道"id:xxx"是小明。而將來bot都不應(yīng)該再問這個問題。
daily
這些是bot可以重復(fù)和用戶聊的主題,可能并不是每天,它們可以每隔一段頻率就觸發(fā),比如:問候,節(jié)日祝福,“你在做什么”, etc.
business
和一些閑聊的機器人不同,bot應(yīng)該提供一些價值,這些價值可能是個人信息助手, 導(dǎo)購,教育, 播放音樂。
聲明對話類型:
> 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.
<
所以,一個對話看起來像是這個樣子。
規(guī)范化輸入
表達同樣的意思,可以有多種表示方法。
whats the color of the calanders
what is the colour of the calenders
what be the colour of the calender
在將輸入語句傳給規(guī)則引擎前,要先做規(guī)則化處理。比如:
tokenized - 分詞
stemmed - 英文單詞取詞根
lemmatized - 英文單詞變形的歸類(例如單復(fù)數(shù)歸類)
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鏈接、系統(tǒng)路徑等
這里需要結(jié)合很多工具庫來實現(xiàn):NLTK, Stanford CoreNLP, Jieba分詞,Wordnet, ConceptNet.
比如,借助Stanford CoreNLP,可以有下面的標注:
經(jīng)過規(guī)范化輸入,在規(guī)則引擎中,可以依賴詞性和函數(shù)實現(xiàn)更智能的回答。
高效率的規(guī)則引擎
Bot可以有大量的主題,即便是只有100主題,每個主題15個對話,那就是1500個規(guī)則。如果只是單機運行,至少要進行下面兩個優(yōu)化:
排序
通過聊天的記錄和關(guān)鍵字,先給對話棧排序。
排序的思路大概是這樣:
1) 查看當前對話,是否還有下文,一個對話的下文可以對應(yīng)多個規(guī)則。
如果有下文,檢測是否一個規(guī)則能匹配上輸入。如果匹配上了,回復(fù)。 如果沒有下文,或者沒有規(guī)則能匹配上,進入次優(yōu)匹配。
2) 次優(yōu)匹配是將聊天主題的歷史記錄,使用TF-IDF算法進行排序。
簡單說,就是使用一個函數(shù)計算用戶聊天的對應(yīng)主題頻率。給不同的聊天主題加權(quán)重。在次優(yōu)匹配中,都是處理用戶曾經(jīng)聊過的主題。
3) 在次優(yōu)匹配中,沒有命中,進入其他匹配。
其他匹配包括了以前沒有聊過的主題。
并發(fā)
在排序后,去同時處理匹配運算,將命中的規(guī)則的回復(fù),按照排序的順序放到數(shù)組里,然后,從數(shù)組中取第一個元素。這樣就比按照順序一個一個檢測快很多。
比如,一些Node.js模塊:async。
用戶畫像
在和用戶聊天的過程中,獲取到的用戶相關(guān)的信息,有必要記錄在數(shù)據(jù)庫中,這其實是構(gòu)建知識圖譜的過程。
知識圖譜所用的數(shù)據(jù)庫是存在三個字段的結(jié)構(gòu)化數(shù)據(jù):
{
"subject": "Mao",
"predict": "chairman",
"object": "China"
}
由此構(gòu)建了一個關(guān)系:
而B又可以跳轉(zhuǎn)到D。
目前,較為成熟的商業(yè)產(chǎn)品和開源方案都有。
在Bot Engine中,可以得到相關(guān)用戶的Knowledge Graph.
this.user.memory.get( ...)
this.bot.createUserFact( ...)
使用知識圖譜,除了對實體之間完成關(guān)系構(gòu)建外,還有一個原因是,搜索速度非???,搜索功能強大。
SuperScript
介紹了這么多,那么到底怎么實現(xiàn)一個Bot Engine呢?經(jīng)過了很多比較后,我覺得基于SuperScript實現(xiàn)Bot Engine是可行的。主要是下面這幾點:
社區(qū)活躍:目前穩(wěn)定版本v0.12.2沒有bug, 最新版v1.0.0也在快速開發(fā)。
輕便靈活: 將SuperScript的源碼讀了一遍,覺得即便是作者不維護了,我也可以維護。
功能強大:在上面討論的問題中,SuperScript都是有涉及的。
對話腳本
topic type - 話題
conversation - 對話
function - 插件和函數(shù)
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
很多人預(yù)計2017年,AI方向最可能取得成功的領(lǐng)域是聊天機器人。那么,在這種情況下,面向聊天機器人的架構(gòu)設(shè)計,是一個熱門問題。包括Google,F(xiàn)acebook都有可能發(fā)布類似于微軟的Botframework平臺。而Bot Engine, 一種處理對話的引擎,起著很關(guān)鍵的作用。在開源社區(qū),還沒有看到哪個呼聲非常高的實現(xiàn),SuperScript,至少在JavaScript社區(qū),是一個不錯的選擇。
在下一篇文章中,我將介紹使用深度學習技術(shù),依靠聊天語料,訓(xùn)練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.
最后
歡迎聯(lián)系我,尤其是業(yè)內(nèi)人士,給予指正,一起優(yōu)化。
文章封面圖來自:中國智能制造網(wǎng)
雷峰網(wǎng)特約稿件,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。