一、   为什么Alice不支持中文
因为Alice的question都会被bitoflife.chatterbean.text.Transformations类中的fit函数过滤,而过滤的表达式就是:

private finalPattern fitting = Pattern.compile("[^A-Z0-9]+");

只会保留英文字符和数字字符。顺带说一句,因为Alice会将question全部转为大写,所以上面的表达式中没有a-z区间。

为了让中文不被过滤掉,就将上面的过滤式中添加中文字符。

privatefinal Pattern fitting = Pattern.compile("[^A-Z0-9\u4e00-\u9FA5]+")

二、   Alice支持中文的原理
先解释一下,Alice对英文支持的原理:

简而言之:在语料库中,找出匹配的用户question的pattern,再返回pattern对应的template内容作为answer。

详细点就是:Alice初始化时,将AIML文件中的<pattern>标签的内容根据空格切分,组成一个Graphmaster对象;用户的question也根据空格切分,根据匹配算法在Graphmaster对象中找到匹配的pattern标签,再返回该pattern对应的template内容。

Graphmaster参考:http://www.alicebot.org/documentation/matching.html

Alice支持英文中的关键一点就是:英文输入有空格,而中文输入没有空格,Alice就不会切分中文字符,只会把整个中文语句当做英文中一个单词。

所以支持中文的关键一点就是:为中文语句加空格。

马上想到了中文分词器,我用的是IK分词器.接下来问题就转化为:怎么为中文语句加空格?在什么地方加空格?

有两个地方要处理:

² 读取AIML文件中的pattern标签时,需要加空格。

² 读取用户question时,要加空格。

三、   代码实践
IK分词器封装函数
         这是就不多说了,csdn博客多得是IK分词器用法。

public static StringIKAnalysis(String str) {

if(str.getBytes().length == str.length()) {
//如果不包含中文,就直接返回。
return str;
}else {
//由于IK分词器,不支持特殊字符,所以将 * 改为中文字符“这是星号”,中文分词以后再将“这是星号”修正为为 *
//同理将 _改为中文字符串“这是下划线”,中文分词以后再将“这是下划线”修正为 _
str= str.replaceAll("\\*","这是星号").replaceAll("_","这是下划线");
}

StringBuffersb =new StringBuffer();
try {
byte[] bt =str.getBytes();
InputStreamip =new ByteArrayInputStream(bt);
Readerread =new InputStreamReader(ip);
//设置为智能分词
IKSegmenteriks =new IKSegmenter(read,true);
Lexemet;
while ((t =iks.next()) !=null) {
//在每个分词元之后添加空格
sb.append(t.getLexemeText()+" ");
}
//sb.delete(sb.length() - 1, sb.length());
}catch (IOException e) {
//TODOAuto-generated catch block
}

returnsb.toString().replaceAll("这是星号","*").replaceAll("这是下划线","_");
}

读取AIML文件的pattern标签时加空格
         AIML的读取解析工作由bitoflife.chatterbean.aiml.AIMLHandler类完成的。

修改pushTextNode函数,根据参数来判断是否调用中文分词器。

/**
*将一个节点的文本信息压入栈中,并根据参数决定是否调用中文分词器。
*@param isToSegment 标识是否调用中文分词器
*/
privatevoidpushTextNode(Boolean isToSegment) {
Stringpushed =text.toString();
text.delete(0,text.length());
if (ignoreWhitespace)
pushed= pushed.replaceAll("^[\\s\n]+|[\\s\n]{2,}|\n","");

if (!"".equals(pushed.trim())){
if(!isToSegment) {
stack.push(newText(pushed));
}else {
pushed= pushed.toUpperCase();
stack.push(newText(cn.edu.scut.cs.IKAnalyzer.ChineseSegmenter.IKAnalysis(pushed)));
}
}
}
在startElement和endElement函数中为pattern和that标签内的中文字符添加空格。将pushTextNode()函数的调用语句改为:

pushTextNode(qname.toLowerCase().equals("pattern")

||qname.toLowerCase().equals("that"));

顺带说一句that标签也可能需要中文分词的。

读取用户question时加空格
         这个很简单,在public void normalization(Sentencesentence)函数中第二行添加调用中文分词函数:

input =cn.edu.scut.cs.IKAnalyzer.ChineseSegmenter.IKAnalysis(input);
---------------------
作者:zhang-hui
来源:CSDN
原文:https://blog.csdn.net/zhang_hui_cs/article/details/22686951
版权声明:本文为博主原创文章,转载请附上博文链接!

alicebot的更多相关文章

  1. Artificial intelligence(AI)

    ORM: https://github.com/sunkaixuan/SqlSugar 微软DEMO: https://github.com/Microsoft/BotBuilder 注册KEY:ht ...

  2. 用 AIML 开发人工智能聊天机器人

    借助 Python 的 AIML 包,我们很容易实现人工智能聊天机器人.AIML 指的是 Artificial Intelligence Markup Language (人工智能标记语言),它不过是 ...

  3. 用PyAIML开发简单的对话机器人

    AIML files are a subset of Extensible Mark-up Language (XML) that can store different text patterns ...

  4. PHP人工智能库

    PHP虽然不是人工智能语言,但做人工智能理论上没问题,下面本人整理了一些PHP人工智能库.1.NLPTools(http://php-nlp-tools.com/)NLPTools是一个PHP自然语言 ...

  5. ALICE源代码分析

    前言 ALICE(爱丽丝)事实上是"人工语言计算机实体"的英文缩写. 它以前在往年(2000年.2001年和2004年)的勒布纳人工智能奖角逐中三次获胜.并在其它年度中也获过骄人的 ...

  6. PHP常用人工智能库

    1.NLPTools(http://php-nlp-tools.com/)NLPTools是一个PHP自然语言处理库.能进行文本分级,聚类等操作.2.Prediction Builder(https: ...

  7. 十个Chatbot框架介绍

    十个Chatbot框架介绍 原创 2016年12月13日 16:01:23 4616 Chatbot列表 1.  Artificial Intelligence Markup Language    ...

  8. http://www.freeopensourcesoftware.org

    Applications http://www.freeopensourcesoftware.org/index.php?title=Applications   Main Page > Thi ...

随机推荐

  1. kafka中消费者消费消息之每个线程维护一个KafkaConsumer实例

    1.首先启动自己的kafka集群哟. 启动zk: bin/zkServer.sh start conf/zoo.cfg. 验证zk是否启动成功: bin/zkServer.sh status conf ...

  2. React中的三大属性

    一.前言: 属性1:state 属性2:props 属性3:ref 与事件处理 二.主要内容: 属性1:state 1,认识: 1) state 是组件对象中最重要的属性,值是一个对象(可以包含多个数 ...

  3. 解决关于 npm build --prod ,出现 ERROR in budgets, maximum exceeded for initial. Budget 5 MB was exceeded by 750 kB的问题

    问题: 执行命令 :npm build --pord,出现以下错误: WARNING :. Ignoring. WARNING MB was exceeded by 3.73 MB. ERROR MB ...

  4. opencv::分水岭图像分割

    分水岭分割方法原理 (3种) - 基于浸泡理论的分水岭分割方法 (距离) - 基于连通图的方法 - 基于距离变换的方法 图像形态学操作: - 腐蚀与膨胀 - 开闭操作 分水岭算法运用 - 分割粘连对象 ...

  5. Mysql中的sql是如何执行的 --- 极客时间学习笔记

    MySQL中的SQL是如何执行的 MySQL是典型的C/S架构,也就是Client/Server架构,服务器端程序使用的mysqld.整体的MySQL流程如下图所示: MySQL是有三层组成: 连接层 ...

  6. day08 作业

    1. 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中 即: {'k1' ...

  7. pipenv 管理虚拟环境

    pipenv --python 3.6 创建虚拟环境 vim Pipfile —> 修改源 为阿里云镜像 https://mirrors.aliyun.com/pypi/simple [pack ...

  8. liteos队列(五)

    1. 概述 队列又称消息队列,是一种常用于任务间通信的数据结构,实现了接收来自任务或中断的不固定长度的消息,并根据不同的接口选择传递消息是否存放在自己空间.任务能够从队列里面读取消息,当队列中的消息是 ...

  9. linux 线程基础

    线程基础函数 查看进程中有多少个线程,查看线程的LWP ps -Lf 进程ID(pid) 执行结果:LWP列 y:~$ ps -Lf 1887 UID PID PPID LWP C NLWP STIM ...

  10. springboot项目打成jar包后台运行在linux上

    背景:springboot2为为主体搭建的项目,直接打成jar包,上传到linux上面 启动项目:java -jar xx.jar 这样很方便,但是不能关闭窗口,否则项目就停了 后台启动: nohup ...