1. 程式人生 > >【轉】人機對話系統

【轉】人機對話系統

分詞,找關鍵字,然後到庫中去查詢這個的回答,然後回答。感覺是這樣。。

---------------------------華麗轉載分割線-------------------

此篇文章是我在別人基礎上寫的,加強了一些自身的體驗
我採用的是VS.NET+SQLSERVER 參考了小i機器人
這不是一篇新手入門的文章,如果你不知道什麼是.NET,不瞭解資料庫方面的哪怕是一丁點東西,建議你先看看。同時,也希望真正的高手不要笑話打擊我.

讓機器人懂中文

1 資料庫

因為我們要做中文聊天機器人,語料庫的大小直接關係到你的機器人是不是聰明。由於自己的習慣,我用了SQLSERVER作為存放語料庫和中文分詞庫的資料庫。因為我呼叫的是元件,所以沒用建分詞庫,只有1個語料庫


2 整句匹配

整句匹配這個概念很簡單。聊天嘛,不認識的人一般都會要上來就說“你好”,或者“hi~~”之類的。這種話通常很簡單,而且沒有什麼太多的變化,直接讓機器人回答就行了。比如對方說“你好”,機器人看到這個“你好”,就直接回答“你好”,就可以了。或者對方說"88",你可以讓機器人說“再見”,或者88什麼的。。這就叫整句匹配。就是機器人拿到整個的句子,在庫裡面一查,啊,庫裡有這句話怎麼回答,挑出一句回答過去,對方不會覺得這個機器人笨。

甚至如果對方說“你好笨”,你讓機器人回答“我才不笨呢”,對方一定會覺得,這個機器人還行,還知道別人說他笨。

3 中文分詞

一個聊天機器人當然要懂些中文。中文處理的基礎就是中文分詞。分詞是什麼?“分詞就是將連續的字序列按照一定的規範重新組合成詞序列的過程。”這個定義是我抄的。因為我是用.net開發,我用的分詞是以下幾種 KTDictSeg中文分片語件,IKAnalyzer中文分片語件,
Lucene.Net分片語件,

有人會說,這個東西我不懂,我也沒研究過。其實我也不懂。只不過,如果不做中文分詞,聊天機器人就只能停留在證據匹配的地步。我們可以使用最大匹配法,對聊天機器人接收到的話做簡單的分詞。關於演算法,請參閱詹衛東先生的這個講義,估計你一看就明白了。

課程名稱:中文資訊處理基礎

分詞演算法不需要太複雜,簡單點就好。


--------------------------------------------------------------------------------

用.NET開發MSN聊天機器人
分詞我用的是元件,因為太難了,所以願意偷懶的朋友們可以用元件,不想偷懶的可以去
http://ccl.pku.edu.cn/doubtfire/


研究一下語言學

4 詞語的匹配

僅僅會分詞還不夠,如果真的要讓機器人瞭解人說的話,肯定需要一些人工智慧的演算法。我們就是做個機器人玩玩,沒必要研究的那麼深。人工智慧走到現在,太聰明的聊天機器人也少之又少。而且,讓專業的研究人員去研究就好了,我們僅僅就是玩玩。所以呢……我們就用一個最簡單的辦法。我們的方法是,讓機器人找這一句話的關鍵詞,這句話大概的詞性搭配,再去語料庫裡面找到符合這樣規則的回答的話。

舉個簡單的例子:
比如對方說:

“你真好玩”

我們先用分詞演算法,把這句話分成

“你 真 好玩”,

然後找出關鍵詞“好玩”。同時把這句話的詞性搭配也記錄下來。 這樣,當找到關鍵詞“好玩”在語料庫中的時候,我們再來找是否有類似這這句話詞性搭配的回答,如果有,隨機回答出一句:“哈哈。。。我就喜歡你這麼說。”,這樣,可以給聊天者比較好的感覺。

那麼問題來了,如何找出關鍵詞呢? 我的方法是……(比較爛,但是通常有效),找出這句話中長度最長的詞作為關鍵詞。沒有為什麼,因為這樣速度會快些。如果一句話中所有的詞都被掃描成為關鍵詞,再去查庫,會出現些匹配上的問題。(不科學,但是通常有效)。
這個找關鍵詞的問題我一直沒有解決,希望有高手知道的+我,我的QQ是329670021

五、讓機器人再“聰明”些

1 整句匹配語料庫的設計

第一步當然是做你的整句匹配語料庫。語料庫都要自己寫的,不要偷懶。找出別人最常說的話,比如你好謝謝對不起什麼的,多放些回答在裡面,免得每次回答都是一樣的,然後要回答的時候,先寫一句sql來查詢,如

這個是MYSQL的:select * from reply where `key` = '"+sentense+"' order by rand() limit 1

但是我用的是SQLSERVER
取值的時候如果有一個關鍵字有N的答案的時候用SQL語句
select top 1 answer from robotchat where keyword = '" + a + "' order by newid()
隨機取出一條,這樣機器人就不會對一個問題只答一句話了
所以就要從資料庫裡取出值之後,在程式那邊用indexof來判斷.
如if (問題.IndexOf(關鍵字.ToString()) >= 0)

把找到的話直接回復過去就可以了。如果找不到整句匹配,再做分詞處理。

2 分詞匹配語料庫的設計

因為我們分詞演算法也沒有經過什麼優化,同時,我們找出關鍵字的辦法也不是那麼的好,所以,你給出的回答一定要不那麼清晰。說白了就是,回答的話要有些“含糊不清”才可以。目標就是,讓人覺得機器人對他說的話已經理解了,回答出來的還算比較“對路”。不要求100%對路,只要有40%以上對路,聊天的人基本就可能會接受。同時,回答的語料庫,最好可以引導對方再次回答的時候,可以說出你語料庫裡面有的,最好是可以整句匹配的句子。

舉個好玩的例子:

問題:你是男的還是女的?/你是男的還是女的/你是男的還是女的? (是否有標點符號沒關係,我們要記錄句子的詞性搭配,同時,要對標點符號做些處理)

像這樣一句話,我們可以通過分詞,找出關鍵詞:“還是”,而且通過判斷詞性,可以知道,這是一句問句。而且問的是在兩種情況之間選擇。(當然,我們通過簡單的演算法,沒法知道這句話其實是問性別)

對於這樣的問題,你的機器人怎麼回答?其實很簡單,首先,回答要“對路”,儘量不讓人覺得答非所問,至少讓人覺得,你的機器人是知道對方在問什麼的。所以,我的機器人這樣回答:

機器人回答:都是。。。哈哈

因為回答的是聊天用語,而且帶點開玩笑的意味,所以會使聊天者覺得,這個機器人還不是那麼笨。

這只是一個簡單的例子。很多具體的句子還得你自己去分析。當然,語料庫越多,機器人懂的就越多,也就越聰明瞭。假如你不懂如何讓自己語料庫更強大,你可以把回答不出的問題存入資料庫中,然後給別人玩,這樣就可以找出別人回答不出的問題了


3 匹配不到關鍵字怎麼辦

語料庫不是很多的情況下,很可能我們的分詞演算法匹配不到合適的回答來應付。所以我們還要另外做一個語料庫,用來在實在匹配不到關鍵詞的時候,進行回答。這樣的回答比較需要類似“算卦”的人的回答技巧,因為對方可能說任何話,而我們的機器人不明白。所以,要想辦法“矇混過關”,同時,儘量引導對方向你機器人可能回答的方面說。你可以試著跟“小布”聊聊天,會發現它回答不出來的時候,就會隨便挑一句“佛經”來說。

其實最重要的一個技巧就是,學習一下算卦的人說的話,都是雲裡霧裡的,讓人摸不到頭腦,還覺得可能是對的。我們就要讓機器人學習這種技巧,來達到看上去“聰明”的目的。


最後的話:
其實寫這樣的一個機器人程式很快的,如果熟悉些的話,估計一天應該就可以寫出來。我大概用了一天半,還加上準備些語料庫的時間。如果你真想做個稍稍“聰明些”的機器人來玩,這篇文章應該可以為你剩下至少3-5個小時的找資料的時間。如果你懶得自己研究,也有別的公司做的只能整句匹配的程式可以下載,自己下一個玩玩也就算了。