如何解释:标签排名平均精度得分(Label Ranking Average Precision Score)

7

我刚接触数组编程,并发现很难解释 sklearn.metrics.label_ranking_average_precision_score 函数。需要您帮助理解它的计算方式,并欢迎任何学习Numpy数组编程的提示。

通常,我知道精度是
((真正例) / (真正例 + 假正例))

我问这个问题的原因是,我偶然发现了 Kaggle 音频标记竞赛,并看到这篇文章说当响应中有多个正确标签时,他们使用 LWRAP 函数来计算分数。我开始阅读,想知道如何计算此分数,但难以解释。我的两个困难是:
1)从文档中解释数学函数,我不确定排名如何用于得分计算
2)解释代码中的 Numpy 数组操作
我正在阅读的函数来自 Google Collab 文档,然后我尝试阅读 sklearn 的文档,但无法正确理解。

一个样本计算的代码如下:

# Core calculation of label precisions for one test sample.

def _one_sample_positive_class_precisions(scores, truth):
  """Calculate precisions for each true class for a single sample.

  Args:
    scores: np.array of (num_classes,) giving the individual classifier scores.
    truth: np.array of (num_classes,) bools indicating which classes are true.

  Returns:
    pos_class_indices: np.array of indices of the true classes for this sample.
    pos_class_precisions: np.array of precisions corresponding to each of those
      classes.
  """
  num_classes = scores.shape[0]
  pos_class_indices = np.flatnonzero(truth > 0)
  # Only calculate precisions if there are some true classes.
  if not len(pos_class_indices):
    return pos_class_indices, np.zeros(0)
  # Retrieval list of classes for this sample. 
  retrieved_classes = np.argsort(scores)[::-1]
  # class_rankings[top_scoring_class_index] == 0 etc.
  class_rankings = np.zeros(num_classes, dtype=np.int)
  class_rankings[retrieved_classes] = range(num_classes)
  # Which of these is a true label?
  retrieved_class_true = np.zeros(num_classes, dtype=np.bool)
  retrieved_class_true[class_rankings[pos_class_indices]] = True
  # Num hits for every truncated retrieval list.
  retrieved_cumulative_hits = np.cumsum(retrieved_class_true)
  # Precision of retrieval list truncated at each hit, in order of pos_labels.
  precision_at_hits = (
      retrieved_cumulative_hits[class_rankings[pos_class_indices]] / 
      (1 + class_rankings[pos_class_indices].astype(np.float)))
  return pos_class_indices, precision_at_hits

依我之见,这篇博客提供了一个关于平均精度和地图的直观解释。链接 - HaaLeo
1个回答

34
为了更好地理解分数是如何计算的,让我们举一个简单的例子。假设我们正在标记可能包含猫、狗和/或鸟类的图像。类数组看起来像[猫,狗,鸟]。因此,如果我们有一张仅包含猫的图像,则真实数组的形式将为[1,0,0]。
我们将这张仅包含猫的图像输入模型,它输出[.9,.2,.3]。首先,我们对模型预测的标签进行排名。 猫得到第一名,鸟得到第二名,狗得到第三名。现在,我们计算从第一名开始到达感兴趣的真实类别(猫)需要多少个标签。模型将猫放在第一位,因此这只需要一个值为1的值。接下来,我们计算在到达正确标签(猫)之前还有多少其他真实标签。这可能会在一开始时令人困惑,但稍后在多标签示例中将变得必要。对于此情况,猫标签是正确的,我们不需要再移动任何值,因此这也取值为1。得分通过将第二个值除以第一个值来计算。在这种情况下,得分为1/1 = 1。

如果模型排列顺序错误会发生什么?我们使用另一个模型来测试同一张猫的图片。输出结果为[.6, .8, .1],依次排名为1. 狗、2. 猫、3. 鸟。计算从第一名开始到正确类别(猫)需要几个标签。在这种情况下,需要两个标签,因此第一个值为2。 接下来,确定沿途有多少个正确标签。只有1个,因此第二个值为1。对于这种情况,得分为1/2 = 0.50。

好的,这些都是简单的例子。下面两个例子我不会那么冗长,但应用与上述相同的逻辑。主要区别在于需要单独计算每个正确标签。

正确评级两个标签: 图像包含一只猫和一只鸟 [1, 0, 1]。模型输出 [.8, .2, .9],排名为1. 鸟、2. 猫、3. 狗。 对于猫标签,第一个值为2(需要两个标签才能找到猫标签),第二个值为2(沿途有两个正确的标签,鸟和猫)。得分=2/2 = 1。对于鸟标签,第一个值为1,第二个值为1。得分= 1/1 = 1。

错误地排列了两个标签:图像包含一只猫和一只狗[1,1,0]。模型输出为[.1,.2,.8]。排名是鸟、狗、猫。对于猫标签,第一个值为3,第二个值为2。得分=2/3=0.66。对于狗标签,第一个值为2,第二个值为1。得分=1/2=0.50。

好的,那么我们如何得到每个类别的最终得分?最简单的方法是取平均值。让我们使用先前的两个示例来计算。对于猫,我们有得分为1和0.66。最终猫得分=(1 + 0.66)/2 = 0.83。对于狗,我们只有得分为0.50,因此最终狗得分=0.50。对于鸟,我们只有得分为1.0,因此最终鸟得分=1。这种指标非常适合分析类别性能。

我们如何将这些类别得分压缩为一个综合得分?我们可以只平均所有最终类别得分,但这会稀释常见类别的得分并提高不常见类别的得分。相反,我们可以简单地使用加权平均值!使用两个示例图像,我们有2只猫,1只狗和1只鸟。最终得分=(2只猫/ 4个标签)* 0.83 +(1只狗/ 4个标签)* 0.50 +(1只鸟/ 4个标签)* 1.0 = 0.79。方便地,这最终与所有个体得分的平均值相同,因此我们甚至不需要存储类别权重。回想一下,对于第一个图像的猫和鸟我们有个体得分为1和1,对于第二个图像的猫和狗我们有个体得分为0.66和0.50。(1 + 1 + 0.66 + 0.50)/4 = 0.79。

希望这能让你更好地理解这些计算。由于我已经说得够多了,所以把代码留给另一个发帖者。也许如果没人很快回答那部分的话,我可以添加一篇文章。


感谢您提供的精彩解释!可以这样说,LRAP为0意味着模型学习了所有相反的内容吗?(就像-1的$R^2$相关分数表示存在反向相关性一样)而LRAP为0.5则意味着模型是完全随机的吗? - Alexander Soare
整体LRAP接近零意味着您的模型将正确的类别排在最后。如果发生这种情况,这可能是一个好迹象,因为这可能意味着您在多热向量中翻转了0和1。 LRAP为0.5具有不同的含义,具体取决于其每个样本的方差。例如,您可能拥有一种在排名某些样本方面表现出色,然后在其他样本方面表现糟糕的模型(高方差)。您还可以拥有一种一致地在包中排列正确的类别的模型(低方差)。这两种情况都需要重新检查数据和模型是否存在问题。 - Austin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接