【发布时间】:2019-12-28 03:01:46
【问题描述】:
我正在尝试将 sigmoid 曲线拟合到一小组点上,基本上是根据一组观察结果生成概率曲线。我正在使用scipy.optimize.curve_fit,稍微修改了逻辑函数(以便完全绑定在 [0,1] 内)。目前,我在 dogbox 方法和精确的 tr_solver 方面取得了最大的成功。
当我尝试运行代码时,对于某些数据点,它会引发:
ValueError: `x0` violates bound constraints.
在我更新到最新版本的 numpy/scipy(numpy 1.17.0,scipy 1.3.1)之前,我没有遇到这个问题(使用相同的代码和数据),所以我相信这是一个结果本次更新(我无法降级,因为该项目的其他方面我需要的其他库需要这些版本)
我在一个大型数据集 (N ~15000) 上运行它,对于非常具体的值,曲线拟合失败,声称初始猜测超出了界限约束。情况并非如此,甚至在提供的示例中的曲线拟合之前通过 print 语句快速检查也证实了这一点。
起初我认为这是一个 numpy 精度错误,并且认为这么小的值超出了界限,但稍微改变它或提供一个新的、任意数量的类似大小不会导致 ValueError。此外,其他失败的值大到 ~1e-10,所以我认为它一定是其他的。
这是一个每次都失败的例子:
import numpy as np
import scipy as sp
from scipy.special import expit, logit
import scipy.optimize
def f(x,x0,g,c,k):
y = c*expit(k*10.*(x-x0)) + g*(1.-c)
return y
# x0 g c k
p0 = np.array([8.841357069490852e-01, 4.492363462957287e-19, 5.547073496706608e-01, 7.435378446218519e+00])
bounds = np.array([[-1.,1.], [0.,1.], [0.,1.], [0.,20.]])
x = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 0.8911796599834791, 1.0, 1.0, 1.0, 0.33232919909076103, 1.0])
y = np.array([0.999, 0.999, 0.999, 0.999, 0.999, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001])
s = np.array([0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9])
print([pval >= b[0] and pval <= b[1] for pval,b in zip(p0,bounds)])
fit,cov = sp.optimize.curve_fit(f,x,y,p0=p0,sigma=s,bounds=([b[0] for b in bounds],[b[1] for b in bounds]),method='dogbox',tr_solver='exact')
print(fit)
print(cov)
这里是具体的错误堆栈,上面调用曲线拟合之后的所有内容。
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\scipy\optimize\minpack.py", line 763, in curve_fit
**kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\scipy\optimize\_lsq\least_squares.py", line 927, in least_squares
tr_solver, tr_options, verbose)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\scipy\optimize\_lsq\dogbox.py", line 310, in dogbox
J = jac(x, f)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\scipy\optimize\_lsq\least_squares.py", line 874, in jac_wrapped
kwargs=kwargs, sparsity=jac_sparsity)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\scipy\optimize\_numdiff.py", line 362, in approx_derivative
raise ValueError("`x0` violates bound constraints.")
ValueError: `x0` violates bound constraints.
如果有人对可能导致此问题的原因有任何见解,我将非常感谢您的帮助!我做了一些搜索,找不到任何可能与这种情况有关的答案,所以我决定提出这个问题。谢谢!
编辑 9/9/19:
np.__version__ 是 1.17.2,sp.__version__ 是 1.3.1,当我最初发布此内容时,我使用的是 numpy 1.17.0,但升级并没有解决问题。我在 64 位 Windows 10 上的 Python 3.6.6 上运行它。
如果我将第二个或第四个绑定更改为 +/-np.inf(或同时更改两者),那么代码实际上完成了 - 但我仍然不确定我的 x0 是如何无效的(我仍然需要使拟合限制在这些值上)
编辑:20 年 1 月 22 日
将 np.__version__ 升级到 1.18.1 和 sp.__version__ 升级到 1.4.1,但无济于事。我为这个错误打开了an issue on the scipy github repository。但是,他们似乎也无法重现该问题,因此无法解决。
【问题讨论】:
-
可以单独设置每个绑定 [-np.inf, np.inf] 来尝试找到有问题的绑定,这很容易做到并且可能会有所帮助。
-
@JamesPhillips Jepp,在这里也可以使用 numpy 1.15.0 和 scipy 1.1.0 在 python 2.7.14 上工作。 ..使用
print()建议python3? -
与 python 3.6.5、numpy 1.16.3 和 scipy 1.3.0 相同......不过,它们都适用于 64 位 Linux。
-
请注意,抱怨的不是拟合本身(因为拟合包装器调用初始参数
p0):这是雅可比计算。这被称为here,您可以看到x输入已事先更改,例如here。所以也许x + step会以某种方式导致未处理的越界。我不明白为什么它是特定于操作系统的。值得打开一个错误on the issue tracker。 -
@AndrasDeak 截至 2020 年 1 月 22 日,此问题仍在发生,并且没有提出或找到其他解决方案(升级到 numpy 1.18.1 和 scipy 1.4.1 没有帮助)。根据您的建议,我已在问题跟踪器上打开了一个问题。
标签: python numpy scipy curve-fitting least-squares