在k处计算的平均精度(对于答案中的前 k 个元素),根据wiki,在 kaggle 的 ml 指标,以及这个答案:关于 (Mean) Average Precision 的混淆应该计算为 k 处的平均精度的平均值,其中平均值k 处的精度计算为:
其中: P(i) 是列表中截止 i 处的精度;rel(i) 是一个指示函数,如果排名 i 的项目是相关文档,则等于 1,否则为零。
分隔符min(k, number of relevant documents)
的含义是答案中相关条目的最大可能数量。
这种理解正确吗?
MAP@k 是否总是小于为所有排名列表计算的 MAP?
我担心的是,这不是 MAP@k 在许多作品中的计算方式。
通常,分隔符不是,而是top-kmin(k, number of relevant documents)
中相关文档的数量。这种方法将给出更高的 MAP@k 值。
HashNet:通过持续进行深度学习散列”(ICCV 2017)
代码: https ://github.com/thuml/HashNet/blob/master/pytorch/src/test.py#L42-L51
for i in range(query_num):
label = validation_labels[i, :]
label[label == 0] = -1
idx = ids[:, i]
imatch = np.sum(database_labels[idx[0:R], :] == label, axis=1) > 0
relevant_num = np.sum(imatch)
Lx = np.cumsum(imatch)
Px = Lx.astype(float) / np.arange(1, R+1, 1)
if relevant_num != 0:
APx.append(np.sum(Px * imatch) / relevant_num)
whererelevant_num
不是min(k, number of relevant documents)
,而是结果中相关文档的数量,与相关文档的总数或k不同。
我读错代码了吗?
代码:https ://github.com/caoyue10/cvpr17-dvsq/blob/master/util.py#L155-L178
def get_mAPs_by_feature(self, database, query):
ips = np.dot(query.output, database.output.T)
#norms = np.sqrt(np.dot(np.reshape(np.sum(query.output ** 2, 1), [query.n_samples, 1]), np.reshape(np.sum(database.output ** 2, 1), [1, database.n_samples])))
#self.all_rel = ips / norms
self.all_rel = ips
ids = np.argsort(-self.all_rel, 1)
APx = []
query_labels = query.label
database_labels = database.label
print "#calc mAPs# calculating mAPs"
bar = ProgressBar(total=self.all_rel.shape[0])
for i in xrange(self.all_rel.shape[0]):
label = query_labels[i, :]
label[label == 0] = -1
idx = ids[i, :]
imatch = np.sum(database_labels[idx[0: self.R], :] == label, 1) > 0
rel = np.sum(imatch)
Lx = np.cumsum(imatch)
Px = Lx.astype(float) / np.arange(1, self.R+1, 1)
if rel != 0:
APx.append(np.sum(Px * imatch) / rel)
bar.move()
print "mAPs: ", np.mean(np.array(APx))
return np.mean(np.array(APx))
其中 除数 是rel
,计算为np.sum(imatch)
, 其中imatch
是一个二进制向量,指示条目是否相关。问题是它只需要 first R
:imatch = np.sum(database_labels[idx[0: self.R], :] == label, 1) > 0
。所以np.sum(imatch)
会在返回的 size 列表中给出相关条目的数量R
,但不会min(R, number of relevant entries)
。请注意,R
论文中使用的值小于数据库中的条目数。
用于快速图像检索的二进制哈希码的深度学习 (CVPR 2015)
代码:https ://github.com/kevinlin311tw/caffe-cvprw15/blob/master/analysis/precision.m#L30-L55
buffer_yes = zeros(K,1);
buffer_total = zeros(K,1);
total_relevant = 0;
for j = 1:K
retrieval_label = trn_label(y2(j));
if (query_label==retrieval_label)
buffer_yes(j,1) = 1;
total_relevant = total_relevant + 1;
end
buffer_total(j,1) = 1;
end
% compute precision
P = cumsum(buffer_yes) ./ Ns';
if (sum(buffer_yes) == 0)
AP(i) = 0;
else
AP(i) = sum(P.*buffer_yes) / sum(buffer_yes);
end
这里的分隔符是sum(buffer_yes)
返回的大小为k的列表中的相关文档的数量的列表中的相关文档的数量,而不是min(k, number of relevant documents)
。
代码:https ://github.com/kevinlin311tw/Caffe-DeepBinaryCode/blob/master/analysis/precision.m
代码与上一篇论文中的相同。
使用无监督深度神经网络学习紧凑二进制描述符 (CVPR 2016)
相同的代码:https ://github.com/kevinlin311tw/cvpr16-deepbit/blob/master/analysis/precision.m#L32-L55
我错过了什么吗?上述论文中的代码是否正确?为什么它与https://github.com/benhamner/Metrics/blob/master/Python/ml_metrics/average_precision.py#L25-L39不一致?
更新
我发现了这个已关闭的问题,指的是同样的问题:https ://github.com/thuml/HashNet/issues/2
索赔以下索赔正确吗?
AP是一个排名指标。如果排名列表中的前 2 个检索是相关的(并且只有前 2 个),则 AP 为 100%。你说的是召回率,在这种情况下确实是 0.2%。
据我了解,如果我们将 AP 视为 PR 曲线下的面积,则上述说法是不正确的。
PS我怀疑这是否应该去Cross Validated或StackOverflow。如果您认为最好将其放置在交叉验证中,我不介意。我的理由是,这不是一个理论问题,而是参考实际代码的实现问题。