人工智能:用AIML写一个机器人

转自:http://lcllcl987.iteye.com/blog/473256


最近搞了一把人工智能,感觉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到底长啥样:

Xml代码   收藏代码
  1. <aiml>  
  2. <category><pattern>WHO WANTS TO KNOW</pattern><template>ALICE wants to know.</template></category>       
  3. <category><pattern>WHY ARE YOU CALLED</pattern><template>   <srai>WHAT DOES ALICE STAND FOR</srai>    </template></category>       
  4. <category><pattern>WHY ARE YOU NAMED *</pattern><template>   <srai>WHAT DOES ALICE STAND FOR</srai>    </template></category>       
  5. <category><pattern>WHY DO YOU DREAM *</pattern><template>I dream about adding new code to ALICE.</template></category>       
  6. <category><pattern>WHY SILVER</pattern><template>ALICE is competing for the Loebner Silver Medal.</template></category>       
  7. <category><pattern>WHY WERE YOU NAMED ALICE</pattern><template><srai>WHAT DOES ALICE STAND FOR</srai></template></category>        
  8. <category><pattern>WHY WERE YOU NAMED</pattern><template><srai>WHAT DOES ALICE STAND FOR</srai></template></category>        
  9. <category><pattern>WHY</pattern><that>I AM SMARTER *</that><template>ALICE won an award for being the "most human" robot.</template></category>       
  10. <category><pattern>WOULD ALICE *</pattern><template><srai>WOULD YOU <star/> </srai> </template></category>  
  11. </aiml>  
 


简单说明一下AIML的常用标签:
1:pattern tag:支持模式匹配(正则表达式,模糊匹配),及基于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表现如下,可见其多么聪明:

Html代码   收藏代码
  1. Alice>Hi ya! Welcome!  
  2. you say>what's your name  
  3. Alice>sorry, what?  
  4. you say>this is not a good answer  //开始学习功能  
  5. Alice>Sorry. What would be a good answer?  
  6. you say>my name is Alice  
  7. Alice>Alright! You can ask me again to see if I got it.  
  8. you say>what's your name  
  9. Alice>my name is Alice  
  10. you say>what is your name  
  11. Alice>my name is Alice  
  12. you say>my name is Lichunlei  
  13. Alice>hello, Lichunlei.  
  14. you say>do you remember me?  
  15. Alice>Your name is Lichunlei, seeker.  //Alice的记忆功能  
  16. you say>what's time now?  
  17. Alice>It is 10:59 A.M.  
  18. you say>what date is today?  
  19. Alice>Monday.  
 



如果感觉机器人Alice的答案不满意, 只需输入包含not和good answer的句子,在你的指导下,Alice就可以开始学习新知识。

让它如此智慧的原因就是AIML文件, 此为机器人的大脑.
下为Alice的AIML文件:

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="ISO-8859-1"?>  
  2. <aiml>  
  3. <!-- Copyright (c) 2007 ALICE A.I. Foundation, Inc. -->  
  4. <!-- Last modified Seo 21, 2009, by Lichunlei -->  
  5.   
  6. <category><pattern>WHAT IS TIME *</pattern><template>It is <date format="h:mm a"/>.</template></category>                           
  7. <category><pattern>WHAT DAY IS TODAY</pattern><template><date format="E"/>.</template></category>  
  8. <category><pattern>WHAT IS TODAY *</pattern><template><date format="EEE"/>.</template></category>  
  9. <category><pattern>MY NAME IS *</pattern><template><think><set name="name"><star/></set></think>hello, <get name="name"/>.</template></category>     
  10. <category><pattern>DO YOU REMEMBER ME</pattern><template>Your name is <get name="name"/>, seeker.</template></category>  
  11. <category><pattern>I CAN NOT *</pattern><template>Why can't you do <set name="it"><person/></set>?</template></category>  
  12. <category><pattern>MY INPUT</pattern> <template> 1:<input index="1"/> 2:<input index="2"/> 3:<input index="3"/></template></category>  
  13. <category><pattern>*</pattern><template>sorry, what?</template></category>                                           
  14.   
  15.   <!-- Greeting categories. -->  
  16.   <category>  
  17.     <pattern>WELCOME</pattern>  
  18.     <template>  
  19.       <think>  
  20.         <system> <!-- Defines a method to create new categories from user input at run-time. -->  
  21.           import bitoflife.chatterbean.AliceBot;  
  22.           import bitoflife.chatterbean.Context;  
  23.           import bitoflife.chatterbean.Graphmaster;  
  24.           import bitoflife.chatterbean.aiml.Category;  
  25.           import bitoflife.chatterbean.text.Transformations;  
  26.            
  27.           void learn(String pattern, String template)  
  28.           {  
  29.             /* The "match" variable represents the current matching context. */  
  30.             AliceBot bot = match.getCallback();  
  31.             Context context = bot.getContext();  
  32.             Transformations transformations = context.getTransformations();  
  33.      
  34.             pattern = transformations.normalization(pattern);  
  35.             Category category = new Category(pattern, new String[] {template});  
  36.             Graphmaster brain = bot.getGraphmaster();  
  37.             brain.append(category);  
  38.           }  
  39.         </system>  
  40.       </think>  
  41.       Hi ya! Welcome!  
  42.     </template>  
  43.   </category>  
  44.   
  45.   <!-- A category set to learn simple user-fed categories. -->  
  46.   <category>  
  47.     <pattern>* NOT *  GOOD ANSWER</pattern>  
  48.     <template>  
  49.       Sorry. What would be a good answer?  
  50.     </template>  
  51.   </category>  
  52.   <category>  
  53.     <pattern>_</pattern>  
  54.     <that>WHAT WOULD BE A GOOD ANSWER</that>  
  55.     <template>  
  56.       <system>learn("<input index="3"/>", "<input index="1"/>")</system>  
  57.       Alright! You can ask me again to see if I got it.  
  58.     </template>  
  59.   </category>  
  60. </aiml>  
 



之所以Alice可以学习, 重要的一点是<input/>标签,此标签记住了之前对方的聊天记录, 通过index可以得到(倒序索引)

程序相对简单,两个class:
Alice工厂: AliceBotMother

Java代码   收藏代码
  1. package co.aiml;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.ByteArrayOutputStream;  
  5.   
  6. import bitoflife.chatterbean.AliceBot;  
  7. import bitoflife.chatterbean.Context;  
  8. import bitoflife.chatterbean.parser.AliceBotParser;  
  9. import bitoflife.chatterbean.util.Searcher;  
  10.   
  11. public class AliceBotMother  
  12. {  
  13.    
  14.   private ByteArrayOutputStream gossip;  
  15.    
  16.    
  17.   public void setUp()  
  18.   {  
  19.     gossip = new ByteArrayOutputStream();  
  20.   }  
  21.    
  22.   public String gossip()  
  23.   {  
  24.     return gossip.toString();  
  25.   }  
  26.   
  27.   public AliceBot newInstance() throws Exception  
  28.   {  
  29.     Searcher searcher = new Searcher();  
  30.     AliceBotParser parser = new AliceBotParser();  
  31.     AliceBot bot = parser.parse(new FileInputStream("Bots/context.xml"),  
  32.                                 new FileInputStream("Bots/splitters.xml"),  
  33.                                 new FileInputStream("Bots/substitutions.xml"),  
  34.                                 searcher.search("Bots/mydomain"".*\\.aiml"));  
  35.   
  36.     Context context = bot.getContext();  
  37.     context.outputStream(gossip);  
  38.     return bot;  
  39.   }  
  40. }  
 



命令行聊天程序:

Java代码   收藏代码
  1. package co.aiml;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6.   
  7. import bitoflife.chatterbean.AliceBot;  
  8.   
  9. public class Chat  
  10. {  
  11. public static final String END = "bye";  
  12.   
  13. public static String input()  
  14. {  
  15. BufferedReader in = new BufferedReader(new InputStreamReader(System.in));  
  16. System.out.println("you say>");  
  17. String input = "";  
  18. try  
  19. {  
  20. input = in.readLine();  
  21. catch (IOException e) {  
  22. // TODO Auto-generated catch block  
  23. e.printStackTrace();  
  24. }  
  25. return input;  
  26. }  
  27.   
  28. public static void main(String[] args) throws Exception  
  29. {  
  30.      AliceBotMother mother = new AliceBotMother();    
  31.      mother.setUp();  
  32.      AliceBot bot = mother.newInstance();  
  33.      System.err.println("Alice>" + bot.respond("welcome"));  
  34. while(true)  
  35. {  
  36. String input = Chat.input();  
  37. if(Chat.END.equalsIgnoreCase(input))  
  38. break;  
  39.   
  40. System.err.println("Alice>" + bot.respond(input));  
  41. }  
  42.   
  43. }  
  44. }  
 



需要说明的是:

Java代码   收藏代码
  1. AliceBot bot = parser.parse(new FileInputStream("Bots/context.xml"),  
  2.                             new FileInputStream("Bots/splitters.xml"),  
  3.                             new FileInputStream("Bots/substitutions.xml"),  
  4.                             searcher.search("Bots/mydomain"".*\\.aiml"));  
 



context.xml:设置application的属性, 及时间格式等可变属性

Xml代码   收藏代码
  1. <context>  
  2. <!-- The id is a unique string that identifies this context. -->  
  3. <bot name="id" value="test_cases" />  
  4.   
  5. <!-- Bot predicates are set at load time, and cannot be changed at runtime. -->  
  6. <bot name="output" value="Logs/gossip.txt" />  
  7. <bot name="randomSeed" value="1" />  
  8. <bot name="series" value="Alpha" />  
  9. <bot name="version" value="0.7.5 Alpha" />  
  10. <bot name="location" value="Atlanta" />  
  11. <bot name="name" value="Alice" />  
  12.   
  13. <!-- Default values for predicates, can be changed later at runtime. -->  
  14. <set name="dateFormat" value="yyyy-MM-dd HH:mm:ss" />  
  15. <set name="name" value="dear friend" />  
  16. <set name="me" value="Alice" />  
  17. <set name="engine" value="ChatterBean" />  
  18. <set name="topic" value="*" />  
  19. </context>  
 



如上属性,都可以用AIML的<bot>标签及<get>标签访问得到。

splitters.xml:定义什么是句子,即句子的结束符。

Xml代码   收藏代码
  1. <splitters>  
  2.   <splitter value="..." type="sentence"/>  
  3.   <splitter value="." type="sentence"/>  
  4.   <splitter value="!" type="sentence"/>  
  5.   <splitter value="?" type="sentence"/>  
  6.   <splitter value=";" type="sentence"/>  
  7.   <splitter value="," type="word"/>  
  8.   <splitter value=":" type="word"/>  
  9. </splitters>  
 

substitutions.xml:定义容错规则及特殊字符映射等。

Xml代码   收藏代码
  1. <substitutions>  
  2.   <!-- Input substitutions correct spelling mistakes and convert "sentence"-ending characters into characters that will not be identified as sentence enders. -->  
  3.   <input>  
  4.     <correction><!--sentence correction-->  
  5.       <substitute find="=reply" replace=""/>  
  6.       <substitute find="name=reset" replace=""/>  
  7.       <substitute find=":-)" replace=" smile "/>  
  8.       <substitute find=":)" replace=" smile "/>  
  9.       <substitute find=",)" replace=" smile "/>  
  10.       <substitute find=";)" replace=" smile "/>  
  11.       <substitute find=";-)" replace=" smile "/>  
  12.       <substitute find="&quot;" replace=""/>  
  13.       <substitute find="/" replace=" "/>  
  14.       <substitute find="&gt;" replace=" gt "/>  
  15.       <substitute find="&lt;" replace=" lt "/>  
  16.       <substitute find="(" replace=" "/>  
  17.       <substitute find=")" replace=" "/>  
  18.       <substitute find=" u " replace=" you "/>  
  19.       <substitute find=" ur " replace=" your "/>  
  20.       <substitute find=" you'd " replace=" you would "/>  
  21.       <substitute find=" you're " replace=" you are "/>  
  22.       <substitute find=" you re " replace=" you are "/>  
  23.       <substitute find=" you've " replace=" you have "/>  
  24.       <substitute find=" you ve " replace=" you have "/>  
  25.      <substitute find=" what's " replace=" what is "/>  
  26.      ...  
  27.     </correction>  
  28.     <protection><!-- sentence protection -->  
  29.       <substitute find=",what " replace=".  what "/>  
  30.       <substitute find=", do " replace=".  do "/>  
  31.       <substitute find=",do " replace=".  do "/>  
  32.       ...  
  33.     </protection>  
  34.   </input>  
  35.   <gender>  
  36.     <substitute find=" on her " replace="on him"/>  
  37.     <substitute find=" in her " replace="in him"/>  
  38.     <substitute find=" his " replace="her"/>  
  39.     <substitute find=" her " replace="his"/>  
  40.     <substitute find=" him " replace="her"/>  
  41.     ...  
  42.   </gender>  
  43.   <person>  
  44.     <substitute find=" I was " replace="he or she was"/>  
  45.     <substitute find=" mine " replace="his or hers"/>  
  46.   </person>  
  47.   <person2>  
  48.     ...  
  49.     <substitute find=" your " replace="my"/>  
  50.   </person2>  
  51. </substitutions>  
 



比如在上面的聊天DEMO中, 我输入what's your name, 和输入what is your name, 都能得到正确的回答,这是因为:
在substitutions.xml文件中有如下设置;

Xml代码   收藏代码
  1. <substitute find=" what's " replace=" what is "/>  
 


3:扩展AIML标签(基于AIML的java引擎:chatterbean):
package bitoflife.chatterbean.aiml是chatterbean对于AIML标签的实现包。目前为止,实现了大多数常用AIML标签.
而对date标签只有一个最简单的实现, 也不支持java时间掩码.
鄙人理想中的date标签应该是:

Xml代码   收藏代码
  1. <category><pattern>WHAT IS TIME *</pattern><template>It is <date format="h:mm a"/>.</template></category>  
 


标签类只需扩展TemplateElement即可。
所以, 修改之:

Java代码   收藏代码
  1. public class Date extends TemplateElement  
  2. {  
  3.   
  4.   private final SimpleDateFormat format = new SimpleDateFormat();  
  5.   
  6.   /**date tag format value, add by lcl**/  
  7.   private String formatStr = "";  
  8.   
  9.   public Date()  
  10.   {  
  11.   }  
  12.   
  13.   public Date(Attributes attributes)  
  14.   {  
  15.   //得到时间掩码  
  16.   formatStr = attributes.getValue(0);  
  17.   }  
  18.   
  19.   public String process(Match match)  
  20.   {    
  21.     try  
  22.     {  
  23.     format.applyPattern(formatStr);  
  24.     return format.format(new java.util.Date());  
  25.     }  
  26.     catch (Exception e)  
  27.     {  
  28.     return defaultDate(match);  
  29.     }  
  30.   }  
  31.    
  32.   private String defaultDate(Match match)  
  33.   {  
  34.     try  
  35.     {  
  36.       format.applyPattern((String) match.getCallback().getContext().property("predicate.dateFormat"));  
  37.       return format.format(new java.util.Date());  
  38.     }  
  39.     catch (NullPointerException e)  
  40.     {  
  41.       return "";  
  42.     }  
  43.   }  
  44.    
  45. }  
 




4:要想让Alice足够聪明, 必须要有足够多的AIML, 如下地址是其所有的资料库:
http://www.alicebot.org/downloads/sets.html
加入到程序中, Alice几乎无所不知了。

5:如果需要做一个某领域的机器人专家, 基于AIML来实现,是一个不错的选择。

6:附件是Alice源码,及其上面的DEMO,eclipse工程.


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值