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
函数返回 NaN
而tf.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-learnpermutation_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 准确度分数