游荡的灵魂
无根的灵魂,除了游荡,还能去那里?

    分词模块中主要是2大部分,首先是分词算法部分,然后就是词库部分。分词算法我们使用的是逆向最大匹配算法、语法效验、生词识别(基于上下文统计和语法效验)。这篇随笔主要说一下词库部分。
    分词效率很大程度取决词库的设计,词库设计必须实现最大限度的查找匹配词。词库设计主要是2大部分,词数据部分和索引部分。

    词数据部分:
    我们将词按照长度不同分为不同的词类型,从长到短排列。在同一类型中按照词首字UTF-8内码从小到大排列。首字相同的词按照词频排列。
    本文示例说明:{和|符号只是示例用,数据文件中不存在
    示例:
    {中华人们共和国|中华苏维埃政府}{数据文件|数据报表}
  
    索引部分:索引部分包含统计数据和词索引,词索引是针对词首字的索引。索引记录的是首字的UTF-8内码和词偏移量。
    总格式:系统版本号|拥有词量|拥有词类型量|各类型长度|各类型拥有词量|各类型拥有索引量|各类型词首字索引|索引开始地址|
    各类型长度:类型长度|类型长度 (最短是2个字)
    各类型拥有词量格式:拥有词量|...|拥有词量
    各类型拥有索引量格式:索引量|...|索引量
    各类型词首字索引格式:首字编码:第一个拥有该字偏移地址|n字编码:第1个拥有该字偏移地址} |...|长度类型n首字索引{首字编码:第一个拥有该字偏移地址|n字编码:第1个拥有该字偏移地址
   
   在首字索引中,第一个拥有该字偏移地址相对地址,也是就是说该地址是所属词类型中的排列位数,需要通过转换才能得到实际地址。

   使用类型说明:系统版本号是一个byte类型,词数量是int32类型,词类型长度数量是byte类型,n字词长度类型长度是byte类型,首字编码是3位byte 第一个拥有该字便宜地址是int32类型。

    在具体使用该词库时,我们需要将整个索引部分解析到内存,解析后提供一个索引类,索引类包含版本号,拥有词类型量,每种词类型长度,每种词类型拥有词量,索引量,并换算出每种词类型第一个词在数据文件中的实际可读取偏移地址和第一个索引的实际偏移地址。换算出没类型索引的首字最大和最小UTF-8内码。

    换算的办法是:感觉文件中记录的便宜量*数据类型所占用的位数。
   
    比如:
   前提条件:当前词库中拥有3个字长度和2个字长度的类型
   2字长度词类型第一个词实际便宜量=3个字类型词量*3(3个字)*3(每个字UTF-8占用空间)+2*3
   2字长度词类型第二个词实际便宜量=3个字类型词量*3(3个字)*3(每个字UTF-8占用空间)+2*3

  通过这样处理后只有在加载的时候因为要换算一部分数据,数据略有影响,而在后去查询的时候由于索引数据载入到内存,并且基数数据换算完成了。那么速度就非常快。

  同时在索引查询的时候可以通过比较最大和最小来加快索引,通过将索引不断的分为2部分,然后比较最大和最小,这样查找起来数据就非常快。查找索引数据后,可以直接将索引的偏移量转换成具体地址(类型首词实际地址+词偏移量*词类型长度*3),然后就可以逐步查找了。

  这个格式的有点是查询速度很快,词库数量越大速度比纯文本词库就越快。但是添加和删除就很麻烦了。

  有这方面经验的同志欢迎讨论哈。


  源代码需要在分词系统测试完成后放出,不好意思了。

 

 

 程序猿们,我也跟风开了网店,主要经营土特产,云南核桃,四川正宗土鸡蛋鸡蛋。有需要的就支持一下小店哈  七彩山川美食(http://qcsc.taobao.com) 

posted on 2006-12-30 17:23  游荡的灵魂  阅读(3817)  评论(8编辑  收藏  举报