テンソルフローを使用してマルチクラス分類を行うときに、クラスごとの精度または再現率を取得する方法はありますか?.
たとえば、各バッチからy_trueとy_predがある場合、2つを超えるクラスがある場合に、クラスごとに精度または再現率を取得する機能的な方法はありますか。
これは、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変数の場合と同様にブールベクトルに設定され、関数を使用できます。
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))
これにより、精度の配列が出力され、値が呼び出されますが、必要に応じてフォーマットされます。
私はこの問題にかなり長い間戸惑っていました。この問題はsklearnで解決できることはわかっていますが、TensorflowのAPIで解決したいのです。そして、そのコードを読むことで、このAPIがどのように機能するかをついに理解しました。
tf.metrics.precision_at_k(labels, predictions, k, class_id)
最後に、この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で始まります。
2つの事実:
他の回答で述べたように、Tensorflowの組み込み指標 precision および recallはマルチクラスをサポートしていません(ドキュメントwill be cast to bool
)と言います
precision_at_k を使用してclass_id
を指定するか、単にlabels
と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)
TFはまだそのような機能を提供していないと思います。ドキュメント( https://www.tensorflow.org/api_docs/python/tf/metrics/precision )によると、ラベルと予測の両方がブール値にキャストされるため、関連していますバイナリ分類のみ。おそらく、サンプルをワンホットエンコードすることが可能であり、うまくいくでしょうか。しかし、これについてはわかりません。
TensorFlowでこれを行う方法があります。
tf.metrics.precision_at_k(labels, predictions, k, class_id)
k = 1に設定し、対応するclass_idを設定します。たとえば、最初のクラスの精度を計算するには、class_id = 0です。