tf.metrics.auc与sklearn.metrics.roc_auc_score

时间:2018-08-19 23:04:42

标签: python tensorflow scikit-learn

在某些情况下,与tf.metrics.auc相比,

sklearn.metrics.roc_auc_score产生了非常不同的值。

我无法确定这种情况的特殊性,但我能够获得可再现的示例:

可从https://www.dropbox.com/s/ym2ptqaqw2qjite/minimal_program_AUC.zip?raw=1下载代码和数据

代码:

import sklearn.metrics
from keras.models import Model, load_model
import tensorflow as tf
from keras import backend as K
import numpy as np

def auc(y_true, y_pred):
    auc = tf.metrics.auc(y_true, y_pred, num_thresholds=65)[1]
    K.get_session().run(tf.local_variables_initializer())
    return auc

model = load_model('Model.hdf5', custom_objects={'auc': auc})

X = np.fromfile('X_test(65, 80, 1292, 1).txt', sep=',').reshape(65, 80, 1292, 1)
Y = np.fromfile('Y_test(65, 1).txt', sep=',').reshape(65, 1)
batchsize = 45

evaluation = model.evaluate(X, Y, batch_size=batchsize, verbose=1)

predictions = model.predict(X, batch_size=batchsize, verbose=0, steps=None)

auc = sklearn.metrics.roc_auc_score(Y, predictions, average='macro', sample_weight=None)

print('sklearn.metrics.roc_auc_score: ', auc)
print('vs')
print('tf.metrics.auc: ', evaluation[2])

结果:

  

sklearn.metrics.roc_auc_score:0.40476190476190477

     

vs

     

tf.metrics.auc:0.2756012196724231



讨论:我已经读过tf.metrics.auc is approximate,并且num_thresholds越高,它越接近理想的AUC。 (变更请求/旁注:我的数据只有65个样本,因此使用65个阈值可以计算理想的AUC) 我已经使用多个阈值进行了测试,并且输出的AUC值有所不同,但与sklearn.metrics.roc_auc_score

不完全匹配

编辑:我还使用batchsize = X.shape[0]进行了测试,因此只计算了1批,并且没有“修复”它

我没有发现sklearn.metrics.roc_auc_score是近似值还是理想值。

问题:怎么了?我们应该创建一个故障单吗?

EDIT2:这是罪魁祸首,预测都几乎为0.5,这导致TF AUC计算的近似性质加剧了

0.506357729434967 0.4968412518501282 0.506340742111206 0.4976259469985962 0.5060197114944458 0.5054880976676941 0.506357729434967 0.5063252449035645 0.506357729434967 0.5028414130210876 0.49709421396255493 0.505968451499939 0.49766668677330017 0.506357729434967 0.506357729434967 0.5059878826141357 0.5063162446022034 0.5062981247901917 0.506357729434967 0.4971608519554138 0.506357729434967 0.506357729434967 0.4985077977180481 0.4981336295604706 0.5063574314117432 0.49704432487487793 0.506357729434967 0.5062510967254639 0.506357729434967 0.49734553694725037 0.49696335196495056 0.506357729434967 0.506357729434967 0.4975492060184479 0.49732962250709534 0.5019861459732056 0.4974926710128784 0.506357729434967 0.4975907504558563 0.49734383821487427 0.49705255031585693 0.506357729434967 0.5036844611167908 0.506357729434967 0.5041226148605347 0.5029517412185669 0.49785998463630676 0.5061197280883789 0.506357729434967 0.49714547395706177 0.506357729434967 0.506357729434967 0.5018795132637024 0.4972745478153229 0.49750152230262756 0.5063059329986572 0.49842190742492676 0.5164832472801208 0.496705561876297 0.49700644612312317 0.49824368953704834 0.5063083171844482 0.5031181573867798 0.49714842438697815 0.4966968595981598

2 个答案:

答案 0 :(得分:0)

以Qusai所说的为基础:

  • 小于0.5的AUC值不是评估工作分类器时的期望值
  • 在TF情况下(引用文档)“使用了线性间隔的阈值集”,这意味着,如果某些预测非常接近,那么得分将非常不准确。

此示例中的分类器并没有真正起作用,当标签值为0或1时,上述预测几乎为0.5。

此外,鉴于所有预测都非常接近,因此计算出的分数确实遥遥无期。

答案 1 :(得分:0)

我相信在您的训练过程中使用 auc 作为指标(model.fit(..., metrics=[auc],...) 意味着它将计算每个 minibatch 的 auc 并给出平均值,这不是 auc 的工作原理。

您在最后使用预测和真实标签使用的 roc_auc_score 更准确。您可以通过绘制 roc 曲线来验证这些值,因为可以轻松区分 ~0.2 auc 和 ~0.4。