论坛首页 Java企业应用论坛

Lucene中文分词“庖丁解牛”

浏览 129965 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-01-25  
Qieqie 写道

感觉在RedSage.com上申请个版本控制服务是个不错注意




code.google.com的svn最好用了啊,又不用申请
前阵子光纤断了我都照用,

sf目前的速度基本废了



你求职的事情,我发你站内短信了,请回复或加我msn
0 请登录后投票
   发表时间:2007-01-25  
billgmh 写道
我也正在就中文分词方向进行研究,也是使用首字hash+折半查找的方法构造词典的,是我尝试过分词效率最高的一种词典实现方式,但是最近我收集到一份论文《基于双数组Trie树的词典查询算法》,发现效率可能比基于双数组Trie树的词典查询算法还要高(利用有穷自动机的原理与Trie树的易扩展性),不知楼主有没有尝试过这种方法呢?


加粗的句子看不明白是什么意思。

HashBinaryDictionary.java.rar中的java文件,他不是单纯的首字hash+折半查找。

只要参数设置的好,可以认为采用hash查找的时间复杂度是O(1),而折半不管怎么说也是log2n,而且每次折半比较都要对字符串和目标词语各个字符进行compare。所以,不能只满足对首字进行hash。

我的原始想法是: 每读入字符串一个新的字符,都要能够把字符串限制到最可能小的位置范围中,直至这个限制在很小很小的范围内(由下面的C来衡量),然后在最终的这个很小很小的范围内判断是否有该字符串,从而达到最快查找。[分词效率高不高,关键是词典查找算法构造得是否优化关系很大,跟分词采用策略关系较少]

我具体采用的是,尽量hash每个字符:

第一次 对第0个字进行hash,所有首字相同的词语是一个子集合。这个子集合相对整个词典称为子词典。
循环每个子词典
   
  • 如果这个子词典的词语数 < 某个常数C(我暂使用C=16) 那这个子词典使用二分查找(对应BinaryDictionary.java)。
  •     
  • 否则 继续对这个子词典做与第一次一样的hash(只是这一次hash的字符是上一次hash的字符的后一位,即上次是第0个字符,这一次就是第1个字符,以此类推),分解出再下一级的子词典。

极端情况下设置C=2,那就是逐字匹配算法,词语查找就和词典的词汇量没有关系了,O(1)。
[该算法已在HashBinaryDictionary.java.rar的java体现。需要下载该rar替代Paoding.rar中的HashBinaryDictionary.java]
  • 描述: 词典分级Hash示意图
  • 大小: 22.2 KB
0 请登录后投票
   发表时间:2007-01-25  
Qieqie 写道
菲利浦思 写道
这种切分还是有很明显的缺点.例如下面一段文字:
"发展社区老年活动场所和服务设施"

如果我想搜索日本的和服相关资料,输入关键字"和服"的时候,上面的资料也会被搜索出来



搜索引擎是第一步搜索:
      在浩瀚的信息中,快速集结最后可能是所想要的结果,按照可能是最好的顺序展现出来。

人的眼睛是第二步搜索:
      找寻最符合要求的结果,同时将机器无法轻易识别的少数“无效”结果过滤

“和服”问题,涉及了汉语语义的问题,几乎不可完全解决(可作为“特例”解决,或通过排序方法,将他排到相对靠后等价解决)。




涉及语义的问题也可以通过数学的方法来解决。楼主可以参考一下google上的那个基于最短路径的切分方法。
象“结合成分子时”这样的句子用词库的最长匹配是解决不了。基于概率的最短路径就可以。
0 请登录后投票
   发表时间:2007-01-25  
我矛盾中....

“羽毛球拍卖了”如何解词? 最短路径的切分方法的切分结果会是什么?
0 请登录后投票
   发表时间:2007-01-26  
对了,“庖丁”是支持自定义算法的。实现特制的Knife,然后注册到Paoding这个类便可。现在这个注册过程由XFactory.java负责,有兴趣时可以弄成Spring xml配置。
0 请登录后投票
   发表时间:2007-01-26  
Qieqie 写道
billgmh 写道
我也正在就中文分词方向进行研究,也是使用首字hash+折半查找的方法构造词典的,是我尝试过分词效率最高的一种词典实现方式,但是最近我收集到一份论文《基于双数组Trie树的词典查询算法》,发现效率可能比基于双数组Trie树的词典查询算法还要高(利用有穷自动机的原理与Trie树的易扩展性),不知楼主有没有尝试过这种方法呢?


加粗的句子看不明白是什么意思。

HashBinaryDictionary.java.rar中的java文件,他不是单纯的首字hash+折半查找。

只要参数设置的好,可以认为采用hash查找的时间复杂度是O(1),而折半不管怎么说也是log2n,而且每次折半比较都要对字符串和目标词语各个字符进行compare。所以,不能只满足对首字进行hash。

我的原始想法是: 每读入字符串一个新的字符,都要能够把字符串限制到最可能小的位置范围中,直至这个限制在很小很小的范围内(由下面的C来衡量),然后在最终的这个很小很小的范围内判断是否有该字符串,从而达到最快查找。[分词效率高不高,关键是词典查找算法构造得是否优化关系很大,跟分词采用策略关系较少]

我具体采用的是,尽量hash每个字符:

第一次 对第0个字进行hash,所有首字相同的词语是一个子集合。这个子集合相对整个词典称为子词典。
循环每个子词典
   
  • 如果这个子词典的词语数 < 某个常数C(我暂使用C=16) 那这个子词典使用二分查找(对应BinaryDictionary.java)。
  •     
  • 否则 继续对这个子词典做与第一次一样的hash(只是这一次hash的字符是上一次hash的字符的后一位,即上次是第0个字符,这一次就是第1个字符,以此类推),分解出再下一级的子词典。

极端情况下设置C=2,那就是逐字匹配算法,词语查找就和词典的词汇量没有关系了,O(1)。
[该算法已在HashBinaryDictionary.java.rar的java体现。需要下载该rar替代Paoding.rar中的HashBinaryDictionary.java]


多谢楼主的解释,受教了……我之前也尝试过双重Hash,但是效率没有首字hash+折半查找高,我第一层Hash是根据词汇的长度来计算的,第二层Hash是首字Hash,最后得到词汇子表进行折半查找,可是我发现效率反而比不上首字Hash+折半查找来得高。
PS:加粗部分写错了,《基于双数组Trie树的词典查询算法》文中介绍的词典实现宣称比现有的词典实现的效率都高,楼主有空可以上google搜索这篇论文来比对一下。
  • 描述: 双层Hash结构
  • 大小: 64.8 KB
0 请登录后投票
   发表时间:2007-01-26  
Qieqie同志


能不能把你的代码挪到我的开源项目里?保留你的声明和作者名,包名和代码要修改
0 请登录后投票
   发表时间:2007-01-26  
alin_ass 写道
Qieqie同志


能不能把你的代码挪到我的开源项目里?保留你的声明和作者名,包名和代码要修改


同问,作者能不能定下来用什么开源协议?否则我们不敢用啊。
0 请登录后投票
   发表时间:2007-01-26  
考虑中,我的思考点是:

1、能够促进持续改进,相互提升
2、鼓励实践中做适应性的变更
3、保护开放源代码机制


有人专门研究各开源协议的不?
0 请登录后投票
   发表时间:2007-01-26  
呵呵,,泼点冷水,,从应用角度来看

我觉得个人做lucene中文分词,没有什么商业价值.
因为中文分词牵涉的不单单是编程知识,还有自然语言等方面的知识.
YAHOO目前采用的中文分词还是购买的.
什么样的公司需要自己订做中文分词? 就lucene的两个analyzer足够用了。
有多少是做类似yahoo,baidu这样大的搜索引擎,,只有这样的公司需要中文分词,国内还有其他公司需要自己中文分词吗?我觉得都用不到。包括sina,163,sohu这样的门户。


从技术角度我支持你。

0 请登录后投票
论坛首页 Java企业应用版

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