【问题标题】:Numpy numerical stability [duplicate]Numpy数值稳定性
【发布时间】:2020-08-04 07:19:20
【问题描述】:

我有一个机器学习模型,它输出直到小数点后一位的概率(即 0.0、0.1、0.2、... 1.0)

写循环时

for i in np.arange(0,1.1,0.1)
    if p >= i:
       print('yes for i = %f' % i)
    else:
       print('no for i = %f' % i)

但问题是np.arange 为三个值输出了一个轻微的数字错误:

0.3变成0.30000000000000004:

0.6 变成 0.6000000000000001:

0.7 变成 0.7000000000000001

p=0.6时,这将导致输出

没有 i = 0.6000000000000001

我该如何规避这个问题?

【问题讨论】:

  • 这能回答你的问题吗? Is floating point math broken?
  • @Keldorn:OP 的问题是如何解决它,而不是它为什么会发生,但您链接上的一些答案包含解决方案。 numpy floating point comparison 的问题可能就在附近,尽管在某些情况下答案不如您的链接有用。
  • @Andris OP 的问题是基于一个错误的前提。 0.3 没有变成 0.30000000000000004,没有 0.3 开头。这是由于对浮点运算的误解。看起来主持人同意了,因为问题已作为重复关闭。
  • 我知道浮点表示,但 scitkit 学习模型将其作为一个值返回,所以当某些值不可表示时,它们首先是如何返回的?

标签: python numpy numeric


【解决方案1】:

“轻微的数字错误”不是数字错误,而是浮点数的一个已知问题:它们是两个存储的二进制和can't represent all real numbers 的分数之和。

如果您希望打印精确的 n 位数字,您可能希望使用格式字符串进行打印,例如%.1f 而不是 %f

要解决比较行为,您可以更改存储数字的方式(但考虑到您使用它们的字段,我怀疑这是一个好主意)或更改比较它们的方式:为两个数字之间的 epsilon“错误”差异留出空间.如果你不想实现自己的方式来做,你可以use numpy/math isclose for checking equality这样:

import numpy as np

p = 0.6

for i in np.arange(0,1.1,0.1):
    if p > i or np.isclose(p,i):
        print('yes for i = %f' % i)
    else:
        print('no for i = %f' % i)

根据您实际希望做的事情而不是您给出的最小示例,一次执行比较可能会更有效:

i = np.arange(0,1.1,0.1)
compres = np.logical_or(p>i, np.isclose(p,i))

for i, ge in zip(i, compres):
    if ge:
        print('yes for i = %.1f' % i)
    else:
        print('no for i = %.1f' % i)

编辑: 我删除了乘以 10000 并在比较之前进行舍入的想法,因为它可能会导致舍入错误,例如0.649999 与 0.650001 的情况。它可能很有用,但要谨慎。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-03
    • 2018-07-18
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 2016-12-23
    • 1970-01-01
    相关资源
    最近更新 更多