一种面向中文分词的搜索算法的制作方法

文档序号:15999360发布日期:2018-11-20 19:15阅读:225来源:国知局

本发明属于文本搜索引擎技术领域,具体涉及一种面向中文分词的搜索算法。



背景技术:

搜索引擎是一种在线信息搜索工具,将符合用户搜索关键字的一系列搜索结果返回给用户。当今社会是个信息爆炸的时代,面对着数不尽的信息,如何快速精确定位用户想要的信息是最迫切的需求之一,信息搜索技术也因此得到快速的发展和应用。

搜索最常见的形式是文本搜索,无论用户的目标资源是文字、图像、音频甚至是视频,只要输入的格式是文本,都可以归结到本发明搜索的范围内。现在除了谷歌、必应、雅虎等提供的全网站搜索功能外,特定领域的搜索需求也越来越大。在特定领域中(比如仅面向电视节目),由于资源的种类有局限性,所以搜索的条件一般能做到十分明确,另外数据集的大小也在可接受的范围内,在这些前提下可以对搜索引擎做出很多有针对性的优化。

目前中文搜索系统的相关技术主要有倒排索引、正排索引、署名文件、后缀树等。其中倒排索引综合性能较好且最常用,但在实际应用中,应用倒排索引模型处理大文本集合时,对CPU资源、内存空间和I/O都是十分严峻的考验。



技术实现要素:

本发明的目的在于提出一种面向中文分词的搜索算法,应用于智能化的中文搜索引擎系统,使之能够快速地根据关键字返回搜索结果,并将结果按匹配程度由高到低排序后展示给用户。

本发明提出的面向中文分词的搜索算法,主要可以分为两个阶段:离线构建索引阶段和在线查找阶段。在离线构建索引阶段,首先提取所有原始字符串集合的后缀串集合,然后由后缀串集合生成改进的后缀树;在在线查找阶段,首先根据基于后缀树的索引模型得到关键词的查询结果,然后量化关键词和查询结果的匹配程度,最后将查询结果按匹配程序由高到低排序后返回。

一、离线构建索引阶段,具体步骤为:

(1)由原数据集生成后缀串集合

T(S)表示带有分隔符($)和结束符(#)的字符串S所组成的原数据集,其中第i个字符串的索引ID为i(1≤i≤n)。假设WBS表示从分隔符处开始的后缀串,NWBS表示不从分隔符处开始的后缀串。由T(S)生成带索引ID的后缀串集合T(WBS)和T(NWBS)的具体步骤如下:

第一步:遍历T(S)中的所有字符串,提取每个字符串的所有后缀串si,构成集合T*(s1),T*(s2)…T*(sn)[1]。其中后缀串是指字符串S从位置i开始到S末尾结束符的一个子串,即若S用C1C2…Cn表示,则CiCi+1…Cn称为S的一个后缀串(1≤i≤n);

第二步:剔除T*(s1),T*(s2)…T*(sn)中所有以分隔符($)或结束符(#)为首的后缀串;

第三步:遍历T*(si)中所有后缀串,若后缀串的首字符跟原字符串的首字符相同,或者跟原字符串中分隔符($)后的首字符相同,则在该后缀串末尾添加索引ID后加入至T(WBS),反之,则在该后缀串末尾添加索引ID后加入至T(NWBS)。

(2)对后缀串集合T(WBS)和T(NWBS)分别建立改进后缀树

改进后缀树是在传统后缀树[1]的基础上,将每条边上的标识存放到节点中。即把每个节点作为一个存储单元,其结构如图1所示。节点存储信息包括节点标识、结束符子节点指针、分隔符子节点指针、一般子节点指针集和匹配索引ID序列,其中节点标识为结束符、分隔符或一般字符串。

对任意后缀串集合T建立改进后缀树的具体步骤如下:

第一步:创建一棵只包含一个节点的改进后缀树,该节点的节点标识、所有子节点指针和匹配索引ID序列均为空,把这个节点记为改进后缀树的根节点root。

第二步:把后缀串集合T中所有元素依次插入到改进后缀树中。每个后缀串的插入过程都是从根节点出发,寻找插入位置。

以图2中的改进后缀树为例子,在插入后缀串时分为以下三种情况:

情况①:如需要插入的后缀串在当前树中已经出现,则直接在节点的匹配索引ID序列中添加索引号即可。例如要插入的后缀串为“学生#2”,由于“学生”节点在当前树中已经出现,因此直接在节点的匹配索引ID序列中添加索引号即可,结果如图3(a)所示。

情况②:如需插入的后缀串的前缀与当前已有节点相同,则是需要直接添加节点即可。例如需要插入的后缀串为“复旦$学生#3”,由于“复旦”节点已经存在,所以直接添加节点“学生”和“#”即可,结果如图3(b)所示。

情况③:如需要插入的后缀串与当前节点中的前缀相同,则先分裂当前节点,然后再插入其他节点。例如需要插入的后缀串为“大$学生#4”,由于后缀串的前缀“大”与当前节点“大学”中的前缀相同,所以需要先分裂当前节点,然后再插入其他节点,结果如图3(c)所示。

第三步:递归构造每个节点的匹配索引ID序列。由前可知,结束符节点的匹配索引ID序列在全部后缀串插入完成时已经构造完成。因此,只需构造所有非结束符节点N(s)的匹配索引ID序列Q(N(s)),具体方法如公式(1)所示:

Q(N(s))=Q(N(s#))Q(N(s$))Q(N(s*))# (1)

其中,N(s#),N(s$)和N(s*)分别表示节点N(s)的结束符子节点,分隔符子节点和所有一般子节点。

二、在线查找阶段,具体步骤为:

(1)匹配点查询

对任意节点N(s),从N(s)出发,查询字符串c1…cn的匹配节点的过程如公式(2)所示:

其中,R(N(s))表示查询结果,N(s)为匹配节点,s为节点标识。

给出查询字符串c1…cn,首先查找根节点的所有子节点,找到节点标识的首字符等于c1的子节点N(s),然后执行R(N(s),c1…cn),找到所有匹配点,最终得到搜索结果R(N(s))=(S,Q(N(s)))。其中,Q(N(s))为N(s)的匹配索引ID序列。

(2)对结果集排序

定义负熵来衡量查询字符串c1…cn和搜索结果字符串s的匹配程度,熵值越小,匹配程度越低;反之,熵值越大,匹配程度越高。

假设负熵值的计算算法如下(初始熵值为0):

(a)获取从c1在s中的位置i;

(b)从i开始向后遍历s,直到遇到分隔符$或者终止符#或者s的结尾,假设期间遍历了m个字符;

(c)如果遇到的是s的结尾,判断最后一个字符是否为终止符#,如果是,则负熵值增加m2,算法结束;否则,负熵值增加m,算法结束;

(d)如果遇到的是分隔符$,负熵值增加m2,算法结束;

(e)将i更新为遇到的分隔符$之后一个字符的位置,回到(b)。

根据以上步骤计算结果集中所有s的分词负熵值,按其值由大到小对结果集进行排序。

(3)消除结果集中的重复项并生成搜索结果序列

依次取出排序后结果集的Q(N(s)),执行相应操作后放入搜索结果序列中,搜索结果序列初始值为空。公式(3)是对Q(N(si))执行的具体操作:

SR(i)=(D(Q(N(si)))-SR(i-1))∩SR(i-1),1≤i≤n# (3)

其中,SR(i)表示合并完第i个节点的匹配索引ID序列Q(N(si))后的搜索结果序列,SR(1)和SR(n)分别为搜索结果序列的初始状态和最终状态;D(Q(N(si)))表示对Q(N(si))执行去重操作;(D-SR)表示在去重后的Q(N(si))中去除已经在搜索结果序列中出现过的索引号;(D-SR)∩SR表示将(D-SR)添加至当前搜索结果序列SR的末尾。

经过上述步骤后,最终得到的搜索结果序列为SR(n)。

本发明通过一种改进的基于后缀树的索引结构来很好的平衡索引构建时间和占用空间,使用本发明的索引结构的搜索效率远高于对结果集暴力计算匹配度并排序的效率,且相比较于其他全文索引结构实现的模糊检索,本发明的索引结构采用更少的构建时间和占用内存代价的同时就能有很高的搜索效率。

附图说明

图1:改进后缀树节点的结构图。

图2:改进后缀树示例图。

图3:插入后缀串时不同情况对比图。

具体实施方式

为研究本发明在不同大小数据集上的搜索性能,我们分别构建了数据量为10000、20000、50000、100000和200000的五个数据集,并在各数据集上与基于倒排表的Lucene引擎进行多组对比实验。

随机生成长度为2-4不等的搜索字符串各25个,共同构成75种搜索字符串。对于每一种搜索字符串,都进行100000次搜索,在搜索结果正确的前提下,记录每次搜索的时间消耗。

为了让Lucene能够完成与本发明索引相同的任务,当建立首字母索引时在首字母序列的每个字符间加入空格,使每个字符被认为是一个单词,在搜索字符串的每个字符间也加入空格,用以实现本发明相同的搜索功能。

实验结果如表1所示:

表1本发明索引和Lucene索引搜索时间对比

由表可见,本发明算法在任何数据集上都有着比Lucene更好的搜索效率,并且结果在小数据集上更加明显,在数据集小于50000的情况下,使用本发明算法的搜索效率可以达到Lucene的7-10倍。

参考文选:

[1]E.Ukkonen,On-Line Construction of Suffix Trees,Algorithmica,14(1995),249-260。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1