基于java的倒排索引
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
倒排索引
一、倒排索引
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)。
建立索引是聊天机器人的语料库搜索核心技术之一,目的是加快响应用户的输入。使用了搜索引擎技术中最常用的倒排索引技术,它是“单词”到“文档”的一个映射。由于问答系统中的查询都是输入一段自然语言文本进行搜索,经过中文分词都转化为一系列关键词。利用倒排索引,可以通过关键词找到包含它们的文档集合,然后将其中的每一个文档与查询进行相似度匹配,从而返回与用户查询最相关的答案。
现在我们先了解下倒排索引建立的大概流程图:
倒序索引流程示意图
由流程图可知道建立索引大概分为5大步:
1)文档的分析。首先为每一篇文档分配唯一的ID ,然后对文档进行分词(主要是去除停用词和抽取词干),接着把得到的每个新词存放到词典当中,如果词典中已经存在该词语,则更新相对应的数据信息。当一篇文档被分析完之后会产生一个临时文件,该临时文件时用来存放词语ID 、文档ID 和相对出现的位置等信息。
2)排序。将得到的临时文件按词语ID 进行排序,得到一个初步有序列表。
3)词语合并。一篇文档是有很多词语所组成的,而每一个汉字或词语都有许多 文档源 临时文件
词语 分配ID 、分词 加入 包括
词典 得到各子有序文档 合并各个文档 的词语集 按各文档 ID 排序 倒序索引列表 具有相同语义的词语集表 词语集合表 词语 语义 分类 排序
词语有序列表 词语ID 、文档ID 等 生成 排序
的近义词,就是词语意思一样,但表达的方式不一样。所以,这一步就是要把一篇文档中的近义词或同义词进行合并,得到一个词类的有序列表。
4)文档合并归类。由于整个知识库和语料库中不止一篇文档,而是由很多文档组成,所以要把这些文档中的相同词语的删除和同义词的进一步归类,从而形成一个总的有序类表的一个临时文件。
5)倒排文件。读取整个文档集的临时文件中各个词语的倒序类表,再根据需要采取必要的压缩算法,写入到倒排文件中从而得到了一个倒排序表。
二、代码结合解说
该代码是用java实现的,所以首先要调用的就是java的一个类方法java.util.*,为代码实现了List、get() 的接口和iterator()的返回调用集合的迭代器等功能。并且应用了哈希表进行信息的存储(在实现前运用到tree map 进一步将获得的信息进行排序,但由于选用了hash table ,所以就应用了hash map 但顺序却不一定能保证!)
程序哈希表的总结构图:
总表
分表ID 分表1属性
分表1 词语ID 位置次数.......
词语1
词语2
...............
分表2 .............. 分表2属性..........
该程序的结构图可知道,该程序分为两种哈希表,现有分表统计个文档词语的信息,然后在到总表中汇报,整理成一个倒排列表(也就是说表中表结构)
1.元素组成:
public Hashtable
建立一个总的哈希表h_invDoc,用来存放词语和问题之间的权重关系,已达到以文档依赖词语的关系。
public Hashtable
该为总表中的一个分表,用来存放类文档中的相近意义词语的有续集的一个序表termIdea:词语url:问题t imes:出现的次数ID::权重tf:文档篇数occur:文档中出现该词的次数
2.创建倒排索引并更新的函数方法详解
1.)InvDoc.java----------主要负责是分表的词语合并排序与更新
public boolean m_iInsertTerm(String termId, String url){
if(h_invDoc.containsKey(termId)){
if( ! isNewTerm(termId, url)){
................................ .................................
}else {
..............................................;
}
}else { ........................................
if(h_invDoc.get(termId).containsKey(url)) .............................
该方法主要是各分表的一个汇报以及合并以实现总表的倒排序表的创建与更新该过程分为2步:
1.)h_invDoc.containsKey(termId。把分割好的词语,并在哈希表中查找词语是否已经存在。如果已经存在的就提取其信息。反则,就在该总的哈希表中创建新一项,并把该词的信息更新记录在表中。再把该词与问题建立权重关系。
2.)isNewTerm。该函数主要是判断该词在问题中是否存在权重关系,也就是说该词在问题中的成分比重,如果是有一定的代表该问题的性质就返回一个False,然后if中就成true,并获得该词在哈希表中的信息(权重),并相对加1,更新记录列表。否则在该表中创建新的一项,赋予初值并赋予总表的更新信息。
2.)Dict.java-----------主要是负责总表的词语排序与更新
public int insertTerm(String termText, boolean isInNewDoc){
.............
if(h_dict.containsKey(termText)){ ......................................
if(isInNewDoc){
......................
}else{
...................... .....................................
}else {
.....................................
}
...................................
}
private boolean isInNewDoc(String termText, String url) {
// TODO Auto-generated method stub
......................
}
}
该方法主要是记录每一篇文档中各个词语的权重、出现的位置、出现的次数、频率等信息。该方法总体分为2步:(一下为每一步的具体功能以及实现)
1.)h_dict.containsKey(termText)。提取分表中的词语进行相对应的在总的哈希表中查找,看是否已经存在该词语,如果存在,则提取该词相对应信息;否则,就创新一张新的哈希表记录该词的信息,并把它加入到总的哈希表中进行更新。