AP是precision-recall曲线下的面积,并且precision-recall曲线应该是在整个返回的排序列表上计算的。
无法通过调整返回排名列表的大小来欺骗 AP。AP 是精确召回曲线下方的区域,它将精确度绘制为召回率的函数,其中召回率是返回的正数相对于地面实况中存在的正数的总数,而不是相对于真实数据中的正数的数量返回列表。因此,如果您裁剪列表,您所做的就是裁剪精确召回曲线并忽略绘制它的尾部。由于 AP 是曲线下的区域,因此裁剪列表会减少 AP,因此调整排名列表大小是没有智慧的 - 如果返回整个列表,则可以实现最大 AP。例如,您可以从您在其他问题中引用的代码中看到这一点- 裁剪列表仅对应于
for ( ; i<ranked_list.size(); ++i) {
更改为
for ( ; i<some_number; ++i) {
这导致更少的增量ap
(所有增量都是非负的,old_precision
并且precision
是非负的并且recall
是非减少的),因此更小的 AP 值。
实际上,出于纯粹的计算原因,您可能希望将列表裁剪为某个合理的数字,例如 10k,因为 AP 不太可能发生太大变化,因为 precision@large_number 可能为 0,除非您有异常大量的正数.
您的困惑可能与某些流行函数的方式有关,例如 VLFeatvl_pr
计算精确召回曲线,因为他们假设您已经为他们提供了整个排名列表,因此只需查看即可计算基本事实中的阳性总数排名列表而不是基本事实本身。因此,如果您vl_pr
在裁剪列表上天真地使用它,您确实可以欺骗它,但那将是无效的计算。我同意从函数的描述中不是 100% 清楚,但是如果您更详细地检查文档,您会看到它提到NUMNEGATIVES
和NUMPOSITIVES
,所以如果你给出一个不完整的排名列表,你应该设置这两个量,让函数知道如何正确计算精确召回曲线/AP。现在,如果您使用vl_pr
但对所有函数调用使用相同的 NUMNEGATIVES 和 NUMPOSITIVES 绘制排序列表的不同作物,您会看到精确召回曲线只是彼此的作物,正如我在上面解释的那样(我没有检查了这个,因为我这里没有 matlab,但我确定是这样,如果不是,我们应该提交一个错误)。