当前位置: 首页 > 工具软件 > k0s > 使用案例 >

搜索推荐评价指标Precision@k、Recall@k、F1@k、NDCG@k

柳高卓
2023-12-01

假设对于一个查询,真实相关的结果是{A,C,E, Q},搜索模型得到5个结果{A, B, C, D, E},则其中只有A,C,E是相关的,标记为{1, 0, 1, 0, 1},1表示相关,0表示不相关。

Precision@k

即预测正确的相关结果占返回的所有结果的比例:
P r e c i s i o n @ k = T P @ k T P @ k + F P @ k Precision@k = \frac{TP@k}{TP@k+FP@k} Precision@k=TP@k+FP@kTP@k
取值范围[0,1],越大越好。

例子:
Precision@3 = 2/3 = 0.67
Precision@4 = 2/4 = 0.50
Precision@5 = 3/5 = 0.60

Recall@k

即预测正确的相关结果占所有相关结果的比例:
R e c a l l @ k = T P @ k T P @ k + F N @ k Recall@k = \frac{TP@k}{TP@k+FN@k} Recall@k=TP@k+FN@kTP@k
取值范围[0,1],越大越好。

例子:
Recall@3 = 2/4 = 0.50
Recall@4 = 2/4 = 0.50
Recall@5 = 3/4 = 0.75

F1@k

即Precision@k和Recall@k的调和平均数:
F 1 @ k = 2 × P r e c i s i o n @ k × R e c a l l @ k P r e c i s i o n @ k + R e c a l l @ k F1@k = \frac{2 \times Precision@k \times Recall@k}{Precision@k+Recall@k} F1@k=Precision@k+Recall@k2×Precision@k×Recall@k
取值范围[0,1],越大越好。

例子:
F1@3 = (2 * 0.67 * 0.50)/(0.67 + 0.50) = 0.57
F1@4 = (2 * 0.50 * 0.50)/(0.50 + 0.50) = 0.50
F1@5 = (2 * 0.60 * 0.75)/(0.60 + 0.75) = 0.67

注意:Precision@k、Recall@k、F1@k评价指标都是与返回顺序无关的。

NDCG@k

归一化折损累计增益(Normalized Discounted Cumulative Gain,NDCG),是一种考虑了返回顺序的评价指标。取值范围[0,1],越大效果越好。

N D C G @ k = D C G @ k I D C G @ k NDCG@k = \frac{DCG@k}{IDCG@k} NDCG@k=IDCG@kDCG@k
其中,
D C G @ k = ∑ i = 1 k r e l i l o g 2 ( i + 1 ) DCG@k=\sum_{i=1}^{k}\frac{rel_{i}}{log_{2}(i+1) } DCG@k=i=1klog2(i+1)reli
r e l i rel_i reli指第 i i i个结果的真实相关性分数。
I D C G @ k = ∑ i = 1 ∣ R E L ∣ r e l i l o g 2 ( i + 1 ) IDCG@k=\sum_{i=1}^{|REL|}\frac{rel_{i}}{log_{2}(i+1) } IDCG@k=i=1RELlog2(i+1)reli
IDCG也就是理想的DCG(Ideal DCG)。|REL| 表示,结果按照真实相关性从大到小排序,取前k个结果组成的集合的个数。

举个例子:

假设对于一个查询,搜索模型得到8个结果{A, B, C, D, E, F, G, H},分数是{0.94, 0.93, 0.92, 0.91, 0.8, 0.7, 0.6, 0.5},其真实相关性分数是{3, 2, 3, 0, 1, 2, 3, 0},求NDCG@6。

首先求DCG@6:

Item r e l i rel_i reli r e l i l o g 2 ( i + 1 ) \frac{rel_{i}}{log_{2}(i+1)} log2(i+1)reli
A33
B21.26185950
C31.5
D00
E10.38685280
F20.71241437

N D C G @ 6 = 3 + 1.26185950 + 1.5 + 0 + 0.38685280 + 0.71241437 = 6.86112667 NDCG@6=3+1.26185950+1.5+0+0.38685280+0.71241437=6.86112667 NDCG@6=3+1.26185950+1.5+0+0.38685280+0.71241437=6.86112667

再求IDCG@6:

对真实相关性分数排序,得到{3, 3, 3, 2, 2, 1, 0, 0}

r e l i rel_i reli r e l i l o g 2 ( i + 1 ) \frac{rel_{i}}{log_{2}(i+1)} log2(i+1)reli
33
31.89278926
31.5
20.86135311
20.77370561
10.35620718

I D C G @ 6 = 3 + 1.89278926 + 1.5 + 0.86135311 + 0.77370561 + 0.35620718 = 8.38405516 IDCG@6=3+1.89278926+1.5+0.86135311+0.77370561+0.35620718=8.38405516 IDCG@6=3+1.89278926+1.5+0.86135311+0.77370561+0.35620718=8.38405516

最终, N D C G @ 6 = 6.86112667 / 8.38405516 = 0.81835419 NDCG@6=6.86112667/8.38405516=0.81835419 NDCG@6=6.86112667/8.38405516=0.81835419,约82%。

注意点:
1、分母 l o g 2 ( i + 1 ) log_2{(i+1)} log2(i+1)相当于对返回位置进行了惩罚,越往后惩罚越大。分母 I D C G @ k IDCG@k IDCG@k是为了将分数归一化到[0,1]之间。
2、模型分数{0.94, 0.93, 0.92, 0.91, 0.8, 0.7, 0.6, 0.5}的大小不会影响最终NDCG的值,比如改为{100, 90, 80, 70, 60, 50, 40, 30},最终NDCG分数是一样的,只要保证是从大到小排序就行,因为在实际中,一般也是按照模型分数从大到小的顺序返回结果。

代码:

import numpy as np
from sklearn import metrics

# NDCG
true_relevance = np.array([[3, 2, 3, 0, 1, 2, 3, 0]])
scores = np.array([[0.94, 0.93, 0.92, 0.91, 0.8, 0.7, 0.6, 0.5]])

print(metrics.ndcg_score(true_relevance, scores, k=6)) # 0.8183541904922857

参考文章:
[1] 搜索评价指标——NDCG
[2] 信息检索中的度量指标全解析

 类似资料: