Tensorflow中的多类分类的类别精确度和召回率?

问题描述 投票:7回答:6

有没有办法在使用张量流进行多类分类时获得每类精度或召回。

例如,如果我有每个批次的y_true和y_pred,如果我有超过2个类,是否有一种功能性的方法来获得精度或每个类的回忆。

python machine-learning tensorflow classification
6个回答
5
投票

这是一个解决方案,适用于n = 6类的问题。如果你有更多的类,这个解决方案可能很慢,你应该使用某种映射而不是循环。

假设在张量labels和张量labels中的logits(或后验)行中有一个热编码类标签。然后,如果n是类的数量,请尝试:

y_true = tf.argmax(labels, 1)
y_pred = tf.argmax(logits, 1)

recall = [0] * n
update_op_rec = [[]] * n

for k in range(n):
    recall[k], update_op_rec[k] = tf.metrics.recall(
        labels=tf.equal(y_true, k),
        predictions=tf.equal(y_pred, k)
    )

请注意,在tf.metrics.recall中,变量labelspredictions被设置为布尔向量,如2变量情况,允许使用该函数。


3
投票

很长一段时间以来,我一直对这个问题感到困惑。我知道这个问题可以通过sklearn解决,但我真的想通过Tensorflow的API来解决这个问题。通过阅读其代码,我终于弄清楚这个API是如何工作的。

tf.metrics.precision_at_k(labels, predictions, k, class_id)
  • 首先,我们假设这是一个4类问题。
  • 其次,我们有两个样本,他们的标签是3和1,他们的预测是[0.5,0.3,0.1,0.1],[0.5,0.3,0.1,0.1]。根据我们的预测,我们可以得到两个结果样本预测为1,1。
  • 第三,如果你想获得1级的精度,使用公式TP /(TP + FP),我们假设结果是1 /(1 + 1)= 0.5。因为两个样本都被预测为1,但其中一个实际上是3,所以TP是1,FP是1,结果是0.5。
  • 最后,让我们使用此API来验证我们的假设。 import tensorflow as tf labels = tf.constant([[2],[0]],tf.int64) predictions = tf.constant([[0.5,0.3,0.1,0.1],[0.5,0.3,0.1,0.1]]) metric = tf.metrics.precision_at_k(labels, predictions, 1, class_id=0) sess = tf.Session() sess.run(tf.local_variables_initializer()) precision, update = sess.run(metric) print(precision) # 0.5

注意

  • k不是类的数量。它表示我们想要排序的数量,这意味着预测的最后一个维度必须与k的值匹配。
  • class_id表示我们想要二进制度量的类。
  • 如果k = 1,意味着我们不会对预测进行排序,因为我们想要做的实际上是二元分类,而是指不同的类。因此,如果我们对预测进行排序,class_id将会混淆,结果将是错误的。
  • 还有一个重要的事情是,如果我们想要得到正确的结果,标签的输入应减1,因为class_id实际上代表标签的索引,而标签的下标从0开始。

3
投票

我相信你不能用tf.metrics.precision/recall函数做多类精度,回忆,f1。你可以使用这样的sklearn来实现3类场景:

from sklearn.metrics import precision_recall_fscore_support as score

prediction = [1,2,3,2] 
y_original = [1,2,3,3]

precision, recall, f1, _ = score(y_original, prediction)

print('precision: {}'.format(precision))
print('recall: {}'.format(recall))
print('fscore: {}'.format(f1))

这将打印一系列精度,召回值,但可以根据需要进行格式化。


2
投票

在TensorFlow中有一种方法可以做到这一点。

tf.metrics.precision_at_k(labels, predictions, k, class_id)

设置k = 1并设置相应的class_id。例如,class_id = 0来计算第一类的精度。


2
投票

2个事实:

  1. 正如其他答案所述,Tensorflow内置指标precisionrecall不支持多类(文档说will be cast to bool
  2. 通过指定precision_at_k,或者通过简单地以正确的方式将class_idlabels投射到predictions,可以通过使用tf.bool来获得一对一分数。

因为这是不满意和不完整的,我写了tf_metrics,一个简单的多类指标包,你可以在github找到。它支持多种平均方法,如scikit-learn

import tensorflow as tf
import tf_metrics

y_true = [0, 1, 0, 0, 0, 2, 3, 0, 0, 1]
y_pred = [0, 1, 0, 0, 1, 2, 0, 3, 3, 1]
pos_indices = [1]        # Metrics for class 1 -- or
pos_indices = [1, 2, 3]  # Average metrics, 0 is the 'negative' class
num_classes = 4
average = 'micro'

# Tuple of (value, update_op)
precision = tf_metrics.precision(
    y_true, y_pred, num_classes, pos_indices, average=average)
recall = tf_metrics.recall(
    y_true, y_pred, num_classes, pos_indices, average=average)
f2 = tf_metrics.fbeta(
    y_true, y_pred, num_classes, pos_indices, average=average, beta=2)
f1 = tf_metrics.f1(
    y_true, y_pred, num_classes, pos_indices, average=average)

1
投票

我相信TF还没有提供这样的功能。根据文档(https://www.tensorflow.org/api_docs/python/tf/metrics/precision),它表示标签和预测都将转换为bool,因此它仅涉及二进制分类。也许有可能对这些例子进行单热编码,它会起作用吗?但不确定这一点。

© www.soinside.com 2019 - 2024. All rights reserved.