匹配文档样例
查询样例
匹配结果样例
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()