AIML学习(一)
AIML 是什么?
AIML由Richard Wallace發明。他設計了一個名為 A.L.I.C.E. (Artificial Linguistics Internet Computer Entity 人工語言網計算機實體) 的機器人,并獲得了多項人工智能大獎。有趣的是,圖靈測試的其中一項就在尋找這樣的人工智能:人與機器人通過文本界面展開數分鐘的交流,以此查看機器人是否會被當作人類。AIML是一種為了匹配模式和確定響應而進行規則定義的 XML 格式。
關于 AIML 詳細的初級讀物,可翻閱 Alice Bot’s AIML Primer。你同樣可以在 AIML Wikipedia page了解更多 AIML 的內容以及它能夠做什么。我們首先將創建 AIML 文件,并用 Python 賦予它生命。
創建標準的啟動文件
創建一個啟動文件 std-startup.xml 作為讀取AIML文件的主入口點是標準做法。在這里,將創建了一個初始文件用來匹配一種模式和進行一個動作。我們想匹配模式 load aiml b ,并且使它載入我們的 aiml 大腦作為響應。我們將即時創建 basic_chat.aiml 文件。
創建 AIML 文件
上面我們已經創建了只有一種模式句柄的 AIML 文件,load aiml b。當我們通過命令行運行這個機器人,它會嘗試讀取 basic_chat.aiml。除非我們已經完成創建,否則載入失敗。下面的示例代碼將告訴你 basic_chat.aiml 文件可以加入什么。我們將匹配兩種基礎的模式和響應。
隨機響應
你同樣可以像下面的示例代碼一樣添加隨機響應。當接收到“One time I”開頭的信息(message),通配符“*”可以進行模糊匹配。
運用 Python
目前為止,所有 XML 格式的 AIML 文件都準備好了。作為機器人大腦的組成部分,它們都很重要,不過目前它們只是信息(information)而已。機器人需要活過來。你可以借助任何語言定制 AIML,但某些好心人已經用 Python 這么做了。
注意,aiml 包只能在 Python2 環境下運行。
最簡單的 Python 程序
我們可以用如下最簡單程序入門。它創建了 aiml 類,學習啟動文件,然后讀取其余 aiml 文件。接下來,它已經準備好聊天了,我們也進入了一個不斷提示用戶輸入信息的死循環。你需要輸入一個機器人能識別的模式。模式的識別取決于你載入的 AIML 文件。
因為我們建立啟動文件作為獨立實體,所以我們稍后可以對機器人添加更多 aiml 文件而不需要調試任何程序的源代碼。只有在 xml 格式的 starup 下,我們才能添加更多文件。
import aiml# 創建Kernel()和 AIML 學習文件 kernel = aiml.Kernel() kernel.learn("std-startup.xml") kernel.respond("load aiml b")# 按組合鍵 CTRL-C 停止循環 while True:print kernel.respond(raw_input("Enter your message >> "))加速大腦載入
當你漸漸有了許多 AIML 文件,機器人就需要很多時間去學習。這就需要大腦文件的介入了。在機器人學習完所有 AIML 文件后,它可以直接以文件形式存儲大腦,再次運行時可以大大提升載入時間。
運行時重載 AIML
運行時,你可以發送載入信息給機器人,接著將會重載 AIML 文件。注意你是否像上文那樣使用了大腦方式,飛速重載不會造成大腦有新的變化。你要么刪除大腦文件,以便下次啟動時重建;要么修改代碼,以便重載后的某一時刻能夠儲存大腦。下一節將利用新建 Python 命令來讓機器人執行這些操作。
添加 Python 命令
如果你想通過運行 Python 函數來為機器人添加一些特別的命令,那么你應該在發送 kernel.respond() 函數前截取輸入信息并處理。在上述的例子中,我們借助 raw_input 函數獲取用戶的輸入。由此我們無論如何都能獲取我們的輸入信息。可能好似一個 TCP 套接字(socket),或者使聲源轉換成文本源。你也許不想 AIML 處理對于某些信息。因此在它們傳遞給 AIML 時處理。
會話和謂詞(Predicates)
通過指定會話,AIML 能根據不同對話者隨機應變。舉個例子,如果某人告訴機器人他們叫 Alice,另一個人則告訴機器人它叫 Bob,機器人可以分清他們。指定你需要的會話,將它作為第二個參數傳遞給 respond()。
和每個客戶都能有個性化的對話——這棒極了。你不得不生成你特有的會話ID并追蹤。記住保存大腦文件不要保存所有的會話值。
sessionId = 12345# 將會話信息作為字典 # 包含輸入輸出的歷史像已知謂詞那樣 sessionData = kernel.getSessionData(sessionId)# 每個會話ID需要一個唯一的值 # 用會話中機器人已知的人或事給謂詞命名 # 機器人已經知道你叫"Billy"而你的狗叫"Brandy" kernel.setPredicate("dog", "Brandy", sessionId) clients_dogs_name = kernel.getPredicate("dog", sessionId)kernel.setBotPredicate("hometown", "127.0.0.1") bot_hometown = kernel.getBotPredicate("hometown")在AIML中,我們可以在 項中設置謂詞。
<aiml version="1.0.1" encoding="UTF-8"><category><pattern>MY DOGS NAME IS *</pattern><template>That is interesting that you have a dog named <set name="dog"><star/></set></template> </category> <category><pattern>WHAT IS MY DOGS NAME</pattern><template>Your dog's name is <get name="dog"/>.</template> </category> </aiml>通過以上 AIML 你可以告訴機器人:
My dogs name is Max機器人會回答:
That is interesting that you have a dog named Max另外如果問機器人:
What is my dogs name?機器人會這么回應你:
Your dog's name is Max.aiml可以用來實現對話機器人,但是用于中文有以下問題:
- 中文規則庫較少。規則庫相當于對話機器人的“大腦”,一般來說,規則庫越豐富,對話機器人的應對就更像人。目前英文的規則庫已經很豐富,涵蓋面很廣,而且是公開可獲取的。但公開的中文規則庫就基本沒有。
AIML解釋器對中文支持不好。實際上,Python下的Pyaiml模塊(解析器)已經能比較好的支持中文,但是也存在以下問題:英文單詞間一般都有空格或標點區分,因此具備一種“自然分詞”特性,由于中文輸入沒有以空格分隔的習慣,以上會在實踐中造成一些不便。比如要實現有/無空格的輸入匹配,就需要在規則庫中同時包含這兩種模式。
解決方案:自己搭建語料庫(比如從字幕文件中獲取訓練)
自己中文分詞工具(如jieba)
相關開源項目:https://github.com/leo108/aliceCN
https://github.com/messense/wechat-bot
https://github.com/Program-O/Program-O
參考資料:
http://www.w3ii.com/aiml/aiml_introduction.html
- http://www.devdungeon.com/content/ai-chat-bot-python-aiml
- http://www.alicebot.org/documentation/aiml-reference.html
總結
- 上一篇: Linux网络抓包
- 下一篇: 自然语言处理--基于规则(AIML)的问