web-dev-qa-db-ja.com

Tensorflowのマルチクラス分類のクラスごとの精度と再現率?

テンソルフローを使用してマルチクラス分類を行うときに、クラスごとの精度または再現率を取得する方法はありますか?.

たとえば、各バッチからy_trueとy_predがある場合、2つを超えるクラスがある場合に、クラスごとに精度または再現率を取得する機能的な方法はありますか。

12
prateek agrawal

これは、n = 6クラスの問題に対して私に役立つ解決策です。さらに多くのクラスがある場合、このソリューションはおそらく遅く、ループの代わりに何らかのマッピングを使用する必要があります。

テンソルlabelsの行に1つのホットエンコードされたクラスラベルがあり、テンソルlabelsにロジット(または事後)があるとします。次に、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、変数labelsおよびpredictionsは、2変数の場合と同様にブールベクトルに設定され、関数を使用できます。

5
Avi

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(fscore))

これにより、精度の配列が出力され、値が呼び出されますが、必要に応じてフォーマットされます。

2
Momin Al Aziz

私はこの問題にかなり長い間戸惑っていました。この問題はsklearnで解決できることはわかっていますが、TensorflowのAPIで解決したいのです。そして、そのコードを読むことで、このAPIがどのように機能するかをついに理解しました。

tf.metrics.precision_at_k(labels, predictions, k, class_id)
  • まず、これが4クラスの問題であると仮定しましょう。
  • 次に、2つのサンプルがあり、ラベルは3と1であり、それらの予測は[0.5,0.3,0.1 、0.1]、[0.5,0.3,0.1,0.1]。私たちの予測によれば、2つのサンプルがとして予測されたという結果を得ることができます1,1
  • 3番目に、クラス1の精度を取得する場合は、式TP /(TP + FP)を使用します、そして結果が1 /(1 + 1)= 0.5であると仮定します。 2つのサンプルは両方とも1として予測されていますが、それらの1つは実際には3TPは1FPは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つ重要なことは、正しい結果を得たい場合、labelの入力は1をマイナスする必要があるということですclass_idは実際にはラベルのインデックス、およびラベルの添え字は0で始まります。

1
Hong Lan

2つの事実:

  1. 他の回答で述べたように、Tensorflowの組み込み指標 precision および recallはマルチクラスをサポートしていません(ドキュメントwill be cast to bool)と言います

  2. precision_at_k を使用してclass_idを指定するか、単にlabelspredictionsを正しい方法で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
LeCodeDuGui

TFはまだそのような機能を提供していないと思います。ドキュメント( https://www.tensorflow.org/api_docs/python/tf/metrics/precision )によると、ラベルと予測の両方がブール値にキャストされるため、関連していますバイナリ分類のみ。おそらく、サンプルをワンホットエンコードすることが可能であり、うまくいくでしょうか。しかし、これについてはわかりません。

1
AVCarreiro

TensorFlowでこれを行う方法があります。

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

k = 1に設定し、対応するclass_idを設定します。たとえば、最初のクラスの精度を計算するには、class_id = 0です。

0
Nandeesh