我如何计算张量流中的马修斯相关系数

Tob*_*ken 4 machine-learning python-2.7 tensorflow tf.keras

所以我用 tensorflow keras 做了一个模型,它似乎工作正常。但是,我的主管说计算 Matthews 相关系数以及它已经计算的准确性和损失会很有用。

我的模型与此处教程 ( https://www.tensorflow.org/tutorials/keras/basic_classification ) 中的代码非常相似,只是数据集要小得多。

是否有预建函数,或者我是否必须获得每个测试的预测并手动计算?

Ste*_*t_R 8

没有任何开箱即用的功能,但我们可以根据自定义指标中的公式进行计算。

您提供的基本分类链接用于多类分类问题,而 Matthews 相关系数专门用于二元分类问题。

假设您的模型是针对此类问题以“正常”方式构建的(即y_pred每个记录的数字都在 0 到 1 之间,代表“真”的预测概率,并且标签每个都恰好是一个01代表基本事实“假”和“真” " 分别)然后我们可以添加一个 MCC 度量,如下所示:

# if y_pred > threshold we predict true. 
# Sometimes we set this to something different to 0.5 if we have unbalanced categories

threshold = 0.5  

def mcc_metric(y_true, y_pred):
  predicted = tf.cast(tf.greater(y_pred, threshold), tf.float32)
  true_pos = tf.math.count_nonzero(predicted * y_true)
  true_neg = tf.math.count_nonzero((predicted - 1) * (y_true - 1))
  false_pos = tf.math.count_nonzero(predicted * (y_true - 1))
  false_neg = tf.math.count_nonzero((predicted - 1) * y_true)
  x = tf.cast((true_pos + false_pos) * (true_pos + false_neg) 
      * (true_neg + false_pos) * (true_neg + false_neg), tf.float32)
  return tf.cast((true_pos * true_neg) - (false_pos * false_neg), tf.float32) / tf.sqrt(x)
Run Code Online (Sandbox Code Playgroud)

我们可以在我们的model.compile电话中包括:

model.compile(optimizer='adam',
              loss=tf.keras.losses.binary_crossentropy,
              metrics=['accuracy', mcc_metric])
Run Code Online (Sandbox Code Playgroud)

例子

这是一个完整的工作示例,我们根据它们是否大于 4 对 mnist 数字进行分类:

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
y_train, y_test = 0 + (y_train > 4), 0 + (y_test > 4)

def mcc_metric(y_true, y_pred):
  predicted = tf.cast(tf.greater(y_pred, 0.5), tf.float32)
  true_pos = tf.math.count_nonzero(predicted * y_true)
  true_neg = tf.math.count_nonzero((predicted - 1) * (y_true - 1))
  false_pos = tf.math.count_nonzero(predicted * (y_true - 1))
  false_neg = tf.math.count_nonzero((predicted - 1) * y_true)
  x = tf.cast((true_pos + false_pos) * (true_pos + false_neg) 
      * (true_neg + false_pos) * (true_neg + false_neg), tf.float32)
  return tf.cast((true_pos * true_neg) - (false_pos * false_neg), tf.float32) / tf.sqrt(x)

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='relu'),
  tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.binary_crossentropy,
              metrics=['accuracy', mcc_metric])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
Run Code Online (Sandbox Code Playgroud)

输出:

Epoch 1/5
60000/60000 [==============================] - 7s 113us/sample - loss: 0.1391 - acc: 0.9483 - mcc_metric: 0.8972
Epoch 2/5
60000/60000 [==============================] - 6s 96us/sample - loss: 0.0722 - acc: 0.9747 - mcc_metric: 0.9495
Epoch 3/5
60000/60000 [==============================] - 6s 97us/sample - loss: 0.0576 - acc: 0.9797 - mcc_metric: 0.9594
Epoch 4/5
60000/60000 [==============================] - 6s 96us/sample - loss: 0.0479 - acc: 0.9837 - mcc_metric: 0.9674
Epoch 5/5
60000/60000 [==============================] - 6s 95us/sample - loss: 0.0423 - acc: 0.9852 - mcc_metric: 0.9704
10000/10000 [==============================] - 1s 58us/sample - loss: 0.0582 - acc: 0.9818 - mcc_metric: 0.9639
[0.05817381642502733, 0.9818, 0.9638971]
Run Code Online (Sandbox Code Playgroud)


小智 5

计算马修斯相关系数的预建函数

sklearn.metrics.matthews_corrcoef(y_true, y_pred, sample_weight=None )
Run Code Online (Sandbox Code Playgroud)

例子 :

> from sklearn.metrics import matthews_corrcoef
> y_true = [+1, +1, +1, -1]
> y_pred = [+1, -1, +1, +1]
> matthews_corrcoef(y_true, y_pred) 
Run Code Online (Sandbox Code Playgroud)

请参阅文档


The*_*Cat 5

由于提问者接受了 sklearn 的 Python 版本,这里是纯 Python 中的 Stewart_Rs 答案:

from math import sqrt
def mcc(tp, fp, tn, fn):

    # /sf/answers/3981296231/
    x = (tp + fp) * (tp + fn) * (tn + fp) * (tn + fn)
    return ((tp * tn) - (fp * fn)) / sqrt(x)
Run Code Online (Sandbox Code Playgroud)

它具有通用性的优点,而不仅仅是用于评​​估二元分类。