我试图在Python中使用一些数据拟合曲线 scipy.optimize.curve_fit
。我遇到了错误 ValueError: array must not contain infs or NaNs
。
我不相信我的 x
要么 y
数据包含infs或NaN:
>>> x_array = np.asarray_chkfinite(x_array)
>>> y_array = np.asarray_chkfinite(y_array)
>>>
想知道我的意思 x_array
和 y_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)
如何避免它。
为什么会失败
不是你的输入数组 nans
要么 infs
,但是在某些X点和某些参数值的目标函数的评估会导致 nans
要么 infs
:换句话说,数组有值 func(x,alpha,beta,b)
对于某些x,alpha,beta和b正在给出 nans
要么 infs
优化程序。
Scipy.optimize曲线拟合函数使用Levenberg-Marquardt算法。它也被称为阻尼最小二乘优化。这是一个迭代过程,并且在每次迭代时计算最佳函数参数的新估计。此外,在优化过程中的某个时刻,算法正在探索未定义函数的参数空间的某些区域。
怎么修
1 /初步猜测
参数的初始猜测对于收敛是决定性的。如果初始猜测远非最优解,那么您更有可能探索一些未定义目标函数的区域。因此,如果您可以更好地了解最佳参数,并使用此初始猜测提供算法,则可以避免在执行过程中出现错误。
2 /型号
此外,您可以修改您的模型,以便它不会返回 nans
。对于那些参数值, params
原来的功能 func
没有定义,你希望目标函数需要巨大的价值,或者换句话说 func(params)
是远远不适合Y值。
此外,在未定义目标函数的位置,您可以返回一个大浮点数 AVG(Y)*10e5
AVG的平均值(这样你就可以确保比要安装的Y值的平均值大得多)。
链接
你可以看一下这篇文章: 将数据拟合到python与gnuplot中的等式
您的函数具有负幂(x ^ -alpha),这与(1 / x)^(alpha)相同。如果x为0,你的函数将返回inf并且你的曲线拟合操作将会中断,我很惊讶之前没有抛出警告/错误,告知你除以0。
顺便说一句,为什么你乘以除以1?
为什么会失败
不是你的输入数组 nans
要么 infs
,但是在某些X点和某些参数值的目标函数的评估会导致 nans
要么 infs
:换句话说,数组有值 func(x,alpha,beta,b)
对于某些x,alpha,beta和b正在给出 nans
要么 infs
优化程序。
Scipy.optimize曲线拟合函数使用Levenberg-Marquardt算法。它也被称为阻尼最小二乘优化。这是一个迭代过程,并且在每次迭代时计算最佳函数参数的新估计。此外,在优化过程中的某个时刻,算法正在探索未定义函数的参数空间的某些区域。
怎么修
1 /初步猜测
参数的初始猜测对于收敛是决定性的。如果初始猜测远非最优解,那么您更有可能探索一些未定义目标函数的区域。因此,如果您可以更好地了解最佳参数,并使用此初始猜测提供算法,则可以避免在执行过程中出现错误。
2 /型号
此外,您可以修改您的模型,以便它不会返回 nans
。对于那些参数值, params
原来的功能 func
没有定义,你希望目标函数需要巨大的价值,或者换句话说 func(params)
是远远不适合Y值。
此外,在未定义目标函数的位置,您可以返回一个大浮点数 AVG(Y)*10e5
AVG的平均值(这样你就可以确保比要安装的Y值的平均值大得多)。
链接
你可以看一下这篇文章: 将数据拟合到python与gnuplot中的等式
您的函数具有负幂(x ^ -alpha),这与(1 / x)^(alpha)相同。如果x为0,你的函数将返回inf并且你的曲线拟合操作将会中断,我很惊讶之前没有抛出警告/错误,告知你除以0。
顺便说一句,为什么你乘以除以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:数组不能包含infs或NaNs”
我认为正在发生的是,numpy正在被喂食巨大的数字和非常微小的数字,并且在它的小脑中它正在创造NaN和Inf的。所以这是sklearn中的一个错误。解决方法是将输入数据展平为算法,以便没有非常大或非常小的数字。
糟糕的sklearn!没有饼干!