14

我正在尝试使用 Python 将一些数据拟合到曲线中scipy.optimize.curve_fit。我遇到了错误ValueError: array must not contain infs or NaNs

我不相信我的xy数据包含 infs 或 NaN:

>>> x_array = np.asarray_chkfinite(x_array)
>>> y_array = np.asarray_chkfinite(y_array)
>>>

了解一下 myx_arrayy_array两端的样子(x_array是计数和y_array分位数):

>>> type(x_array)
<type 'numpy.ndarray'>
>>> type(y_array)
<type 'numpy.ndarray'>
>>> x_array[:5]
array([0, 0, 0, 0, 0])
>>> x_array[-5:]
array([2919, 2965, 3154, 3218, 3461])
>>> y_array[:5]
array([ 0.9999582,  0.9999163,  0.9998745,  0.9998326,  0.9997908])
>>> y_array[-5:]
array([  1.67399000e-04,   1.25549300e-04,   8.36995200e-05,
     4.18497600e-05,  -2.22044600e-16])

我的功能:

>>> def func(x,alpha,beta,b):
...    return ((x/1)**(-alpha) * ((x+1*b)/(1+1*b))**(alpha-beta))
...

我正在执行:

>>> popt, pcov = curve_fit(func, x_array, y_array)

导致错误堆栈跟踪:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py", line 426, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py", line 338, in leastsq
cov_x = inv(dot(transpose(R),R))
File "/usr/lib/python2.7/dist-packages/scipy/linalg/basic.py", line 285, in inv
a1 = asarray_chkfinite(a)
File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 590, in asarray_chkfinite
"array must not contain infs or NaNs")
ValueError: array must not contain infs or NaNs

该错误可能与我的数组无关,而是与 scipy 在中间步骤中创建的数组有关?我已经对相关的 scipy 源文件进行了一些挖掘,但是以这种方式调试问题很快就会变得棘手。有什么明显的我做错了吗?我在其他问题中随便提到过,有时某些初始参数猜测(我目前没有任何明确的猜测)可能会导致这类错误,但即使是这种情况,最好知道a)为什么那是以及b)如何避免它。

4

3 回答 3

12

为什么它失败了

不是您的输入数组包含nansor infs,而是在某些 X 点和参数的某些值对目标函数的评估导致nansor infs:换句话说,具有func(x,alpha,beta,b)某些 x、alpha、beta 和 b 值的数组给出nansinfs超过优化例程。

Scipy.optimize 曲线拟合函数使用 Levenberg-Marquardt 算法。它也被称为阻尼最小二乘优化。它是一个迭代过程,每次迭代都会计算最佳函数参数的新估计值。此外,在优化过程中的某个时刻,算法正在探索参数空间中未定义函数的某些区域。

怎么修

1/初步猜测

参数的初始猜测对于收敛是决定性的。如果初始猜测远非最优解,您更有可能探索目标函数未定义的某些区域。因此,如果您可以更好地了解您的最佳参数是什么,并为您的算法提供这个初始猜测,那么可能会避免在进行过程中出现错误。

2/型号

此外,您可以修改模型,使其不返回nans. 对于那些未定义params原始函数的参数值func,您希望目标函数采用巨大的值,或者换句话说, func(params)远离要拟合的 Y 值。

此外,在未定义目标函数的点上,您可能会返回一个大浮点数,例如AVG(Y)*10e5使用 AVG 平均值(这样您就可以确保比要拟合的 Y 值的平均值大得多)。

关联

你可以看看这篇文章:Fitting data to an equation in python vs gnuplot

于 2013-01-23T06:02:38.497 回答
3

您的函数具有负幂 (x^-alpha),这与 (1/x)^(alpha) 相同。如果 x 永远为 0,您的函数将返回 inf 并且您的曲线拟合操作将中断,我很惊讶没有提前抛出警告/错误,通知您除以 0。

顺便说一句,你为什么要乘以除以 1?

于 2013-01-23T00:11:35.517 回答
1

我能够在 python2.7 中重现此错误,如下所示:

from sklearn.decomposition import FastICA
X = load_data.load("stuff")    #this sets X to a 2d numpy array containing 
                               #large positive and negative numbers.
ica = FastICA(whiten=False)

print(np.isnan(X).any())   #this prints False
print(np.isinf(X).any())   #this prints False

ica.fit(X)                 #this produces the error:

总是会产生错误:

/usr/lib64/python2.7/site-packages/sklearn/decomposition/fastica_.py:58: RuntimeWarning: invalid value encountered in sqrt
  return np.dot(np.dot(u * (1. / np.sqrt(s)), u.T), W)
Traceback (most recent call last):
  File "main.py", line 43, in <module>
    ica()
  File "main.py", line 18, in ica
    ica.fit(X)
  File "/usr/lib64/python2.7/site-packages/sklearn/decomposition/fastica_.py", line 523, in fit
    self._fit(X, compute_sources=False)
  File "/usr/lib64/python2.7/site-packages/sklearn/decomposition/fastica_.py", line 479, in _fit
    compute_sources=compute_sources, return_n_iter=True)
  File "/usr/lib64/python2.7/site-packages/sklearn/decomposition/fastica_.py", line 335, in fastica
    W, n_iter = _ica_par(X1, **kwargs)
  File "/usr/lib64/python2.7/site-packages/sklearn/decomposition/fastica_.py", line 108, in _ica_par
    - g_wtx[:, np.newaxis] * W)
  File "/usr/lib64/python2.7/site-packages/sklearn/decomposition/fastica_.py", line 55, in _sym_decorrelation
    s, u = linalg.eigh(np.dot(W, W.T))
  File "/usr/lib64/python2.7/site-packages/scipy/linalg/decomp.py", line 297, in eigh
    a1 = asarray_chkfinite(a)
  File "/usr/lib64/python2.7/site-packages/numpy/lib/function_base.py", line 613, in asarray_chkfinite
    "array must not contain infs or NaNs")
ValueError: array must not contain infs or NaNs

解决方案:

from sklearn.decomposition import FastICA
X = load_data.load("stuff")    #this sets X to a 2d numpy array containing 
                               #large positive and negative numbers.
ica = FastICA(whiten=False)

#this is a column wise normalization function which flattens the
#two dimensional array from very large and very small numbers to 
#reasonably sized numbers between roughly -1 and 1
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)

print(np.isnan(X).any())   #this prints False
print(np.isinf(X).any())   #this prints False

ica.fit(X)                 #this works correctly.

为什么该规范化步骤可以修复错误?

我在这里找到了尤里卡时刻:sklearn 的 PLSRegression: "ValueError: array must not contain infs or NaNs"

我认为正在发生的事情是,numpy 正在被输入巨大的数字和非常小的数字,而在它的小大脑内部,它正在创建 NaN 和 Inf。所以这是sklearn中的一个错误。解决方法是将您的输入数据展平到算法中,以便没有非常大或非常小的数字。

糟糕的sklearn!没有饼干!

于 2016-04-03T20:00:58.983 回答