IR中python 写倒排索引与查询处理

来源:互联网 发布:js给数组赋值 编辑:程序博客网 时间:2024/06/03 19:58

学习信息检索课程,老师让写一个倒排索引与查询处理的程序,于是抱着试试的心态自学python写了出来。

整个没有什么太大的算法技巧,唯一的就是查询处理那里递归函数正反两次反复查找需要多调试下。

数据结构:

#-*-coding:utf-8-*-#!/usr/bin/python'''数据结构建立索引mydir   文档列表onedoc  每一个文档mydoc   当前查询的文档mywords 建立索引的字典myindex 0 文档下标 1 单词下标 2 次数 3...wordcntdict中的个数 doccnt文档个数三个字典mywordsdictindex  单词编号 起始位置antimywordsdict   单词编号 结束位置mywordsdict       单词->单词编号查询mypos是每个的单词起始的index下标myfindindex是每个单词的标号,mydocs 查询到的文档号'''mydir=[]mywords=[]myindex=[]mywordsdictindex={}antimywordsdict={}mywordsdict={}wordcnt=0#dict中的个数doccnt=0#文档个数listcnt=0#index个数mypos=[]mydocs=[]myfindindex=[]mydoc=0direct=0print id(mydir)


创建索引:

#-*-coding:utf-8-*-#!/usr/bin/pythonfrom mydate import *import sysimport osimport pprintimport pickledef getmydoc(thepath,onedir):ans=[]for line in open(thepath+'/'+onedir):line=line.strip('\n')ans.append(line)return ansdef createindex(thepath):global mydirglobal mywordsglobal myindexglobal mywordsdictindexglobal antimywordsdictglobal mywordsdictglobal wordcntglobal doccntglobal listcntglobal myposglobal mydocsglobal myfindindexglobal mydocglobal directmydir=os.listdir(thepath)for i in mydir:if(os.path.isdir(thepath+'/'+i)==True):mydir.remove(i)#print mydirmydir=['a.txt','b.txt','c.txt']wordcnt=0#dict中的个数doccnt=0#文档个数listcnt=0#index个数print id(wordcnt)for onedoc in mydir:mylist=getmydoc(thepath,onedoc)onedocword=0#每个词在这个文本中的位置docworddict={}for myword in mylist:if(myword not in mywordsdict):mywords.append([0]*2)mywords[wordcnt][0]=mywordmywordsdict[myword]=wordcntwordcnt+=1#print myword,mywordsdict[myword]if(myword not in docworddict):docworddict[myword]=listcntlistcnt+=1myindex.append([0]*3)ins=docworddict[myword]myindex[ins][0]=doccntmyindex[ins][1]=mywordsdict[myword]myindex[ins][2]+=1myindex[ins].append(onedocword)onedocword+=1doccnt+=1myindex.sort(key=lambda x:x[1]) #sortbeg=0fin=0for i in range(len(mywords)):mywordsdictindex[mywords[i][0]]=begmywords[i][1]=begwhile fin <len(myindex) and myindex[fin][1]==i:#python不支持逻辑短路fin+=1beg=finfor i in range(len(mywords)):mywordsdictindex[i]=mywords[i][1]if(i==len(mywords)-1):antimywordsdict[i]=len(myindex)else:antimywordsdict[i]=mywords[i+1][1]'''pprint.pprint (mywords)pprint.pprint (myindex)pprint.pprint (mywordsdict)pprint.pprint (mywordsdictindex)pprint.pprint (antimywordsdict)out=open("myindex.dat","wb")pickle.dump(myindex,out)out=open("mywords.dat","wb")pickle.dump(mywords,out)'''

接收查询与查询处理:

#-*-coding:utf-8-*-#!/usr/bin/python#得到一个文本的列表import sysimport osimport pprintimport pickleimport pdbfrom mydate import *'''返回值三种:1 整个查询词都找到了 0 并没有同时出现在一个文本中 -1 查询完毕或不存在mydoc 查询词是否都在这个文档中direct 查询方向 direct=0 递归向下,携带标记flag若为1则表明之前一直存在。0表明并不都在一个文本中那么mydoc取过程中的最大值      当到len(mypos)的时候,决定是否将该结果放入,并将最后一个词的mypos后移 改变查询方向,并返回1      direct=1 递归返回,与0同样操作,当到第0层再改变查询方向'''def findword(loc,flag):global mydirglobal mywordsglobal myindexglobal mywordsdictindexglobal antimywordsdictglobal mywordsdictglobal wordcntglobal doccntglobal listcntglobal myposglobal mydocsglobal myfindindexglobal mydocglobal directif(loc==len(mypos)):#pdb.set_trace()direct=1#############################if(flag==1):mydocs.append(mydoc)i=mypos[loc-1]+1#print mydocsif(i<antimywordsdict[myfindindex[loc-1]]):mydoc=myindex[i][0]else:return -1return 1i=mypos[loc]while i<antimywordsdict[myfindindex[loc]]:if(flag==-1):return -1if(loc==0 and direct==1):direct=0if( flag==1 and loc==0):mydocs.append(mydoc)#############################i+=1#print mydocsif(i<antimywordsdict[myfindindex[loc]]):mydoc=myindex[i][0]else:return 0T=0while i<antimywordsdict[myfindindex[loc]] and myindex[i][0]<=mydoc:if(myindex[i][0]==mydoc):T=1breaki+=1if(T==0):if(i+1==antimywordsdict[myfindindex[loc]]):return -1i+=1mydoc=myindex[i][0]mypos[loc]=i#############################if(flag==1 and T==1):passelse:T=0if(direct==1):return Tflag=findword(loc+1,T)return 0def getwords():global mydirglobal mywordsglobal myindexglobal mywordsdictindexglobal antimywordsdictglobal mywordsdictglobal wordcntglobal doccntglobal listcntglobal myposglobal mydocsglobal myfindindexglobal mydocglobal directsearchword=raw_input("find words\n")searchword=searchword.split(' ')flag=Truefor i in range(len(searchword)):if(searchword[i] not in mywordsdict):flag=Falsebreakmyfindindex.append(mywordsdict[searchword[i]])#mypos是每个的单词起始的index下标,myfindindex是每个单词的标号,三个字典mypos.append(mywordsdictindex[searchword[i]])if(flag==False):print 'wrong'sys.exit()mydoc=myindex[mywordsdictindex[myfindindex[0]]][0]direct=0import pdb#pdb.set_trace()flag=findword(0,0)print mydocs#mydocs 查询到的文档号 返回这个数据

使用:

#-*-coding:utf-8-*-#!/usr/bin/pythonimport hwffrom mydate import *import createindeximport sysimport osimport pprintimport picklecreateindex.createindex('.')#创建索引hwf.getwords()#查询单词


0 0