sklearn 的 log_loss 给出了 nan,而 tensorflow.losses.log_loss 有效

Posted

技术标签:

【中文标题】sklearn 的 log_loss 给出了 nan,而 tensorflow.losses.log_loss 有效【英文标题】:log_loss from sklearn gives nan, while tensorflow.losses.log_loss works 【发布时间】:2018-10-13 22:10:22 【问题描述】:

我有一个二元分类问题。 我正在使用来自tensorflow.losses.log_loss 的 log_loss。

为了检查,我使用sklearn.metrics.log_loss。大多数时候,这两个函数给出相同的结果(只有 dtype 不同)。在某些情况下,sklearn 函数返回 NaNtf.losses.log_loss 返回正确的值。

数据在这里: https://pastebin.com/BvDgDnVT

代码:

import sklearn.metrics
import tensorflow as tf
y_true = [... see pastebin link]
y_pred = [... see pastebin link]
loss_sk = sklearn.metrics.log_loss(y_true, y_pred, labels=[0, 1]) # -> returns NaN
with tf.Session() as sess:
    loss_tf = tf.losses.log_loss(y_true, y_pred).eval(session=sess) # -> returns 0.0549

好像有一些log(0)发生了,但是为什么tensorflow没有这个问题呢?

【问题讨论】:

这看起来像你偶然发现了一个错误,因为我得到了相同的结果。它看起来像是某种形式的溢出,因为获取列表的子部分可以正常工作,所以它不是一个特定的值。 【参考方案1】:

解决此问题的另一种方法是将eps=1e-7 提供给log_loss,这是float32 更合适的epsilon,并且是tensorflow 使用的。 然而,Scikit 使用 1e-15 作为默认值(期望 float64)。

【讨论】:

谢谢!我正在使用 scikit-learn permutation_importance 并因此获得 NaN 的重要性。在 scorer 中设置 eps 可以解决这个问题。 :)【参考方案2】:

将两个数组的 dtype 更改为 64 位浮点数修复它

dtype=np.float64

例如添加y_pred = y_pred.astype(np.float64)

【讨论】:

为什么?我也偶然发现了这个问题,但好奇地将我的 numpy 数组转换为 pandas 系列的 dtype float64 修复了它!

以上是关于sklearn 的 log_loss 给出了 nan,而 tensorflow.losses.log_loss 有效的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow 和 Scikitlearn log_loss 函数实现的区别

具有交叉验证的 Sklearn 线性回归返回 NA 准确度分数

为啥logloss是负数?

python sklearn 朴素贝叶斯分类

Sklearn 和 StatsModels 给出了非常不同的逻辑回归答案

多个类的 tf.losses.logloss