向量空间模型实现文档查询(Vector Space Model to realize document query)
xml中文档(query)的结构:
<topic>
<number>CIRB010TopicZH006</number>
<title>科索沃難民潮</title>
<question>
查詢科索沃戰爭中的難民潮情況,以及國際間對其采取的援助。
</question>
<narrative>
相關文件內容包含科省難民湧入的地點、人數。受安置的狀況,難民潮引發的問題,参與救援之國家與國際組織,其援助策略與行動內容之報導。
</narrative>
<concepts>
科省、柯省、科索沃、柯索伏、難民、難民潮、難民營、援助、收容、救援、醫療、人道、避難、馬其頓、土耳其、外交部、國際、聯合國、紅十字會、阿爾巴尼亞裔難民。
</concepts>
</topic>
文档列表的样子(file-list)
CIRB010/cdn/loc/CDN_LOC_0001457
CIRB010/cdn/loc/CDN_LOC_0000294
CIRB010/cdn/loc/CDN_LOC_0000120
CIRB010/cdn/loc/CDN_LOC_0000661
CIRB010/cdn/loc/CDN_LOC_0001347
CIRB010/cdn/loc/CDN_LOC_0000439
词库的样子(vocab.all) 中文的话是单个字一行
utf8
Copper
version
EGCG
432Kbps
RESERVECHARDONNAY
TommyHolloway
platts
Celeron266MHz
VOLKSWAGEN
INDEX
SmarTone
倒排文档的表示(inverted-file)
词库中词的行号1 词库中词的行号2(-1表示单个词,仅仅考虑1)文档个数
文档在列表中的行数 词出现的次数
1 -1 2
33689 1
38365 1
2 -1 1
33256 1
2 12371 1
33256 1
3 -1 1
10849 2
3 6756 1
代码实现 仅仅是考虑单个的字
# -*- coding: utf-8 -*-
#!usr/bin/python import sys
import getopt
from xml.dom.minidom import parse
import xml.dom.minidom
import scipy.sparse as sp
from numpy import *
from math import log
from sklearn.preprocessing import normalize #deal with the argv
def main(argv):
ifFeedback=False
try:
opts,args=getopt.getopt(argv,'ri:o:m:d:',[])
except getopt.GetoptError:
# run input
print 'wrong input'
for opt,arg in opts:
if opt=='-r' and ifFeedback==False:
ifFeedback=True
elif opt=='-i':
queryFile=arg
elif opt=='-o':
rankedList=arg
elif opt=='-m':
modelDir=arg
elif opt=='-d':
NTCIRDir=arg
else:
pass
return ifFeedback,queryFile,rankedList,modelDir,NTCIRDir
#if __name__=='__main__' : #get the path in the arguments
ifFeedback,queryFile,rankedList,modelDir,NTCIRDir=main(sys.argv[1:])
#print ifFeedback,queryFile,rankedList,modelDir,NTCIRDir #get the file path in the model-dir
vocab=modelDir+'/vocab.all'
fileList=modelDir+'/file-list'
invList=modelDir+'/inverted-file' #read
pf=open(vocab,'r')
vocab=pf.read()
pf.close() pf=open(fileList,'r')
fileList=pf.read()
pf.close() pf=open(invList,'r')
invList=pf.read()
pf.close() #splitlines
vocab=vocab.splitlines();
fileList=fileList.splitlines()
invList=invList.splitlines() # vocab dict
vocabDict={}
k=0
while k <len(vocab):
vocabDict[vocab[k]]=k
k+=1 #get the TF and IDF matrix
#dimension:
#tfMatrix=sp.csr_matrix(len(fileList),len(vocab)) IDFVector=zeros(len(vocab))
totalDocs=len(fileList)
count=0
tempMatrix=zeros((len(fileList),len(vocab))) while count<len(invList):
postings=invList[count]
post=postings.split(' ')
k=1
#just deal with the single word
if(len(post)>2 and post[1]=='-1'):
IDFVector[int(post[0])]=int(post[2])
while k<=int(post[2]):
line=invList[count+k].split(' ')
tempMatrix[int(line[0])][int(post[0])]=int(line[1])
k+=1
count+=k tfMatrix=sp.csr_matrix(tempMatrix) #BM25
doclens=tfMatrix.sum(1)
avglen=doclens.mean()
k=7
b=0.7
#
tp1=tfMatrix*(k+1)
tp2=k*(1-b+b*doclens/avglen)
tfMatrix.data+=array(tp2[tfMatrix.tocoo().row]).reshape(len(tfMatrix.data))
tfMatrix.data=tp1.data/tfMatrix.data #calculate the idf
k=0
while k<len(vocab):
if IDFVector[k]!=0:
IDFVector[k]=log(float(totalDocs)/IDFVector[k])
k+=1
#tf-idf
tfMatrix.data*=IDFVector[tfMatrix.indices] #row normalization for tf-idf matrix
normalize(tfMatrix,norm='l2',axis=1,copy=False) #deal with the query
doc=xml.dom.minidom.parse(queryFile)
root=doc.documentElement
topics=root.getElementsByTagName('topic')
rankList=''
for topic in topics:
#query vector
qVector=zeros(len(vocab)) number=topic.getElementsByTagName('number')[0].childNodes[0].data
title=topic.getElementsByTagName('title')[0].childNodes[0].data question=topic.getElementsByTagName('question')[0].childNodes[0].data
narrative=topic.getElementsByTagName('narrative')[0].childNodes[0].data
concepts=topic.getElementsByTagName('concepts')[0].childNodes[0].data narrative+=question+concepts
for w in narrative:
if vocabDict.has_key(w.encode('utf8')):
qVector[vocabDict[w.encode('utf8')]]+=1
for w in title:
if vocabDict.has_key(w.encode('utf8')):
qVector[vocabDict[w.encode('utf8')]]+=1
#...normalization
normalize(qVector,norm='l2',axis=1,copy=False)
#similarity compute:
#a sparse matrix
sim=tfMatrix*(sp.csr_matrix(qVector).transpose()) sim=sim.toarray()
k=0
simCount=[]
while k<len(fileList):
tup=(sim[k],k)
simCount.append(tup)
k+=1 #sort
simCount.sort(reverse=True)
simCount=simCount[:100]
if ifFeedback:
topk=[]
for score,k in simCount[:20]:
topk.append(k)
d=tfMatrix[topk,:].sum(0)/20
qVector+=array(0.8*d).reshape(len(qVector))
#.....
normalize(qVector,norm='l2',axis=1,copy=False)
#similarity compute:
#a sparse matrix
sim=tfMatrix*(sp.csr_matrix(qVector).transpose()) sim=sim.toarray()
k=0
simCount=[]
while k<len(fileList):
tup=(sim[k],k)
simCount.append(tup)
k+=1 #sort
simCount.sort(reverse=True)
simCount=simCount[:100]
#..... num=number.split('ZH')
num=num[1]
for sim in simCount:
name=fileList[sim[1]]
name=name.split('/')
name=name[3].lower()
rank=num+' '+name
rankList+=rank+'\n' pf=open(rankedList,'w')
pf.write(rankList)
向量空间模型实现文档查询(Vector Space Model to realize document query)的更多相关文章
- 向量空间模型(Vector Space Model)的理解
1. 问题描述 给你若干篇文档,找出这些文档中最相似的两篇文档? 相似性,可以用距离来衡量.而在数学上,可使用余弦来计算两个向量的距离. \[cos(\vec a, \vec b)=\frac {\v ...
- Solr相似度名词:VSM(Vector Space Model)向量空间模型
最近想学习下Lucene ,以前运行的Demo就感觉很神奇,什么原理呢,尤其是查找相似度最高的.最优的结果.索性就直接跳到这个问题看,很多资料都提到了VSM(Vector Space Model)即向 ...
- 向量空间模型(Vector Space Model)
搜索结果排序是搜索引擎最核心的构成部分,很大程度上决定了搜索引擎的质量好坏.虽然搜索引擎在实际结果排序时考虑了上百个相关因子,但最重要的因素还是用户查询与网页内容的相关性.(ps:百度最臭名朝著的“竞 ...
- ES搜索排序,文档相关度评分介绍——Vector Space Model
Vector Space Model The vector space model provides a way of comparing a multiterm query against a do ...
- 转:Lucene之计算相似度模型VSM(Vector Space Model) : tf-idf与交叉熵关系,cos余弦相似度
原文:http://blog.csdn.net/zhangbinfly/article/details/7734118 最近想学习下Lucene ,以前运行的Demo就感觉很神奇,什么原理呢,尤其是查 ...
- Elasticsearch增删改查 之 —— mget多文档查询
之前说过了针对单一文档的增删改查,基本也算是达到了一个基本数据库的功能.本篇主要描述的是多文档的查询,通过这个查询语法,可以根据多个文档的查询条件,返回多个文档集合. 更多内容可以参考我整理的ELK文 ...
- ES 父子文档查询
父子文档的特点 1. 父/子文档是完全独立的. 2. 父文档更新不会影响子文档. 3. 子文档更新不会影响父文档或者其它子文档. 父子文档的映射与索引 1. 父子关系 type 的建立必须在索引新建或 ...
- css盒子模型、文档流、相对与绝对定位、浮动与清除模型
一.CSS中的盒子模型 标准模式和混杂模式(IE).在标准模式下浏览器按照规范呈现页面:在混杂模式下,页面以一种比较宽松的向后兼容的方式显示.混杂模式通常模拟老式浏览器的行为以防止老站点无法工作. h ...
- Elasticsearch文档查询
简单数据集 到目前为止,已经了解了基本知识,现在我们尝试用更逼真的数据集,这儿已经准备好了一份虚构的JSON,关于客户银行账户信息的.每个文档的结构如下: { , , "firstname& ...
随机推荐
- 快照、克隆,xshell优化,Linux历史
目录 一.虚拟拍照功能 二.虚拟机克隆功能 三.Xshell的优化 四.介绍Linux历史 一.虚拟拍照功能 1.拍摄快照 关机状态拍照 关机命令:shutdown -h now 或者 init 0 ...
- 三、harbor部署之SSL
1 签名证书与自签名证书 签名证书:由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西. 自签名证书:由服务器自己颁发给自己,用于证明自己身份的东西,非权威颁发机构发布. 2 openssl简介 ...
- appium+python自动化-adb shell模拟点击事件(input tap)
前言 appium有时候定位一个元素很难定位到,或者说明明定位到这个元素了,却无法点击,这个时候该怎么办呢? 求助大神是没用的,点击不了就是点击不了,appium不是万能的,这个时候应该转换思路,换其 ...
- Python第三方库之openpyxl(8)
Python第三方库之openpyxl(8) 饼图 饼图将数据绘制成一个圆片,每个片代表整体的百分比.切片是按顺时针方向绘制的,0在圆的顶部.饼图只能取一组数据.该图表的标题将默认为该系列的标题. 2 ...
- 【bzoj3489】A simple rmq problem 三维KD-tree
题目描述 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会 ...
- Luogu【P1901】发射站(单调栈)
题目链接 题目说明比自己矮的塔收不到自己的能量,摆明了就是单调栈呗. 把比自己矮的全都从栈里弹出去,于是碰到第一个比自己高的.让他接受自己发射的能量. 当然由于发射站发射的能量有两个方向,所以正反两遍 ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- Peaks BZOJ 3545 / Peaks加强版 BZOJ 3551
Peaks [问题描述] 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问 ...
- 湘潭大学oj 1206 Dormitory's Elevator dp
27153 njczy2010 1206 Accepted 1976 KB 234 MS G++ 1415 B 2014-09-28 10:01:23 真是吐血ac,,,,这么easy的题..... ...
- Python入门--5--列表
python没有数组 蛋是有列表 列表里面可以有:整数,浮点数,字符串,对象 没有数组,没有数组,没有数组,不重要的也说三遍!! 一.创建列表 x = ['abc','sas','www'] ...