我试图计算Average Precision上的Mean Average Precision(和Oxford Building image dataset)。
下面是他们为计算平均精度而提供的代码。请注意,pos_set
是"最佳"的并集。和#34;好"来自地面行为集的图像,而junk_set
是一组不相关的图像。
void OxfordTest::computeAp(std::vector<std::string> &ranked_list){
float old_recall = 0.0;
float old_precision = 1.0;
float ap = 0.0;
size_t intersect_size = 0;
size_t i = 0;
size_t j = 0;
for ( ; i<ranked_list.size(); ++i) {
if(!pos_set.count(ranked_list[i]))
std::cin.get();
}
if (junk_set.count(ranked_list[i])) continue;
if (pos_set.count(ranked_list[i])) intersect_size++;
float recall = intersect_size / (float)pos_set.size();
float precision = intersect_size / (j + 1.0);
ap += (recall - old_recall)*((old_precision + precision)/2.0);
old_recall = recall;
old_precision = precision;
j++;
}
}
这与链接的维基百科页面上给出的概念完全不同。 这些概念之间的相关性是什么?
我更确定维基百科的概念是正确的,因为它与此answer和this文章中给出的概念相符。
我不明白为什么在上面的代码中会报告:
答案 0 :(得分:3)
召回与平均精度无关,因为您有效地计算每个可能召回点的精度 。您可以在第一个维基百科定义中看到这一点,正如您自己注意到的那样。
在此处可以找到有关AP明确解释的良好概述: https://sanchom.wordpress.com/tag/average-precision/
我将首先假设此代码段正确计算AP,让我们看看它引导我们的位置。 (这不一定是真的,但考虑到有关论文自2007年以来被引用了1.8K次,大概是如果出现错误,有人会在现在就抓住它。)
每个对AP总和有贡献的元素由维基百科定义为:
P(k) * delta_ r(k)
其中 k 是检索到的文档序列中的排名, n 是检索到的文档的数量, P(k)是列表中的截止精度 k , delta_r(k)是项目 k-1 到的召回变化ķ
换句话说,这一行...
ap += (recall - old_recall)*((old_precision + precision)/2.0);
...可能是添加和元素的原因。
很明显delta_r(k)==(recall - old_recall)
,因此该部分已被覆盖。
现在,((old_precision + precision)/2.0)
呢?这也是你所关心的。
行。所以。这部分确实很奇怪。它不是使用 P(k)(截止k处的精度),而是显然平均 P(k)和 P(k-1)。我是由我的同事(我在国家认可的IR实验室工作)运行的,我们无法弄清楚为什么代码会这样做。我的预感是,这是作者选择做的某种形式的平滑,但我不明白为什么。另一种选择是总和以某种方式伸缩,并且这些物品相互抵消。这当然看起来很奇怪。
编辑:正如ReljaArandjelović在接受的答案中所解释的那样,这个“怪异”规则显然是使用trapeziodal rule代替rectangle rule来估算曲线下面积。在此处添加完整性。 &LT; \编辑&gt;
与此同时,您可以将此排名功能的结果与trec_eval进行交叉引用,看看是否得到相同的结果或不同的结果。
答案 1 :(得分:3)
原始论文指出:
(3) Junk – less than 25% of the object
is visible, or there is a very high level of occlusion or distortion.
(4) Absent – the object is not present
即。垃圾图片不是负片。有正面(OK +好),忽略(垃圾)和负面(缺席)。请注意,所有这些都是每个查询,即某些图片对于查询1而言是垃圾,但对于查询15则不是。如果您查看的是“垃圾”图像。你会看到含糊不清的例子,例如:有些情况会有极端的变焦或模糊,这会让你想到这个图像是否包含被查询的地标,以及只有一小部分物体可见的情况,因此图像太硬了。
In computing the average precision, we use the Good and
Ok images as positive examples of the landmark in question,
Absent images as negative examples and Junk images
as null examples. These null examples are treated as though
they are not present in the database – our score is unaffected
whether they are returned or not.
因此,作者将垃圾集定义为既不是正面也不是负面 - 图像最有可能描绘被查询的对象,但是对于其中一些我们不确定,或者将它们视为正面并且要求它们过于苛刻系统来检索这些例子(因此,如果它没有,则惩罚)。与此同时,将它们视为否定,如同系统确实检索它们一样也是苛刻的,它不应该受到惩罚。因此,所有需要做的就是(在每个查询的基础上)你忽略了垃圾并将它们视为不存在。因此,您获取检索到的列表,过滤掉此查询的所有垃圾图像,然后在此筛选列表上运行正常的AP计算。这就是代码有效的作用 - 当示例在amb(=垃圾)中时,它就被跳过了。然后,如果该示例不在amb中,如果它在pos(itives)中,则intersect_size(当前的正数直到位置i)递增。数量j(井,j-1)是列表中未跳过的元素的数量(仅当当前元素不是垃圾时才会递增)。
您在AP计算中肯定需要召回,正如shiri在前一个答案中所解释的那样,并且如您的文章中所述,p(r)是特定召回的精确度。考虑AP的最佳方法不是检查随机公式,而是要了解什么是直觉,然后看看公式如何捕获它,即维基百科在开始时说的内容:您可以将精确度绘制为召回的函数,以及AP那么就是曲线下的区域。您希望所有召回时的精度都很高,因此理想的曲线是p(r)= 1,这将使AP最大化。
那么代码在做什么?它使用梯形规则计算精确回忆曲线下的区域,请参阅this equation on Wikipedia,您将看到它与代码相同。维基百科文章中关于离散情况的AP计算是(常用的)精确回忆曲线下rectangle method区域的较差近似值。