信息检索系统——VSM算法实现

    技术2026-06-05  11

    匹配文档样例

    查询样例

    匹配结果样例

    python–源码如下

    import math from tqdm import tqdm df_dict={} global docs_num #一个全局变量,保留全部文档数 docs_num=0 def doc_pl(doc): #求出文档中的词频数,及总词数,用于tf-idf的计算 word_list=doc.split() num=0 word_pl={} for word in word_list[1:]: word_pl[word]=word_pl.get(word,0)+1 num+=1 for word in word_pl.keys(): df_dict[word]=df_dict.get(word,0)+1 return (word_pl,num) def tf_idf(doc,flag): #求tf-idf的值 global docs_num word_tfidf={} for word in doc[0].keys(): tf=doc[0][word]/doc[1] #tf---某词在文章出现的次数/总词数 if flag==1: idf = math.log((docs_num / (df_dict[word]+1))) #idf---log(文档总数/包含该词文档数+1) #idf=(docs_num/df_dict[word])**2 #idf=(1/df_dict[word])**1.8 else: #对于一个问询的的tf-idf情形 idf=1 word_tfidf[word]=tf*idf return word_tfidf def simolarity(doc1,doc2): #求文档相似度 zi=0 mu1=0 mu2=0 for word in doc1.keys(): if doc2.get(word,0)!=0: zi+=doc1[word]*doc2[word] for word in doc1.values(): mu1+=word**2 for word in doc2.values(): mu2+=word**2 return zi/((mu2**0.5)*(mu1**0.5)) def vsm(dlist,que): #利用夹角余弦(Cosine)计算距离 global docs_num docs_num=0 #查询前清零总文档书 doc_pl_list=[] #各个文档的词频,及此文档总词数 tfidf_list=[] #各个文档中词的tf-idf字典 sim_list=[] #各文档与查询的相似度 for doc in dlist: doc.strip() doc_pl_list.append(doc_pl(doc)) #对于list的每一个元素为一个元组,元组中第0号元素为包含文档中词频率的字典,第二个元素为该文档的总词数 docs_num+=1 for pl in doc_pl_list: tfidf_list.append(tf_idf(pl,1)) #每一个文档中包含其所有词的tf-idf的字典构成的list docs_num=1 tfidf_que=tf_idf(doc_pl(que),0) #一个查询的所有词的tf-idf字典 for i in range(len(tfidf_list)): sim_list.append([simolarity(tfidf_que,tfidf_list[i]),dlist[i].split()[0]]) #各文档与查询的余弦相似度 return sorted(sim_list,key=lambda x:(-x[0])) #使各文档按余弦相似度由高到低排序 docs = open(r"C:\Users\CYY\Desktop\documents.txt",encoding='utf-8') doc_list = docs.readlines() docs.close() query = open(r"C:\Users\CYY\Desktop\q100.txt", encoding='utf-8') #问询的文档 query_list = query.readlines() query.close() Result = open(r"C:\Users\CYY\Desktop\result.txt", 'w',encoding='utf-8') #写入结果的文档 que_dict=dict() for i in tqdm(range(100)): #查询的数目 df_dict = {} result = vsm(doc_list, query_list[i]) Docs = [] Docs.append(query_list[i].split()[0]) k = 0 for doc in result: #去重 if doc[1] not in Docs: Docs.append(doc[1]) k += 1 if k == 10: #单次查询匹配的文档数 break que_dict[i] = Docs for i in range(100): #将一百个问询的前十个最匹配的文档写入 Result.write(que_dict[i][0]) Result.write("\t") for j in range(10): Result.write(que_dict[i][j+1]) Result.write(' ') Result.write('\n') Result.close()
    Processed: 0.012, SQL: 9