人工智慧:用AIML寫一個機器人

來源:互聯網
上載者:User

最近搞了一把人工智慧,感覺AIML(Artificial Intelligence Mark-up Language)確實是個好東西,特筆記之。
AIML OVERVIEW:

http://www.pandorabots.com/pandora/pics/wallaceaimltutorial.html

AIML的一個java引擎:
http://www.geocities.com/phelio/chatterbean/?200931#BOTS

1: AIML OVERVIEW

首先看看AIML到底長啥樣:
<aiml><br /><category><pattern>WHO WANTS TO KNOW</pattern><template>ALICE wants to know.</template></category><br /><category><pattern>WHY ARE YOU CALLED</pattern><template> <srai>WHAT DOES ALICE STAND FOR</srai> </template></category><br /><category><pattern>WHY ARE YOU NAMED *</pattern><template> <srai>WHAT DOES ALICE STAND FOR</srai> </template></category><br /><category><pattern>WHY DO YOU DREAM *</pattern><template>I dream about adding new code to ALICE.</template></category><br /><category><pattern>WHY SILVER</pattern><template>ALICE is competing for the Loebner Silver Medal.</template></category><br /><category><pattern>WHY WERE YOU NAMED ALICE</pattern><template><srai>WHAT DOES ALICE STAND FOR</srai></template></category><br /><category><pattern>WHY WERE YOU NAMED</pattern><template><srai>WHAT DOES ALICE STAND FOR</srai></template></category><br /><category><pattern>WHY</pattern><that>I AM SMARTER *</that><template>ALICE won an award for being the "most human" robot.</template></category><br /><category><pattern>WOULD ALICE *</pattern><template><srai>WOULD YOU <star/> </srai> </template></category><br /></aiml>
簡單說明一下AIML的常用標籤:
1:pattern tag:支援模式比對(Regex,模糊比對),及基於template的返回
2:random tag:支援隨機回答(一對多)
4:think,system tag: 支援簡單邏輯記憶及自訂函數(本來打算擴充一下AIML, 搞一個支援Groovy語言的標籤, 結果看到了它的<system>標籤, 遂作罷)
5:javascript tag: 支援嵌入js指令碼(適用於web chat開發,比如根據情緒改變表情等)。
6:srai tag: 支援多對一回答.
詳細內容請參加AIML的官方文檔:
http://alicebot.org/TR/2005/WD-aiml/WD-aiml-1.0.1-008.html

2:按照AIML, 鄙人整理了一個簡單的DEMO,擴充了AIML的DATE標籤,支援了java的時間掩碼,並有自學習功能.

機器人Alice表現如下,可見其多麼聰明:
Alice>Hi ya! Welcome!<br />you say>what's your name<br />Alice>sorry, what?<br />you say>this is not a good answer //開始學習功能<br />Alice>Sorry. What would be a good answer?<br />you say>my name is Alice<br />Alice>Alright! You can ask me again to see if I got it.<br />you say>what's your name<br />Alice>my name is Alice<br />you say>what is your name<br />Alice>my name is Alice<br />you say>my name is Lichunlei<br />Alice>hello, Lichunlei.<br />you say>do you remember me?<br />Alice>Your name is Lichunlei, seeker. //Alice的記憶功能<br />you say>what's time now?<br />Alice>It is 10:59 A.M.<br />you say>what date is today?<br />Alice>Monday.

如果感覺機器人Alice的答案不滿意, 只需輸入包含not和good answer的句子,在你的指導下,Alice就可以開始學習新知識。

讓它如此智慧的原因就是AIML檔案, 此為機器人的大腦.
下為Alice的AIML檔案:
<?xml version="1.0" encoding="ISO-8859-1"?><br /><aiml><br /><!-- Copyright (c) 2007 ALICE A.I. Foundation, Inc. --><br /><!-- Last modified Seo 21, 2009, by Lichunlei --><br /><category><pattern>WHAT IS TIME *</pattern><template>It is <date format="h:mm a"/>.</template></category><br /><category><pattern>WHAT DAY IS TODAY</pattern><template><date format="E"/>.</template></category><br /><category><pattern>WHAT IS TODAY *</pattern><template><date format="EEE"/>.</template></category><br /><category><pattern>MY NAME IS *</pattern><template><think><set name="name"><star/></set></think>hello, <get name="name"/>.</template></category><br /><category><pattern>DO YOU REMEMBER ME</pattern><template>Your name is <get name="name"/>, seeker.</template></category><br /><category><pattern>I CAN NOT *</pattern><template>Why can't you do <set name="it"><person/></set>?</template></category><br /><category><pattern>MY INPUT</pattern> <template> 1:<input index="1"/> 2:<input index="2"/> 3:<input index="3"/></template></category><br /><category><pattern>*</pattern><template>sorry, what?</template></category><br /> <!-- Greeting categories. --><br /> <category><br /> <pattern>WELCOME</pattern><br /> <template><br /> <think><br /> <system> <!-- Defines a method to create new categories from user input at run-time. --><br /> import bitoflife.chatterbean.AliceBot;<br /> import bitoflife.chatterbean.Context;<br /> import bitoflife.chatterbean.Graphmaster;<br /> import bitoflife.chatterbean.aiml.Category;<br /> import bitoflife.chatterbean.text.Transformations;</p><p> void learn(String pattern, String template)<br /> {<br /> /* The "match" variable represents the current matching context. */<br /> AliceBot bot = match.getCallback();<br /> Context context = bot.getContext();<br /> Transformations transformations = context.getTransformations();</p><p> pattern = transformations.normalization(pattern);<br /> Category category = new Category(pattern, new String[] {template});<br /> Graphmaster brain = bot.getGraphmaster();<br /> brain.append(category);<br /> }<br /> </system><br /> </think><br /> Hi ya! Welcome!<br /> </template><br /> </category><br /> <!-- A category set to learn simple user-fed categories. --><br /> <category><br /> <pattern>* NOT * GOOD ANSWER</pattern><br /> <template><br /> Sorry. What would be a good answer?<br /> </template><br /> </category><br /> <category><br /> <pattern>_</pattern><br /> <that>WHAT WOULD BE A GOOD ANSWER</that><br /> <template><br /> <system>learn("<input index="3"/>", "<input index="1"/>")</system><br /> Alright! You can ask me again to see if I got it.<br /> </template><br /> </category><br /></aiml>

之所以Alice可以學習, 重要的一點是<input/>標籤,此標籤記住了之前對方的聊天記錄, 通過index可以得到(倒序索引)

程式相對簡單,兩個class:
Alice工廠: AliceBotMother
package co.aiml;<br />import java.io.FileInputStream;<br />import java.io.ByteArrayOutputStream;<br />import bitoflife.chatterbean.AliceBot;<br />import bitoflife.chatterbean.Context;<br />import bitoflife.chatterbean.parser.AliceBotParser;<br />import bitoflife.chatterbean.util.Searcher;<br />public class AliceBotMother<br />{</p><p> private ByteArrayOutputStream gossip;</p><p> public void setUp()<br /> {<br /> gossip = new ByteArrayOutputStream();<br /> }</p><p> public String gossip()<br /> {<br /> return gossip.toString();<br /> }<br /> public AliceBot newInstance() throws Exception<br /> {<br /> Searcher searcher = new Searcher();<br /> AliceBotParser parser = new AliceBotParser();<br /> AliceBot bot = parser.parse(new FileInputStream("Bots/context.xml"),<br /> new FileInputStream("Bots/splitters.xml"),<br /> new FileInputStream("Bots/substitutions.xml"),<br /> searcher.search("Bots/mydomain", ".*//.aiml"));<br /> Context context = bot.getContext();<br /> context.outputStream(gossip);<br /> return bot;<br /> }<br />}<br />

命令列聊天程式:
package co.aiml;<br />import java.io.BufferedReader;<br />import java.io.IOException;<br />import java.io.InputStreamReader;<br />import bitoflife.chatterbean.AliceBot;<br />public class Chat<br />{<br /> public static final String END = "bye";</p><p> public static String input()<br /> {<br /> BufferedReader in = new BufferedReader(new InputStreamReader(System.in));<br /> System.out.println("you say>");<br /> String input = "";<br /> try<br /> {<br /> input = in.readLine();<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> return input;<br /> }</p><p> public static void main(String[] args) throws Exception<br /> {<br /> AliceBotMother mother = new AliceBotMother();<br /> mother.setUp();<br /> AliceBot bot = mother.newInstance();<br /> System.err.println("Alice>" + bot.respond("welcome"));<br /> while(true)<br /> {<br /> String input = Chat.input();<br /> if(Chat.END.equalsIgnoreCase(input))<br /> break;</p><p> System.err.println("Alice>" + bot.respond(input));<br /> }</p><p> }<br />}

需要說明的是:
AliceBot bot = parser.parse(new FileInputStream("Bots/context.xml"),<br /> new FileInputStream("Bots/splitters.xml"),<br /> new FileInputStream("Bots/substitutions.xml"),<br /> searcher.search("Bots/mydomain", ".*//.aiml"));

context.xml:設定application的屬性, 及時間格式等可變屬性
<context><br /> <!-- The id is a unique string that identifies this context. --><br /> <bot name="id" value="test_cases" /><br /> <!-- Bot predicates are set at load time, and cannot be changed at runtime. --><br /> <bot name="output" value="Logs/gossip.txt" /><br /> <bot name="randomSeed" value="1" /><br /> <bot name="series" value="Alpha" /><br /> <bot name="version" value="0.7.5 Alpha" /><br /> <bot name="location" value="Atlanta" /><br /> <bot name="name" value="Alice" /><br /> <!-- Default values for predicates, can be changed later at runtime. --><br /> <set name="dateFormat" value="yyyy-MM-dd HH:mm:ss" /><br /> <set name="name" value="dear friend" /><br /> <set name="me" value="Alice" /><br /> <set name="engine" value="ChatterBean" /><br /> <set name="topic" value="*" /><br /></context>

如上屬性,都可以用AIML的<bot>標籤及<get>標籤訪問得到。

splitters.xml:定義什麼是句子,即句子的結束符。
<splitters><br /> <splitter value="..." type="sentence"/><br /> <splitter value="." type="sentence"/><br /> <splitter value="!" type="sentence"/><br /> <splitter value="?" type="sentence"/><br /> <splitter value=";" type="sentence"/><br /> <splitter value="," type="word"/><br /> <splitter value=":" type="word"/><br /></splitters>

substitutions.xml:定義容錯規則及特殊字元映射等。
<substitutions><br /> <!-- Input substitutions correct spelling mistakes and convert "sentence"-ending characters into characters that will not be identified as sentence enders. --><br /> <input><br /> <correction><!--sentence correction--><br /> <substitute find="=reply" replace=""/><br /> <substitute find="name=reset" replace=""/><br /> <substitute find=":-)" replace=" smile "/><br /> <substitute find=":)" replace=" smile "/><br /> <substitute find=",)" replace=" smile "/><br /> <substitute find=";)" replace=" smile "/><br /> <substitute find=";-)" replace=" smile "/><br /> <substitute find=""" replace=""/><br /> <substitute find="/" replace=" "/><br /> <substitute find=">" replace=" gt "/><br /> <substitute find="<" replace=" lt "/><br /> <substitute find="(" replace=" "/><br /> <substitute find=")" replace=" "/><br /> <substitute find=" u " replace=" you "/><br /> <substitute find=" ur " replace=" your "/><br /> <substitute find=" you'd " replace=" you would "/><br /> <substitute find=" you're " replace=" you are "/><br /> <substitute find=" you re " replace=" you are "/><br /> <substitute find=" you've " replace=" you have "/><br /> <substitute find=" you ve " replace=" you have "/><br /> <substitute find=" what's " replace=" what is "/><br /> ...<br /> </correction><br /> <protection><!-- sentence protection --><br /> <substitute find=",what " replace=". what "/><br /> <substitute find=", do " replace=". do "/><br /> <substitute find=",do " replace=". do "/><br /> ...<br /> </protection><br /> </input><br /> <gender><br /> <substitute find=" on her " replace="on him"/><br /> <substitute find=" in her " replace="in him"/><br /> <substitute find=" his " replace="her"/><br /> <substitute find=" her " replace="his"/><br /> <substitute find=" him " replace="her"/><br /> ...<br /> </gender><br /> <person><br /> <substitute find=" I was " replace="he or she was"/><br /> <substitute find=" mine " replace="his or hers"/><br /> </person><br /> <person2><br /> ...<br /> <substitute find=" your " replace="my"/><br /> </person2><br /></substitutions>

比如在上面的聊天DEMO中, 我輸入what's your name, 和輸入what is your name, 都能得到正確的回答,這是因為:
在substitutions.xml檔案中有如下設定;
<substitute find=" what's " replace=" what is "/>

3:擴充AIML標籤(基於AIML的java引擎:chatterbean):

package bitoflife.chatterbean.aiml是chatterbean對於AIML標籤的實現包。目前為止,實現了大多數常用AIML標籤.
而對date標籤只有一個最簡單的實現, 也不支援java時間掩碼.
鄙人理想中的date標籤應該是:
<category><pattern>WHAT IS TIME *</pattern><template>It is <date format="h:mm a"/>.</template></category>
標籤類只需擴充TemplateElement即可。
所以, 修改之:
public class Date extends TemplateElement<br />{<br /> private final SimpleDateFormat format = new SimpleDateFormat();<br /> /**date tag format value, add by lcl**/<br /> private String formatStr = "";<br /> public Date()<br /> {<br /> }<br /> public Date(Attributes attributes)<br /> {<br /> //得到時間掩碼<br /> formatStr = attributes.getValue(0);<br /> }<br /> /*<br /> Methods<br /> */</p><p> public int hashCode()<br /> {<br /> return 13;<br /> }<br /> public String process(Match match)<br /> {<br /> try<br /> {<br /> format.applyPattern(formatStr);<br /> return format.format(new java.util.Date());<br /> }<br /> catch (Exception e)<br /> {<br /> return defaultDate(match);<br /> }<br /> }</p><p> private String defaultDate(Match match)<br /> {<br /> try<br /> {<br /> format.applyPattern((String) match.getCallback().getContext().property("predicate.dateFormat"));<br /> return format.format(new java.util.Date());<br /> }<br /> catch (NullPointerException e)<br /> {<br /> return "";<br /> }<br /> }</p><p>}

4:要想讓Alice足夠聰明, 必須要有足夠多的AIML, 如下地址是其所有的資料庫:

http://www.alicebot.org/downloads/sets.html

加入到程式中, Alice幾乎無所不知了。

5:如果需要做一個某領域的機器人專家, 基於AIML來實現,是一個不錯的選擇。

6:源碼下載(eclipse工程):

http://download.csdn.net/source/1683344

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.