eaglet

本博专注于基于微软技术的搜索相关技术
posts - 189, comments - 3717, trackbacks - 26, articles - 0
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
KTDictSeg 分词组件1.3版本 部分算法讨论 -- 分词粒度
作者:肖波
    KTDictSeg 分词组件1.3版本已经接近完成,只剩下最后的一点功能。在KTDictSeg 分词组件1.3版本的开发过程中,得到了很多朋友的关注和支持,特别是一些分词方面的专家提出了很多很好的意见,也对我的分词算法给出了很多中肯的建议,在此向他们表示由衷的感谢。1.3版本的预分词算法还是沿用了之前版本的变相的最大匹配算法,这个算法有着本质的缺陷,未来的2.0版本可能会使用目前比较先进的算法替代这个过时的算法。 1.3版本在预分词中增加了对英文专业词汇的支持,比如C++,C#原来无法被分出来,现在只要在词库中有就可以分出来。在预分词中1.3版本还增加了对词频的判断。在预分词后,1.3版本对中文姓名匹配,未登录词识别等进行了一些改进。另外1.3版本还增加了对lucene.net的支持以及字典管理功能。之前很多朋友建议将ArrayList全部改成了List<>,非常好的建议,1.3版本将原来代码中所有的ArrayList全部改成了List<>.
    从今天开始,我打算逐步公布新版本中的一些主要算法,供朋友们参考,由于我水平有限,很多算法难尽如人意,有不对的地方还望指正。
    本片博客主要讨论分词粒度的问题
    中文分词主要应用于搜索引擎中,在搜索引擎建立索引时,如果分词粒度过大,将导致只有输入特定关键词才能搜索到相应结果。如果过小,则影响搜索的准确性。举一个简单的例子。"中央饭店"这个词,如果我们直接分词为"中央饭店",则我们必须输入"中央饭店"这个词才能搜索到相关的文章。如果仅输入"中央" 或者 "饭店",则得不到对于结果。而在实际应用中,我们往往希望用户输入中央或者饭店来找到中央饭店。但如果分词力度过小,如分成 中央/饭/店 注意饭和店单独也是词。那么当我们输入鞋店的时候(分词为鞋/店)也能搜索到中央饭店。这也是我们不希望的结果。所以最好的分词方案应该是中央/饭店。但针对单个词组,我们可以这样分词,如果词组本身不确定,我们又如何来确定具体的分词颗粒度呢?网友 雨中漫步的太阳 在一个多月前提议强行控制分词粒度,我理解就是强行设置一个粒度,比如2或者3,超过这个长度的数组就强行拆分。这也是一个可以接受的方案,但中文词一般长度在1到4之间,有些4字成语根本无法拆分。如果我们把粒度设置为4,则
上面我举例的那种情况无法完成拆分,当然我们还有一个办法,就是把字典中所有可以拆分的词组全部删除,这样做一来工作量太大,另外在某些情况下,删除的人也很难取舍。比如“杀身成仁” 到底要不要拆分为 “杀身”和“成仁"两个,我觉得也是仁者见仁,智者见智。所以考虑再三,觉得还是在1.3版本中采用根据词频决定分词粒度的方法。具体算法是,当发现一个由多个短词组成的长词时,判断每个短词中最小的词频,如果这个词频还是大于长词的词频,则按该组合进行拆分。如果多种组合,按词频最大的组合拆分。
如上面例子,"中央饭店",中央的词频为1000,饭店为900,饭为200,店为600,而中央饭店为500
有如下组合
中央饭店 最小词频了600
中央/饭店 最小词频了900
中央/饭/店 最小词频了200
选择最大词频组合,拆分为为中央/饭店.

KTDictSeg 分词组件1.3版本 新增功能列表及下载位置