分词的好坏关系到查询的准确程度和生成的索引的大小。在中文分词发展中,早期经常使用分词方式是二元分词法,该方法的基本原理 是将包含中文的句子进行二元分割,不考虑单词含义,只对二元单词进行索引。因此该方法所分出的单词数量较多,从而产生的索引数量巨大,查询中会将无用的数 据检索出来,好处是算法简单不会漏掉检索的数据。之后又发展出最大匹配分词方法,该方法又分为正向最大分词和逆向最大分词。其原理和查字典类似,对常用单 词生成一个词典,分析句子的过程中最大的匹配字典中的单词,从而将句子拆分为有意义的单词链。最大匹配法中正向分词方法对偏正式词语的分辨容易产生错误, 比如“首饰和服装”会将“和服”作为单词分出。达梦数据库采用的是改进的逆向最大分词方法,该分词方法较正向正确率有所提高。最为复杂的是通过统计方式进 行分词的方法。该方法采用隐式马尔科夫链,也就是后一个单词出现的概率依靠于前一个单词出现的概率,最后统计所有单词出现的概率的最大为分词的依据。这个 方法对新名词和地名的识别要远远高于最大匹配法,准确度随着取样文本的数量的增大而提高。
二元分词方法和统计方法是不依赖于词典的,而最大匹配法分词方法是依赖于词典的,词典的内容决定分词结构的好坏。
全文检索的索引被称为倒排索引,之所以成为倒排索引,是因为将每一个单词作为索引项,根据该索引项查找包含该单词的文本。因此,索引都是单词和唯一记录文本的标示是一对多的关系。将索引单词排序,根据排序后的单词定位包含该单词的文本。
逆向分词的过程说明
步骤1)读取一整条句子到变量str中,转到步骤2
步骤2)从句子的尾端读取1个字到变量word中,转到步骤3
步骤3)在字典查找word中保存的单词。如果存在则保存word,转到步骤4,否则转到步骤5)
步骤4)如果是字典中最大单词或者超过最大单词数(认定为新词),从句尾去掉该单词,返回步骤2
步骤5)读取前一个字到word中,构成新单词,转到步骤3)
词库的内存数据结构和词库中单词的匹配算法
内存中单词采用层次结构保存
假设字典中有如下的单词:中国 中华民国 国家 人民 民主
在内存中按照如下方式按层排列,其中每一个方块代表一个字,箭头所指向为该单词的前一个字。
单词按照如下方式匹配
比如查找单词“中华民国”
首先在第一层中使用二分法找到“国”字
获得“国”下层的数组“中民”
在该层使用二分法查找“民”,获得“民”下层的数组“华”
在该层使用二分法查找“华”,获得“华”下层的数组“中”
最后在该层找到中,至此,但此匹配完毕。
索引的格式
索引的格式是倒排索引的格式,也就是一个单词对应若干个文本表示。
在达梦数据库中,建立全文索引的对象是rec中的字段,生成倒排索引使用数据库中的b树进行存储。
在数据库是对某个字符字段进行全文索引,因此,rec的rowid作为该rec上该field的标示是必须要被记录的。
因此倒排索引存储的格式如下。
字段1 | 字段2 |
单词1 | Rowid1,rowid2… |
单词1 | Rowid1,rowid2… |
… | … |
由于b树的字段长度是有限的,因此b树存储的格式为
字段1 | 字段2 | 字段3 |
单词1 | 单词1Rowid的格数 | Rowid1,rowid2… |
单词1 | 单词2Rowid的格数 | Rowid1,rowid2… |
… | … | … |