论坛首页 Java企业应用论坛

庖丁分词的源码分析

浏览 1585 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-04-08  
在网上也看到了不少庖丁分词的使用说明,但是源码分析比较少。但是我也不想死板的一步步的把代码说一遍,这个多debug几次就ok了。我想说说比较关键或有意思的地方。

1 庖丁只要是同一个配置文件就会是同一个庖丁对象,所以其实你可以放心的new。

2 庖丁的配置文件改变他是会去检查的,可以通过设置paoding.dic.detector.interval这个来设置检查的时间间隔。

3 庖丁使用的不是原始的字典文件,而是处理过后放到.compiled文件夹,原始的分散多个的字典文件也会被合成少数几个文件,主要的一个是vocabulary,一个是noise,vocabulary是主要的查找对象,noise则是要排除的。

4 庖丁有两种处理机制,一个是最多分词,一个是最长分词。
paoding.analyzer.mode=most-words  最多分词
paoding.analyzer.mode=max-word-length 最长分词
这两个机制同样用到了字典的处理过程。例如 如果是用最多分词,原始字典文件中有 二手 汽车 二手汽车,那么.compiled文件夹最后得到的只有二手 汽车,二手汽车就没有了,因为他是由二手和汽车组成的。

5 庖丁分词最主要的有3个,一个是字典,一个是beef,就是要分的词,一个是knife,就是分词的规则。分词的结果是个LinkedList,不断的next得到全部的分词结果。在生成LinkedList过程中,同样会用到最长和最多的规则。

6 庖丁分词主要用的是一个叫CJKKnife的分词规则,其中的dissect方法有300行,里面有几乎全部的逻辑,不过这个不是很好懂,虽然作者写了不少注释,我也是debug了几次才搞懂的。


7 庖丁的字典也比较有意思,我最初的想法是map,把每个字典都做为一个key,查的时候如果对应的key为null,那么就没这个字典。但是这个太天真了,首先这个会浪费很多的空间,我们还需要以某个字开头的是否在字典里。直接map也是不能实现的。
庖丁的做法是:有一个大的数组,记录所有的字典。一个多叉树,不同字开头的不同分叉,如果得到的集合小于16,直接一个二叉树,多于16的话,继续比较下一个字,又是多个分叉,这样循环下去。
这样的空间占用还是比较小的,而且一个分叉下面没有只分叉,那么说明这个开头的肯定不在字典里了。查找的时候也很快,一个个分叉查下去是很快的。

8 庖丁的分词逻辑是:从第一个字开始,去字典里去找,然后前两个字,然后前3个字,如果查到后面的不可能出现在字典里,那么现在从第二个字开始,然后第2,3字,然后3,4字。。如果查到后面的不可能出现在字典里,那么现在从第二个字开始....

9 庖丁遇到非汉字会强行分开。

10 庖丁增加了对《》“”这些的处理,这些词会作为一个完整的词出现。

总的来说基本就是这样的,生成字典,根据字典分词。(字典没有没两个字一分词。)
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics