信息检索与模式识别实验报告
姓名:宋赖招
学号:20181813
实验内容
实现MAP、MRR、NDCG评估查询出来的结果;
需要测试的查询出来的结果为result.txt文档里面,转化为字典形式存储在test_dict里面
每一个query_id的文档的初始相关Gain在qrels.txt文件里面,转化为字典形式存储在qrels_dict里面(这个字典是排除掉了所有不相关的文档)
实验步骤
MAP实现过程
- 对于每个query里面的document,记录这是遍历的第几个文档i,以及在此之前有多少个相关文档j,这样就可以计算出precision@i的值;
- 然后再将所有的 i*precision@i 的值相加,除以numberOfRelevant,这样就得到了AP(average precision)的值;
- 最后再计算所有query的平均值,即mean average precision(MAP)值
score=0
query_cnt=0#记录总的有几个查询
for query_id in test_dict.keys():
numberofRel=len(qrels_dict[query_id])
query_cnt+=1
i=0#记录的是查询到第几个
j=0#记录的是相关的第几个
p=0#计分
for doc_id in test_dict[query_id]:
i+=1
if i>k:
break
if doc_id in qrels_dict[query_id]:#这是对于这个查询来说相关的文档
j+=1
p=p+j/i
#j个相关文档数
score+=p/numberofRel
score=score/query_cnt#最后取平均值
MRR实现过程
- 对于每个query的每个document,记录第一个出现相关文档的位置i,那么这个query的RR值就是 1/i
- 然后对每个query求平均值,即RR相加,除以numberOfQuery
score=0#记录分数
query_cnt=0#记录总的有几个查询
for query_id in test_dict.keys():
query_cnt+=1
i=0#记录的是查询的第几个
for doc_id in test_dict[query_id]:
i+=1
if i>100:
break
if doc_id in qrels_dict[query_id]:#这是对于这个查询来说相关的文档
RR=1/i
break
score+=RR
score=score/query_cnt#最后取平均值
return score
NDCG实现过程
-
首先计算DCG,用gain字典存储
DCG的计算公式为:
#gain={query_id:{doc_id:gain, doc_id:gain, ...}, ...}
gain={}#存储DCG
for query_id in test_dict.keys():
i=0
gain[query_id]={}#对于每一个query_id都创建一个字典记录每个doc_id的DCG
DCG=0#记录cumulative gain的值
for doc_id in test_dict[query_id]:
i+=1
#每一个query_i都取前面100个doc_id
if i>k:
break
if doc_id in qrels_dict[query_id]:#这是对于这个查询来说相关的文档
if i==1:
DCG=qrels_dict[query_id][doc_id]
else:
DCG+=qrels_dict[query_id][doc_id]/math.log(i,2)
gain[query_id][doc_id]=DCG
-
然后对返回的文档进行排序,存储再ideal_test_dict字典里面
根据qrels_dict里面的分数来对doc_id进行排序,不在qrels_dict字典里面的分数就是0
ideal_test_dict={} for query_id in gain.keys(): ideal_test_dict[query_id]={} for doc_id in gain[query_id].keys(): if doc_id in qrels_dict[query_id].keys(): ideal_test_dict[query_id][doc_id]=qrels_dict[query_id][doc_id] else: ideal_test_dict[query_id][doc_id]=0 ideal_test_dict[query_id]=sorted(ideal_test_dict[query_id].items(),key=lambda x:x[1],reverse=True)
-
再根据ideal_test_dict字典计算IDCG,用I_gain字典存储
实现过程和第1步一样,只不过这里是根据ideal_test_dict的顺序进行累积计算
-
最后计算NDCG=DCG/IDCG
将对应的n的DCG值和IDCG值相除得到结果
for query_id in gain.keys(): z=0 i=0#存储文档次数 query_cnt+=1 for doc_id in gain[query_id]: i+=1 z=z+gain[query_id][doc_id]/I_gain[query_id][i] z=z/i score+=z score=score/query_cnt
实验结果
实验分析与体会
- 在MAP中,主要是体会precision@k这个值的计算,它是返回文档里面的第k个之前的相关文档数j,除以k;即j/k,这个计算是把没有返回的文档忽略掉了;但是最后求average的时候,除以的numberOfRevelant这个值是所有的文档的,即使有些相关文档没有返回;
- 在NDCG中,ideal字典是对返回的文档进行理想化排序,而不是对所有的文档进行排序;
- 在计算NDCG=DCG/IDCG的时候,是n对应的相除,而不是doc_id对应的相除。