全文检索

来源:互联网 发布:引流软件一般多少钱 编辑:程序博客网 时间:2024/04/26 19:47

经历了很久的构思 有了一个感觉可以的全文检索方法

下面是我的构想 请大家交流指正 谢谢

 

 

()全文检索分析



全文检索 不用说就是对文本及其内容的一种查找方式 分为两种 一种基于字来建立索引 一种是基于词汇建立索引他们各有千秋

 

对字建立索引 在准确度和覆盖度方面都是非常理想的 但是索引文件比较大 速度比较慢

对词建立索引 在效率速度和索引文件大小方面比较理想 但是准确度和覆盖度又有缺失

 

到底如何能兼顾呢 可能我的方法前人会有人想过 不过我未曾见到类似资料 如有雷同纯属巧合

 

 

()索引结构

 

下面以 化妆和服装 为例子

建立索引方式:

 

索引结构

这个是基本的索引方式 最左边是字库 其次是词库 pos代表所对应文档 frq是出现频率 idx表示在文档中的位置

 

方式是 ->字词库->pos->frq->idx

首先是 字库 对 字词库 建立索引文件 这个是之前就做好的

然后 用中文分词算法分割 然后对每个词建立索引

对与未分出来的字就对字建立索引

这样整个索引建立完毕后就可以进行检索了

 

例子:

下 面举个例子 比如 化妆和服装 把这个进行分词 我用的是正向最大匹配方法的改进算法 这个稍后讲会分出来 化妆//服装/和服/装 这种分词算法会把每个可能的词都分出来 比如 中华人民共和国 会分成 中华/人民/共和国/中华人民共和国 具体的分的颗粒度根据词库相关 比如某些词库可能有中华人民某些没有

 

这样分词之后就可以对词 和 未分出的单字做索引 当然 这里可以优化一下 比如 和服 和这个字在和服中出现 就不用对这个字再次建立索引 当然 上图画的时候没有考虑这个

 

特点分析:

1.准确度和覆盖率

这样在索引的时候 对要查询字串分词 如果是词就在字词库中查找 如果是单字就找对应的字典对字词库的映射就能达到查全 用这种方法建立索引应该是在覆盖度和准确度和对字建立索引不相上下

 

2.而效率问题

由于在检索之前已经把字库和字词库读入内存中的HASH表查询是很高效的

在效率上略逊于只针对分词的索引建立方式 但是多了一点开销 但是换来的准确率和覆盖率是值得的如果你查询不到用户的需求 就算在好的效率也是徒劳 这算是一种折中的方案

 

3.索引文件大小

由于在分词过程中 大多数都会被分成词 只有小部分是为识别的单字

举个例子 我用的词库最大字是8个 如果光对字建立索引每次要记录8个字出现的坐标

而对于这种索引结构 是1-8次 由于中文文本几乎分出来都是词所以建立的索引会小很多



4.歧义的解决

而且就算对于真歧义也可以解决 比如 乒乓球拍卖完了 这个连人都分不清到底是什么意思的句子 经过分词乒乓球/拍卖/完了/乒乓/球拍/卖完/了 也能全部检索出来避免了中文分词建立索引的歧义问题

 

5.人名问题

检索对于人名的也很高 这种索引方式 虽然不能识别人名 但是 对于人名的每个字都有索引 所以检索人名是绝对没有问题的



6.包含词的解决

比如 风风雨雨 一般分词会当成一个词 这样查风雨的时候会产生 漏检的效果

但是针对于我这种改进的分词方式不会 会分出来 风风雨雨/风雨这样查风雨也会查的到

 



()中文分词算法

 

对于中文分词 大家比较熟悉的大概有 正向最大匹配 逆向最大匹配 双向匹配 如果有好的词库可以实现双向词性词频的分析但是针对中文这种语言的特点 分词算法并不能解决比如真歧义这种问题 比如 乒乓球拍卖完了 这种连人都分不出来的 还有一些普通的歧义 比如 日本和服务

到底是和服还是服务 计算机不好区别 虽然加上一些算法会提高准确率 如根据词频判断 但是开销会很大

 

我改进的分词算法

所谓正向最大匹配 就是要从最大匹配 而我这种更类似于最小匹配故 先叫 正向最小全匹配

就是在正向最小匹配的基础上 要分到文件结束 或者 词库最长词的长度

 

举例吧 比较清楚 比如 中华人民共和国

 

分词步骤

1.中华                       (是一个词 建立索引)

2.中华人                    (不是)

3.中华人民                  (是一个词 建立索引)

4.中华人民共               (不是)

5.中华人民共和             (不是)

6.中华人民共和国          (是一个词 建立索引 文本结束 或者 到达词库词的最大长度)

 

这样 第一个字是一个词内的 所以跳到第三个字 再次分词

 

1.人民                        (是一个词 建立索引)

2.人民共                     (不是)

3.人民共和                   (不是)

4.人民共和国                (不是 文本结束 或者 到达词库词的最大长度)

 

这样重复以上步骤

 

1.共和                        (不是)

2.共和国                     (是一个词 建立索引 文本结束 或者 到达词库词的最大长度)

 

最后剩下国字 因为国在一个词中 而每个字对词都有映射 可以不用添加单对国字的映射

这 样 整个就分为 中华/中华人民/中华人民共和国/人民/共和国 这样在检索时候就能达到不漏检 还提高了效率 对于普通分词 只是单纯分成 中华人民共和国 这样查中国 人民 这些词都查不到对于单个字就更不用说了 由于有了 字->字词库映射 所以单字都查的到

 

特点分析:

1.效率

这种分词技术虽然效率上差了一点点 但是由于中文中80%以上的词都是两个字 其实和正向最大匹配效率相差不是很大 虽然分级索引的效率高于这个 不过对内存要求很高 资源占用太大

 

2.准确度和覆盖率

准确度和覆盖率有大幅度的提高 达到了对字建索引的检索效果覆盖率更不用说了 你查什么都能查的到

 

 

()相关度



由 于检索是对输入文本关键字关键词的一种检索取并集的方式所以在排序和取并集的算法上有待提高 目前的想法是以链表做存储 因为动态增加比较多 链表比较合适 如果同一文件含有不同的关键字 设置一个值 多一个加1 这样 可以简单的实现相关度的排序 具体的相关度算法很多 可以自己参考来计算

 

 

()待提升部分

 

在检索部分的排序和取并集可以进行优化 提高检索的效率 毕竟速度慢对于我这种要求效率的人是不可忍受的

 

 

()总结



我会用C++编写 由于具体代码还没有出来 还有毕业设计比较忙 不能为大家提供一些测试数据以上是小弟的一些浅见  大家一起做交流 目的就是为了中文的全文检索能做的更好 也希望会对大家有所帮助 起到抛砖引玉的作用

 

如大家有任何意见或者更好的方法请联系 york528@yeah.net