從產品完整性的角度淺談chatbot

從產品完整性的角度淺談chatbot

來自專欄菜鳥看演算法6 人贊了文章

現在似乎每家公司都開始推出自己的一個chatbot,但是我們都知道一個chatbot想做好,涉及很多複雜的技術。對於普通學生黨來說,可能想做出一個工業級產品的chatbot基本不太可能。而且另一方面如何從產品化和架構的角度來整體考慮問題,而不只是一個技術模型的堆砌,這我個人認為也是非常重要。

故本篇文章想在這裡從一個入門的階段和方式,結合我個人的一些實踐,討論一下如何用一些基本的技術和混合的人工策略搭建出一個具有初步原型,各方面功能都有一定涉及的chatbot。不求技術深度,只求產品完整度和廣度的一個考量。

當然這裡都是我自己個人的一些想法和設計思路,如果覺得有不對的地方,還請批評指教。

註:本chatbot只關注單純的聊天領域,無知識問答或針對兒童聊天或者老年陪伴等領域。

基本功能

  1. chatbot自身人格的設置
  2. 產品上線需要考慮的敏感詞處理
  3. 文本檢索模型的使用
  4. 文本生成模型的使用
  5. 回答打分機制
  6. 萬能回答的使用策略
  7. 多媒體消息的處理
  8. 產品模型部署的問題

流程設計

可能一般人在使用chatbot的時候,也就感覺,不就是我發一句話,對面回復一句話么?

簡單來說,基本是這個邏輯。但問題是機器在收到用戶的消息,如何根據內容的不同和上下文的不同進一步去做決策和走不同的邏輯,最終返回一個相對合適的結果是很複雜和困難的。而且如果是一個向公眾開放,接受民眾使用的產品,又會有一些其他政治敏感、文明用語等等方面的進一步考量。故一個東西,真正要落地使用,不僅僅就靠牛逼的技術就夠了,更多的還有全局與產品設計的考慮。

先上一張我之前在創新工場深度學習訓練營和其他同學一起合作,用一個月時間搭的一個小demo的流程設計吧。demo就是我們幾個研一年級上下的新手根據自己的理解,加上一個月來不斷的查資料、做實驗,最後完成的。工場方面提供了語料與GPU資源,在此非常感謝。我在裡面主要負責這個流程框架的設計及部分模塊的實現工作。

感覺相對還是比較粗糙,用的模型也很簡單,有很多優化的空間。

分流

本chatbot根據用戶輸入的內容,先按照數據類型,進入一個分流器,進入不同的模塊。(這裡只處理了圖片和文本,沒有處理視頻和語音)

圖片類型

對於圖片類型的輸入,我們就設計了一個簡單的表情包斗圖功能。我們事先採集了約2W張各種類型的表情包,然後用VGG-NET 19進行特徵提取,並用KD樹做簡單的索引保存下來。然後對於輸入的新圖片,也進行特徵提取,然後在KD樹中進行相似度查找,返回最相似的第K張圖片。(K的設置一般取不要太小,不要把一模一樣的返回即可)

文本類型

對於文本類型輸入,我們先對其進行了各種預處理和語義信息的提取,如切詞、詞向量、句法樹的解析等,將帶著這些基本信息的句子送到回答系統的流程中。

敏感詞、不雅詞檢測

當然在生成回答系統的pipeline中,第一步最重要的就是先用一套事先定好的敏感詞、不文明詞詞典進行一遍檢查,如果發現有敏感信息,則直接根據相應的策略生成回復,不再走後面的流程,如「小心我把你的事告訴警察叔叔哦」或者「你這麼不禮貌,你媽媽知道么」之類的。之所以這個檢查要放在第一步的原因,我想大家都懂。騰訊之前在QQ里上線的一款聊天機器人好像就是因為一些這方面的原因,最後又下架了。所以對於一個成熟的產品來說,技術是一方面,遵守相應的一些法律法規要求也是很重要的。

人格檢測模塊

如果前面的檢查都通過了,那麼按照設計,先進行人格信息 檢測匹配。首先可能有些人不太理解什麼叫做人格信息。簡單理解,就是一個chatbot雖然只是一個程序,但是它也可以擁有他自己的一個身份,比如它的名字、它的愛好、它是否有親人、它的性別等等。就像微軟的小冰一樣,它的人格就是很青春的美少女。

那為什麼要加入這個模塊呢?

是因為我們在準備開始做這個項目的時候,在調研用戶的需求和我們自己體驗其他家的聊天機器人的過程中發現,在聊天場景下,很多的會話都發生在對機器人本身信息的詢問上。比如「你叫什麼名字」、「你吃飯了沒」、「你有沒有爸爸媽媽」等等。

這個也很好想像,我們人和人交往的過程中,聊天的內容大部分情況下也是對人本身的關注。(這裡注意聊天和問答的區別)。那對於一個產品來說,其要保持一個本身產品口碑和可持續性的話,也就要保持它的人格是不變的,也就是說不管用戶怎麼問,它對於自己信息類問題的回答總是穩定的。不會出現「你是誰」,回答「我是張三」。第二次再問「你好,我是*,請問你叫什麼名字」,就又變成回答「你好,我是李四」這樣的情況。

那如何做這個模塊呢?首先我們需要先設計好聊天機器人的一個人格。包括其姓名、年齡、愛好、家鄉、家庭成員、平常幹什麼等常見的信息,並針對每個信息設置一些模板回答。比如對於年齡,它可以回答」我今年5歲了「、」啦啦啦,我是一個五歲的小朋友「、」我來到這個世界上才只有5年呢「,用於 增加 產品 的豐富度和穩定性

另外注意加一個「other」類,用於處理可能是問我們個人信息,但比較偏的「你有沒有上過大學」這種,統一回答「我知道你好像想了解我,不過我只是個小孩子,回答不了你呢。」。因為我們不可能把所有的信息類別都窮舉,都設置出模板,但如果能夠做到知道用戶是在問機器人本身的話,返回這個萬能回答,其實也已經夠了。

模板定義之後問題就來了,那如何判斷這個時候要不要採用模板回答呢,以及我是回答年齡還是姓名呢?這裡我覺得一個相對比較合理的方式是先採集和構造一批針對人格信息詢問句式的語料庫。然後先構建一個二分類的分類器,分類現在是否是對於人格信息的問詢。如果是,則往下走。下面是一個多分類器,有多少種人格信息類別,則就是多少分類。最後根據分類結果取出對應的回答模板之一。

而分類器怎麼構建呢?這裡我當時是用了百度句法樹的API,提了一些賓語與主語之間依賴關係的特徵、關鍵詞的命中、關鍵詞的前後順序等特徵。其實用一個LSTM直接來做更好,避免了手工提特徵的過程。

複雜模型

經過前面兩個模塊的層層篩選後,再過來的句子才是可以通過演算法模型來解決的聊天內容了。

而這裡面又按照技術不同主要分為兩個大方向,一個是檢索式,另一個是生成式。

檢索式模型

檢索式就是從一個備選的大語料庫中,用一定的辦法去找出裡面最匹配的一個或多個回答,直接返回。不過在實現方式上不同方法還是有一些區別。(個人才疏學淺,就只講講我所知道的)

一種是對於pair類型的語料(一來一回式的單輪對話,設第一句話為A,第二句話為B),對A用一些模型(如TF-IDF的LDA)進行建模,得到一個向量,並索引和保存起來。然後對於新句子,也按照建模的方式計算出一個向量,然後去和保存的模型索引進行相似度查詢。然後把最相似的那句話對應的B取出來返回。這樣的一個例子是用戶問「今天你心情怎麼樣」,然後我們去語料庫里查詢,發現跟已有的「今天你心情好不好」很像,就把其對應的結果「我很好,你呢?」取出來返回。(或者用簡單的倒排索引加BM25也可以做)

另一種方式是用文本匹配的思路來做,對於A和B,我們建立一個模型,去看什麼樣的pair,A和B是能夠生成一輪對話的,把匹配的過程轉換成一個二分類問題,能匹配和不能匹配

具體操作的話,就是對A和B分別編碼生成一個向量,然後用一定的模型計算他們兩個之間的匹配度,用一個0-1之間的概率來做分類。這個思路的例子是去盡量發現出A和B之間一種潛在的關聯和匹配,如「今天你心情怎麼樣」和「現在我很高興」之間就有一個很強的關聯關係在(「你」和「我」,「心情」和「高興」,」現在「和」今天「等),從而把匹配的句子能夠檢索出來。

那對於新的句子進來,我們就對它先編碼,得到一個向量A_vec,然後用 A_vec去對可能的B向量都去計算一遍匹配度,取出匹配度最高的結果進行返回。這裡我們使用了一個簡單的Dual Encoder編碼器模型。如下圖

這裡進階可以考慮更複雜的文本匹配模型,如DSSM、Multi View LSTM、ARC 模型等。

當然我們在實踐的過程中也發現,用DL來做檢索會存在時間效率上的問題。所以一個更好的設計方案是,先用帶索引的速度快的LDA或者倒排索引等模型粗略地召回一些結果,然後針對這些結果,進一步用一個更複雜的DL model來rerank匹配檢索。這樣達到一個效果和速度的平衡。

生成式模型

生成式模型跟檢索模型相同,同樣有非常多值得深入研究的話題,但我個人也不是特別熟悉。所以只能淺淺地談下。其基本原理就是通過對大量pair語料的學習,學習出A和B之間的聯繫。而聯繫是通過兩個模型,一個編碼器,一個解碼器構建的,學習出通過什麼樣的編碼解碼能夠讓第一句話產生出第二句話。而在預測的時候就對輸入句子進行編碼,根據得到的A_vec,在解碼器中一步步地判斷此時需要用什麼樣的詞,最終得到總體的結果。

在這裡我們就用了一個經典的Seq2Seq + Attention模型。不過在過程中也發現生成式模型會有不可控的結果和總是容易變成「萬能回答」的一個特點。這些問題都非常值得研究。進階可以考慮只用Attention的Attention is All You Need模型等。

回答評分模型

前面提到了檢索和生成模型,也許他們都能給出一定的結果。那怎麼最終確定下要回復哪一個呢?在這裡我們可以再引入一個模型,叫做評分模型,主要就是對回復與輸入的相關度、匹配度及回複本身的合理性做出一個評分。這裡我們就簡單再次藉助文本匹配的思路來做,用一個參數有所不同的Dual Encoder 模型產生的概率值作為評分值。(當然實際也許可以很複雜,如阿里小蜜在rerank階段就用了一個seq2seq模型,用候選句子每個詞被生成的平均概率的和作為評分)

所以最終可以把這個過程看做一個rerank的過程,就是從優中選優和從矮子里拔高個的道理。同時通過對評分閾值的處理,也可以加入一個額外策略,如果所有候選句子的得分都低於一定的閾值,就不再採用模型產生的結果,而直接從一個萬能回答庫中取出一句事先編好的模板,如龍泉寺機器人常回復的「阿彌陀佛」。這樣可以盡量控制系統最壞情況下是回復了一個」不匹配但不出錯「的結果,而不是」既不匹配又出錯「的結果。

總結

本文主要從產品完整性和技術相結合的一個角度闡述了Chatbot在設計和實現上一個思路,涉及了策略的使用、模型的選取等多個方面。

如果有不足之處,還請指正,謝謝。

推薦閱讀:

第七篇 自然語言處理與語音合成
基於CNN的自然語言處理TensorFlow實現(上)
全文搜索+語義向量
<DepthLGP : Learning Embeddings of Out-of-Sample Nodes in Dynamic Networks>筆記

TAG:自然語言處理 | 聊天機器人 | 深度學習DeepLearning |