IR中python 寫倒排索引與查詢處理
阿新 • • 發佈:2018-12-22
學習資訊檢索課程,老師讓寫一個倒排索引與查詢處理的程式,於是抱著試試的心態自學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=0 direct=0 print id(mydir)
建立索引:
#-*-coding:utf-8-*- #!/usr/bin/python from mydate import * import sys import os import pprint import pickle def getmydoc(thepath,onedir): ans=[] for line in open(thepath+'/'+onedir): line=line.strip('\n') ans.append(line) return ans def createindex(thepath): global mydir global mywords global myindex global mywordsdictindex global antimywordsdict global mywordsdict global wordcnt global doccnt global listcnt global mypos global mydocs global myfindindex global mydoc global direct mydir=os.listdir(thepath) for i in mydir: if(os.path.isdir(thepath+'/'+i)==True): mydir.remove(i) #print mydir mydir=['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]=myword mywordsdict[myword]=wordcnt wordcnt+=1 #print myword,mywordsdict[myword] if(myword not in docworddict): docworddict[myword]=listcnt listcnt+=1 myindex.append([0]*3) ins=docworddict[myword] myindex[ins][0]=doccnt myindex[ins][1]=mywordsdict[myword] myindex[ins][2]+=1 myindex[ins].append(onedocword) onedocword+=1 doccnt+=1 myindex.sort(key=lambda x:x[1]) #sort beg=0 fin=0 for i in range(len(mywords)): mywordsdictindex[mywords[i][0]]=beg mywords[i][1]=beg while fin <len(myindex) and myindex[fin][1]==i:#python不支援邏輯短路 fin+=1 beg=fin for 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 sys import os import pprint import pickle import pdb from 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 mydir global mywords global myindex global mywordsdictindex global antimywordsdict global mywordsdict global wordcnt global doccnt global listcnt global mypos global mydocs global myfindindex global mydoc global direct if(loc==len(mypos)): #pdb.set_trace() direct=1############################# if(flag==1): mydocs.append(mydoc) i=mypos[loc-1]+1 #print mydocs if(i<antimywordsdict[myfindindex[loc-1]]): mydoc=myindex[i][0] else: return -1 return 1 i=mypos[loc] while i<antimywordsdict[myfindindex[loc]]: if(flag==-1): return -1 if(loc==0 and direct==1): direct=0 if( flag==1 and loc==0): mydocs.append(mydoc)############################# i+=1 #print mydocs if(i<antimywordsdict[myfindindex[loc]]): mydoc=myindex[i][0] else: return 0 T=0 while i<antimywordsdict[myfindindex[loc]] and myindex[i][0]<=mydoc: if(myindex[i][0]==mydoc): T=1 break i+=1 if(T==0): if(i+1==antimywordsdict[myfindindex[loc]]): return -1 i+=1 mydoc=myindex[i][0] mypos[loc]=i############################# if(flag==1 and T==1): pass else: T=0 if(direct==1): return T flag=findword(loc+1,T) return 0 def getwords(): global mydir global mywords global myindex global mywordsdictindex global antimywordsdict global mywordsdict global wordcnt global doccnt global listcnt global mypos global mydocs global myfindindex global mydoc global direct searchword=raw_input("find words\n") searchword=searchword.split(' ') flag=True for i in range(len(searchword)): if(searchword[i] not in mywordsdict): flag=False break myfindindex.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=0 import pdb #pdb.set_trace() flag=findword(0,0) print mydocs#mydocs 查詢到的文件號 返回這個資料
使用:
#-*-coding:utf-8-*-
#!/usr/bin/python
import hwf
from mydate import *
import createindex
import sys
import os
import pprint
import pickle
createindex.createindex('.')#建立索引
hwf.getwords()#查詢單詞