摘要: 此版本改进为:分词时采用了完全匹配方式(自命名的),也即将符合字典条目的词全部切分出来,在基于字典的分词中达到了“分无可分”的程度;分词时完全按照标准分词来进行,这样保证了在和一些高亮显示组件如highlighter一起使用时,能准确无误的将命中进行高亮显示,避免了Google高亮显示的 Bug;配置文件的存放支持相对路径,这样更灵活,更方便应用在一些虚拟机上;字典条目支持导入到内存中,也就是在原有JDBM字典系统的基础上增加内存字典系统,且能方便自定义导入多少条目到内存中,能自定义使用内存还是JDBM字典系统还是两者结合起来使用,从而提高了索引创建速度;改进了对搜索词的处理;能对字典系统进行管理;另外也提供适合jdk1.5的版本。
一、改进具体说明:
1、分词时采用了完全匹配方式(自命名的),也就是将符合字典条目的词全部切分出来,在基于字典的分词中达到了“分无可分”的程度
典型例子如对“中华人民共和国”的分词为:
中华 中华人民 中华人民共和国 华人 人民 人民共和国 共和 共和国
2、分词时完全按照标准分词来进行,这样保证了在和一些高亮显示组件如highlighter一起使用时,能准确无误的将命中进行高亮显示。在后面将说明何谓标准分词,另外也会对上篇随笔中Google搜索在对命中进行高亮显示时候的bug产生的原因一并进行说明,标准分词的结果可以参见(篇幅太长,故不在此处贴出):http://www.shuzhen.net/result.html;另外,有需要highlighter的朋友可以参见:http://www.zihou.com/bbs/htm_data/15/0810/512.html,里面有highlighter-2.2.0的介绍及下载
3、配置文件的存放支持相对路径,这样更灵活,更方便应用在一些虚拟机上
这个也是应一位叫ameng的朋友的建议而改进的,也是非常有道理的,因为有时我们使用的虚拟机根本就不知道根目录是什么或很难获知,现在统一配置在WEB-INF/classes 下,比如现在shuzhen.properties(已经将dict.properties改为了shuzhen.properties)中的 pDict=dict/dict.txt就表示WEB-INF/classes/dict/dict.txt
4、字典条目支持导入到内存中,也就是在原有JDBM字典系统的基础上增加内存字典系统,既可以将字典系统只配置在JDBM系统中,也可以将字典系统只配置在内存系统中,也可以两者结合在一起使用,当两者结合一起使用的时候,会优先调用内存字典系统,当且仅当在内存字典系统中没有找到匹配项时才调用JDBM字典系统;这样做的好处是既能利用内存的速度提高索引创建的速度,也能通过自己灵活的配置(参见shuzhen.properties)在内存中导入了足够多的字典条目时不会出现内存溢出的错误。
5、对搜索词的处理也改进了,因为分词时候的匹配发生了变化,所以对搜索词的处理也随之发生了变化,比如对搜索词:
1949年10月1日,中华人民共和国在\"北京\"宣-告成立
两种方式处理后的结果分别为:
严格匹配:1949 10 1 中华 中华人民 中华人民共和国 华人 人民 人民共和国 共和 共和国 "北京" -告成 成立
模糊匹配:1949 年 10 月 1 日 中华 中华人民 中华人民共和国 华人 人民 人民共和国 共和 共和国 在 "北京" 宣 -告成 成立
值得注意的是:读特殊符号的处理保留了三个特殊符号,分别是:| 、- 、",这也是完全参照Google对特殊符号的处理而改的,去掉了上个版本中保留的“!”
6、对字典系统的处理
主要是在之前只对JDBM字典系统进行管理的基础上增加了对内存字典系统进行管理的功能
7、提供适合jdk1.5的版本
版本不兼容的问题比较多,所以这次提供了适合jdk1.5的版本
二、什么是分词标准
“分词标准”这个词也是我自命名的(我不知道这种称呼是否已经存在了,我没看到过,也没去查),那么什么是分词标准呢?为什么分词还要讲究个标准?如果不讲究标准会如何?
在讲这个问题前,我们先来说下我们都熟知的WEB标准,WEB标准一个很主要的地方就是要求各个不同的浏览器厂商都支持统一的页面样式(css样式和页面标记如div),那么这样做的好处就是能使同一个遵循了标准设计的页面在不同的浏览器(IE、Firefox、Opera等)下的效果一样,反之,同一个页面(不一定遵循web标准的)在某一个浏览器(不一定遵循web标准的)下是正常的,但在另一个浏览器下则页面错乱,这样的页面我想我们大家都见过很多了(这样的页面是不是很糟糕?).
分词的标准与这个也是很类似的,分词就相当于页面,那么什么相当于浏览器呢?highlighter?对,就是highlighter!那遵循的标准应当是什么呢?先来讲下分词器分词的原理,举个例子:有两队人,第一队有编号分别为1234567的7个人,第二队有编号分别为abcdefg的7个人,这个时候要点名了:34两个人在哪个队?回答是:34两个人在第一队,这完全没有错;进一步说明为:34两个人在第一队且在第一队的左数34两个位置,OK,标准出来了,在上面的进一步说明中就是分词的标准!
分词标准概括起来只有一句话:不仅要知道词还要知道词的位置!
那么分词的时候,我们通常要记住当前被切分出来的词的两个关键值:一个是起始位置(start),另一个就是偏移量(length),比如在http://www.shuzhen.net/result.html中举两个例子:
1 卫生部长>>>start>>>2>>>length>>>4 //start=2表示 卫 的起始位置为2,而length=4表示从start开始偏移4位,就是 卫生部长
2 部长>>>start>>>4>>>length>>>2 //start=4表示 部 的起始位置(可以数一下刚好),而length=2表示偏移2位,就是 部长
大家看到没有?这与上面举的点名例子从本质上来说是不是一样的呀?
但假如分词的时候没有按照标准来办如何呢?比如:卫生部长>>>start>>>2>>>length>>>3,那么在搜索卫生部长 的时候还是会搜到对应的结果(这与点名只知道在哪一个队也是一样的),但是高亮的时候加亮到 卫生部 ,而不是正确的“卫生部长”!
highlighter就是遵循的这样一个分词标准,所以如果我们想要使我们的分词器在与highlighter一起使用的时候高亮显示正确,那么我们就一定要严格按照分词标准来分词,否则高亮就会错误!
关于highlighter高亮显示错误的问题,我在网上看到有帖子说,highlighter高亮显示英文的时候没有问题,但高亮显示中文有时就会出错,而错以为原因在于highlighter,其实我们现在知道了,错误其实主要(是因为也不排除highlighter程序的可能出错)在于我们的分词器没有遵循分词标准(当然之前好像也没人提起这个),highlighter本身对英文和中文是一视同仁的。
对于我个人而言,我也感觉比较惭愧,惭愧的地方是在我没有发现Google高亮显示的BUG前,我也没有意识到这个问题,在1.1.3版本中也存在高亮有时会出错的问题,之所有是有时,是因为虽然我们没有有意识的去按标准来分词,但大多数时候还是不知不觉所分的词符合了标准,这也是有人认为国人写的中文分词器在高亮显示有时不准确的原因。
所以以后当我们发现应用中文分词器来与highlighter一起使用进行高亮显示不正确时,我们就能99%的肯定是分词器的问题而不是highlighter的问题(在正确使用highlighter的前提下)
但这个1.1.4版本可以放心与highlighter一起使用,高亮显示不会有问题,因为在写分词的时候自己是有意识地去按照这种标准进行,另外我也测试切分了一些各有特色的词,到目前为止没有发现问题!(所谓百密难免一疏,如果发现有问题请反馈给作者,谢谢)
三、Google搜索高亮显示BUG的原因之我见
关于Google搜索高亮显示的Bug在我上一篇随笔中有图片说明,这里不再重复,讲述了上面的分词标准后,对Google搜索高亮显示Bug的原因也就很清楚了,用来加亮的组件出错的几率很小,所以主要原因还是Google在分词的过程中没有按照标准来切分,或者按照标准切分了,但由于分词过程中哪里出了点错而导致了这个Bug.当然这个Bug其实说起来也并不是很严重,但不管如何也总是个Bug.这点可能是让人感到有点难以置信的,Google搜索引擎这么厉害,竟然也有Bug!但事实就是如此,这也说明了对中文(双字节)进行分词的确是一件比较困难的事情,分词越精确,出错的概率也越大