Scipy.optimize.curvefit() - массив не должен содержать infs или NaNs
Я пытаюсь сопоставить некоторые данные с кривой в Python, используя scipy.optimize.curve_fit
. Я столкнулся с ошибкой ValueError: array must not contain infs or NaNs
.
Я не считаю, что мои данные x
или y
содержат inf или NaNs:
>>> x_array = np.asarray_chkfinite(x_array)
>>> y_array = np.asarray_chkfinite(y_array)
>>>
Чтобы дать некоторое представление о том, как выглядят мои x_array
и y_array
на обоих концах (x_array
- counts и 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)
как его избежать.
Ответы
Ответ 1
Почему он терпит неудачу
Не ваши входные массивы влекут за собой nans
или infs
, но оценка вашей целевой функции в некоторых точках X и для некоторых значений параметров приводит к nans
или infs
: другими словами, массив со значениями func(x,alpha,beta,b)
для некоторых x, alpha, beta и b дает nans
или infs
над процедурой оптимизации.
Scipy.optimize функция подгонки кривой использует алгоритм Левенберга-Марквардта. Он также называется затухающей наименьшей квадратичной оптимизацией. Это итеративная процедура, и на каждой итерации вычисляется новая оценка оптимальных параметров функции. Кроме того, в какой-то момент оптимизации алгоритм исследует некоторую область пространства параметров, где ваша функция не определена.
Как исправить
1/Исходная оценка
Исходная оценка параметров является решающей для сходимости. Если первоначальная догадка далека от оптимального решения, вы с большей вероятностью исследуете некоторые области, где целевая функция undefined. Таким образом, если вы можете лучше понять, какие ваши оптимальные параметры и подать свой алгоритм с этим первоначальным предположением, можно избежать ошибки при продолжении.
2/Модель
Кроме того, вы можете изменить свою модель, чтобы она не возвращала nans
. Для тех значений параметров params
, где исходная функция func
не определена, вы хотите, чтобы целевая функция принимала огромные значения, или, другими словами, что func(params)
далека от значений Y, которые нужно установить.
Кроме того, в тех точках, где ваша целевая функция не определена, вы можете вернуть большой поплавок, например AVG(Y)*10e5
с AVG в среднем (чтобы вы были намного больше среднего значения Y, которое должно быть установлено).
Ссылка
Вы могли бы посмотреть этот пост: Подгонка данных к уравнению в python vs gnuplot
Ответ 2
Ваша функция имеет отрицательную мощность (x ^ -альфа), это то же самое, что (1/x) ^ (альфа). Если x всегда 0, ваша функция вернет inf, и ваша операция с кривой будет ломаться, я удивлен, что предупреждение/ошибка не выбрасывается ранее, информируя вас о делении на 0.
Кстати, почему вы умножаете и делите на 1?
Ответ 3
Я смог воспроизвести эту ошибку в 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.
Почему этот шаг нормализации исправляет ошибку?
Я нашел момент эврики здесь: PLSRegression sklearn: " ValueError: массив не должен содержать infs или NaNs,
То, что я думаю, происходит, это то, что numpy питается гигантскими числами и очень маленькими числами, а внутри него крошечный мозг создает NaN и Inf. Так что это ошибка в sklearn. Работа вокруг заключается в том, чтобы сгладить ваши входные данные в алгоритм, чтобы не было очень больших или очень маленьких чисел.
Плохой склеарн! НЕТ печенья!