MAP
)MRR
)NDCG
)平均精确率
,再对所有查询的平均值取均值。最高排名的倒数的平均值
,再对所有查询的平均值取均值。相对于理想排序的增益值
,然后对这些相对增益值进行加权求和
,再除以理想排序的增益值
。qrels_dict
和test_dict
qrels_dict
,根据 qrel.txt 中的 query_id 和对应库中真正相关的 doc_id 的信息构建 qrels_dict={query_id:{doc_id:gain,doc_id:gain,……}}
。 遍历文件中的每一行,完成遍历后,返回 qrels_dict:
ele[0]
(query_id)是否已经在 qrels_dict 中。如果不在,将其作为新的查询ID键添加到 qrels_dict 中,并将其对应的值设置为空字典。ele[3]
(gain)是否大于0。如果是,将 ele[2]
(doc_id)作为新的相关文档ID键添加到查询ID键对应的值中,并将其对应的值设置为 ele[3] 的整数形式。def generate_tweetid_gain(file_name):
qrels_dict = {}
with open(file_name, 'r', errors='ignore') as f:
for line in f:
# 按空格划分
ele = line.strip().split(' ')
# ele[0]中存放的是query_id
if ele[0] not in qrels_dict:
qrels_dict[ele[0]] = {}
# ele[3]存放的是gain,ele[2]存放的是doc_id
# 将gain大于0的存入
if int(ele[3]) > 0:
qrels_dict[ele[0]][ele[2]] = int(ele[3])
return qrels_dict
test_dict
,根据 result.txt 文档中 query 和对应的检索到的 doc 文档对应信息构建 test_dict={query_id:{doc_id,doc_id,……}}
。遍历文件中的每一行,完成遍历后,返回 test_dict:
ele[0]
(query_id)是否已经在 test_dict 中。如果不在,将其作为新的查询ID键添加到 test_dict 中,并将其对应的值设置为一个空列表。ele[1]
(doc_id)添加到查询ID键对应的列表中。def read_tweetid_test(file_name):
# 输入格式为:query_id doc_id
test_dict = {}
with open(file_name, 'r', errors='ignore') as f:
for line in f:
# 按空格划分
ele = line.strip().split(' ')
# 这里的ele[0]是query_id,ele[1]是doc_id
if ele[0] not in test_dict:
test_dict[ele[0]] = []
test_dict[ele[0]].append(ele[1])
return test_dict
def MAP_eval(qrels_dict, test_dict, k = 100):
# MAP是对AP评价结果进行平均,AP基于P(Precision@K)评估
AP_result = []
for query in qrels_dict:
# 获取相关信息
test_result = test_dict[query] # 检索文档
true_list = set(qrels_dict[query].keys()) # 相关文档
use_length = min(k, len(test_result)) # 用不超过100条文档计算
if use_length <= 0:
print('query:', query, '未找到')
return []
# 声明变量
P_result = []
total = 0
the_true = 0
# P@K 评估
for doc_id in test_result[0: use_length]:
total += 1
if doc_id in true_list:
# 如果是相关的
the_true += 1
P_result.append(the_true / total)
# AP评估
if P_result:
AP = np.sum(P_result) / len(true_list)
# print('query:', query, '的AP评估结果:', AP)
AP_result.append(AP)
else:
print('query:', query, ' 就没有相关的┭┮﹏┭┮')
AP_result.append(0)
# MAP就是AP的平均值
return np.mean(AP_result)
def MRR_eval(qrels_dict, test_dict, k = 100):
# MRR是对RR评价结果进行平均,RR基于排序倒数
RR_result = []
for query in qrels_dict:
# 获取相关信息
test_result = test_dict[query] # 检索文档
true_list = set(qrels_dict[query].keys()) # 相关文档
use_length = min(k, len(test_result)) # 用不超过100条文档计算
if use_length <= 0:
print('query:', query, '未找到')
return []
# 声明变量
R_result = []
rank = 0
# 计算排序倒数
for doc_id in test_result[0: use_length]:
rank += 1
if doc_id in true_list:
R_result.append(1 / rank)
break
# RR评估
if R_result:
RR = np.sum(R_result)/1.0
# print('query:', query, '的RR评估结果:', RR)
RR_result.append(RR)
else:
print('query:', query, ' 就没有相关的┭┮﹏┭┮')
RR_result.append(0)
# MRR就是RR的平均值
return np.mean(RR_result)
def NDCG_eval(qrels_dict, test_dict, k = 100):
# NDCG@K = DCG@K / IDCG@K
# DCG = rel(1) + sum(rel(i)/log(i))
# IDCG就是按rel排序之后的DCG
NDCG_result = []
for query in qrels_dict:
# 获取相关信息
test_result = test_dict[query] # 检索文档
true_list = list(qrels_dict[query].values()) # 相关文档的gain列表
true_list = sorted(true_list, reverse=True) # 按gain(rel)倒序排列
use_length = min(k, len(test_result),len(true_list)) # 用不超过100条文档计算
if use_length <= 0:
print('query:', query, '未找到')
return []
# 声明变量
i = 1
DCG = 0.0
IDCG = 0.0
# 计算DCG和IDCG
rel1 = qrels_dict[query].get(test_result[0], 0)
DCG += rel1
for doc_id in test_result[1: use_length]:
i += 1
rel = qrels_dict[query].get(doc_id, 0)
DCG += rel / math.log(i, 2)
IDCG += true_list[i - 2] / math.log(i, 2)
NDCG = DCG / IDCG
# print('query:', query, '的NDCG评估结果:', NDCG)
NDCG_result.append(NDCG)
# 取平均值后返回
return np.mean(NDCG_result)
参考博客:信息检索实验3- IR Evaluation