【信息检索】【评价】 IR Evaluation

本文实验探索了评价查询好坏的MAP,MRR,IDCG三种方式,从原理到代码以及使用方式做介绍,如果对您有帮助,欢迎点赞 : )

实验过程

实验数据分析:

qrels.txt:(标准查询与文档以及相关性 对照文档)

image-20211110145233618

result.txt(本地查询方法结果):

image-20211110145400988

Mean Average Precision (MAP)

figure

对于寻返回一个排序的结果,其中有相关的(绿色),不相关(红色),Precision表示到当前rank之前的正确的所占的比例;

AP:平均精准率,将rank中正确的所对应Presion拿出来取平均值,得到这个query的AP;

MAP:对于所有query的ap求平均值,得到查询的平均精确度MAP;

def MAP_eval(qrels_dict,res_dict):
    APs=[]#每个query的AP
    for query in qrels_dict:#对于每个query
        true_ans=qrels_dict[query]#真实相关文档
        search_res=res_dict[query]#查询返回值
        accumulate_num=0#累计数量
        true_num=0#正确的个数
        per_rank=[]#一个query的返回中的Presions
        for doc in search_res:
            accumulate_num+=1
            if doc in true_ans:
                true_num+=1
                per_rank.append(float(true_num/accumulate_num))
        tsum=0#计算一个query的AP
        tcnt=0
        for per_r in per_rank:
            tsum+=per_r
            tcnt+=1
        APs.append(float(tsum/tcnt))
    tsum=0#计算MAP
    tcnt=0
    for ap in APs:
        tsum+=ap
        tcnt+=1
    ans=float(tsum/tcnt)
    return ans

Mean Reciprocal Rank (MRR):平均倒数排名

MRR概念

MRR得核心思想很简单:返回的结果集的优劣,跟第一个正确答案的位置有关,第一个正确答案越靠前,结果越好。具体来说:对于一个query,若第一个正确答案排在第n位,则MRR得分就是 1/n 。(如果没有正确答案,则得分为0)

figure

MRR计算例子

假设现在有5个query语句,q1、q2、q3、q4、q5

q1的正确结果在第4位,q2和q3没有正确结果(即未检索到文档),q4正确结果在第5位,q5正确结果在第10位。

那么系统的得分就是1/4+0+0+1/5+1/10=0.55

最后MRR就是求平均,即该系统MRR=0.55/5=0.11

def MRR_eval(qrels_dict,res_dict):
    mrrs=[]#所有query的rr
    for query in qrels_dict:
        true_docs=qrels_dict[query]#实际相关
        search_ans=res_dict[query]#查询返回结果
        acc_rank=0#累计rank
        for per_doc in search_ans:
            acc_rank+=1
            if per_doc in true_docs:#找到正确的后记录返回
                mrrs.append(float(1/acc_rank))
                break
    tsum=0.0#计算MRR
    tcnt=0
    for rr in mrrs:
        tsum+=rr
        tcnt+=1
    return float(tsum/tcnt)

Normalized Discounted Cumulative Gain (NDCG):(归一化折损累积增益)

Gain

表示每篇文档的重要性,对应0/1/2一个gain增益;也用rel表示;

CG:

累计增益,

figure

表示到当前排名的所有文档的增益;

DCG:

返回的顺序也会对查询结果有影响,上面没有考虑位置因素,增加一个折损考虑位置:

figure

NDCG:

查询结果容易受返回结果的长短的影响,返回的越长可能导致DCG越大,不同长度的query结果没有直接的比较意义,为了增加比较意义,更便于直接比较,引入归一化,按照全部的正确结果排在最前面且按照增益降序排列得到最优IDCG,然后将DCG/IDCG作为NDCG;

计算CG:

figure

计算DCG:

image-20211110144001549

计算IDCG:

在这里插入图片描述

得到的NDCG就可以在0–1之间;

其中公式:

image-20211110144013825

def NDCG_eval(qrels_dict_rel,res_dict):#这里需要rel数值
    ndcgs=[]
    # print(qrels_dict_rel)
    for per_query in qrels_dict_rel.keys():
        true_ranks=qrels_dict_rel[per_query]#真正的相关文档和rel值为 dic
        #len_true=len(true_ranks)#算DCG的终止位置
        # print(true_ranks)
        sorted_true_ranks=sorted(true_ranks,reverse=True)
        # print(true_ranks)

        IDCG=0.0
        i=2
        IDCG+=int(true_ranks[sorted_true_ranks[0]])#初始值是否和DCG相同
        for per_item in sorted_true_ranks[1:]:
            gain=true_ranks[per_item]
            IDCG+=int(gain)/float(math.log(i,2))
            i+=1
        DCG=0.0
        i=2
        search_res=res_dict[per_query]
        if search_res[0] in true_ranks:#先判断在相关文档中
            DCG+=int(true_ranks[search_res[0]])
        for per_res in search_res[1:]:#算法的位置?1:lentrue
            if per_res in true_ranks.keys():
                DCG+=int(true_ranks[per_res])/float(math.log(i,2))
            i+=1
        # print(DCG/IDCG)
        ndcgs.append(DCG/IDCG)
    # tnum=0.0
    tsum=0.0
    for ndcg in ndcgs:
        # tnum+=1
        tsum+=ndcg
    return float(tsum)/len(ndcgs) 

限定对前100返回结果进行评价:

def evaluate(k):#按照排名前100查询
    qrels_file="qrels.txt"
    res_file="result.txt"
    qrels_dict={}#所有的查询项正确结果
    qrels_dict_rel={}#查询项正确结果以及rel
    res_dict={}#自己查询实际返回结果
    with open(qrels_file,"r") as f:#将真确结果填充
        for line in f:
            evals=line.strip().split(" ")
            if evals[0] not in qrels_dict:
                qrels_dict[evals[0]]=[]
                qrels_dict_rel[evals[0]]={}
            if int(evals[3])>0:#只保留真正只有rel>0才是相关项存储,后面不用判断rel为正
                qrels_dict[evals[0]].append(evals[2])
                qrels_dict_rel[evals[0]][evals[2]]=evals[3]
                
    # print(qrels_dict)
    with open(res_file,"r") as f:#将查询返回结果保存为{qiery:[d1,d2,...],q2:[d1,d2,...]}
        for line in f:
            item=line.strip().split(' ')
            if item[0] not in res_dict:
                res_dict[item[0]]=[]
            res_dict[item[0]].append(item[1])
    for key in res_dict.keys():
        res_dict[key]=res_dict[key][:k]
        # print("key:",key,"len_ans:",len(res_dict[key]))
    # print(res_dict,"----------")
    map_eval=MAP_eval(qrels_dict,res_dict)
    mrr_eval=MRR_eval(qrels_dict,res_dict)
    ndcg_eval=NDCG_eval(qrels_dict_rel,res_dict)
    print("map_eval:",map_eval,"\nmrr_eval:",mrr_eval,"\nndcg_eval:",ndcg_eval)

实验结果

image-20211110145504711

上述没有限定在返回的前多少个中做评价,限定了在返回结果的前100中的结果:

image-20211124170804726

实验总结

了解了几种评价查询系统优劣的方法,对于其中评判标准的不同有了进一步的认识;

其中结果MAP与NDCG结果相近,进一步探究两者:

MAP和NDCG这两种指标是位置敏感的评价指标,总体来说可以理解为:正确推荐的item在列表中越靠前,其贡献的推荐效果越大,反之,正确推荐的item在列表中越靠后,贡献的推荐效果越小。MAP和NDCG主要的区别在于,MAP考虑的时二元相关性(1和0),NDCG可以有多种相关性的比较,相关性可以按照程度有多种取值,类似于分类与回归的关系。

说明结果返回的rank trival效果较好;

MRR只关注返回结果的第一个项目;

评价

这三者都是有排序意义的度量指标;

MRR的优点
  • 该方法计算简单,解释简单。
  • 这种方法高度关注列表的第一个相关元素。它最适合有针对性的搜索,比如用户询问“对我来说最好的东西”。
  • 适用于已知项目搜索,如导航查询或寻找事实。
MRR的缺点
  • MRR指标不评估推荐项目列表的其余部分。它只关注列表中的第一个项目。
  • 它给出一个只有一个相关物品的列表。如果这是评估的目标,那找个度量指标是可以的。
  • 对于想要浏览相关物品列表的用户来说,这可能不是一个好的评估指标。用户的目标可能是比较多个相关物品。
MAP优点
  • 给出了一个代表精确度 — 召回率曲线下复杂区域的单一度量。这提供了每个列表的平均精度。
  • 处理列表推荐物品的自然排序。这与将检索项视为集合的度量标准形成了对比。
  • 这一指标能够给予发生在排序高的推荐名单中的错误更多的权重。相反,它对发生在推荐列表中较深位置的错误的权重较小。这符合在推荐列表的最前面显示尽可能多的相关条目的需要。
MAP缺点
  • 这个度量标准适用于二进制(相关/非相关)评级。然而,它不适合细粒度的数字评级。此度量无法从此信息中提取误差度量。
  • 对于细粒度的评分,例如从1星到5星的评分,评估首先需要对评分进行阈值,以产生二元相关性。一种选择是只考虑大于4的评级。由于人工阈值的存在,这在评估度量中引入了偏差。此外,我们正在丢弃那些精细的信息。这个信息是在4星和5星之间的差异评级,以及在不相关的项目的信息。1星评级真的和3星评级一样吗?
NDCG优点
  • NDCG的主要优势是它考虑到了分等级的相关性值。当它们在数据集中可用时,NDCG是一个很好的选择。
  • 与MAP度量相比,它在评估排名项目的位置方面做得很好。它适用于二元的相关/非相关场景。
  • 平滑的对数折现因子有一个很好的理论基础,该工作的作者表明,对于每一对显著不同的排名推荐系统,NDCG度量始终能够确定更好的一个。
NDCG缺点
  • NDCG在部分反馈方面有一些问题。当我们有不完整的评级时,就会发生这种情况。这是大多数推荐系统的情况。如果我们有完整的评级,就没有真正的任务去实现!在这种情况下,recsys系统所有者需要决定如何归罪于缺失的评级。将缺少的值设置为0将把它们标记为不相关的项。其他计算值(如用户的平均/中值)也可以帮助解决这个缺点。
  • 接下来,用户需要手动处理IDCG等于0的情况。当用户没有相关文档时,就会发生这种情况。这里的一个策略是也将NDCG设置为0。
    推荐系统,NDCG度量始终能够确定更好的一个。
NDCG缺点
  • NDCG在部分反馈方面有一些问题。当我们有不完整的评级时,就会发生这种情况。这是大多数推荐系统的情况。如果我们有完整的评级,就没有真正的任务去实现!在这种情况下,recsys系统所有者需要决定如何归罪于缺失的评级。将缺少的值设置为0将把它们标记为不相关的项。其他计算值(如用户的平均/中值)也可以帮助解决这个缺点。
  • 接下来,用户需要手动处理IDCG等于0的情况。当用户没有相关文档时,就会发生这种情况。这里的一个策略是也将NDCG设置为0。
  • 另一个问题是处理NDCG@K。recsys系统返回的排序列表的大小可以小于k。为了处理这个问题,我们可以考虑固定大小的结果集,并用最小分数填充较小的集合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值