ValueError: входные данные содержат значения NAN - из модели lmfit, несмотря на то, что входные данные не содержат NaN.

Я пытаюсь построить модель с помощью lmfit (ссылка на документы), и я не могу понять, почему я продолжаю получать ValueError: The input contains nan values, когда пытаюсь соответствовать модели.

from lmfit import minimize, Minimizer, Parameters, Parameter, report_fit, Model
import numpy as np

def cde(t, Qi, at, vw, R, rhob_cb, al, d, r):
    # t (time), is the independent variable
    return Qi / (8 * np.pi * ((at * vw)/R) * t * rhob_cb * (np.sqrt(np.pi * ((al * vw)/R * t))))  * \
        np.exp(- (R * (d - (t * vw)/ R)**2) / (4 * (al * vw) * t) - (R * r**2)/ (4 * (at * vw) * t))

model_cde =  Model(cde)


# Allowed to vary
model_cde.set_param_hint('vw', value =10**-4, min=0.000001)
model_cde.set_param_hint('d', value = -0.038, min = 0.0001)
model_cde.set_param_hint('r', value = 5.637e-10)
model_cde.set_param_hint('at', value =0.1)
model_cde.set_param_hint('al', value =0.15)

# Fixed
model_cde.set_param_hint('Qi', value = 1000, vary = False)
model_cde.set_param_hint('R', value =1.7, vary = False)
model_cde.set_param_hint('rhob_cb', value =3000, vary = False)

# test data
data = [ 1.37,  1.51,  1.65,  1.79,  1.91,  2.02,  2.12,  2.2 ,
        2.27,  2.32,  2.36,  2.38,  2.4 ,  2.41,  2.42,  2.41,  2.4 ,
        2.39,  2.37,  2.35,  2.33,  2.31,  2.29,  2.26,  2.23,  2.2 ,
        2.17,  2.14,  2.11,  2.08,  2.06,  2.02,  1.99,  1.97,  1.94,
        1.91,  1.88,  1.85,  1.83,  1.8 ,  1.78,  1.75,  1.72,  1.7 ,
        1.68,  1.65,  1.63,  1.61,  1.58]

time = list(range(5,250,5))

model_cde.fit(data, t= time)

Выдает следующую ошибку:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-16-785fcc6a994b> in <module>()
----> 1 model_cde.fit(data, t= time)

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/lmfit/model.py in fit(self, data, params, weights, method, iter_cb, scale_covar, verbose, fit_kws, **kwargs)
    539                              scale_covar=scale_covar, fcn_kws=kwargs,
    540                              **fit_kws)
--> 541         output.fit(data=data, weights=weights)
    542         output.components = self.components
    543         return output

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/lmfit/model.py in fit(self, data, params, weights, method, **kwargs)
    745         self.init_fit    = self.model.eval(params=self.params, **self.userkws)
    746 
--> 747         _ret = self.minimize(method=self.method)
    748 
    749         for attr in dir(_ret):

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/lmfit/minimizer.py in minimize(self, method, params, **kws)
   1240                     val.lower().startswith(user_method)):
   1241                     kwargs['method'] = val
-> 1242         return function(**kwargs)
   1243 
   1244 

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/lmfit/minimizer.py in leastsq(self, params, **kws)
   1070         np.seterr(all='ignore')
   1071 
-> 1072         lsout = scipy_leastsq(self.__residual, vars, **lskws)
   1073         _best, _cov, infodict, errmsg, ier = lsout
   1074         result.aborted = self._abort

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
    385             maxfev = 200*(n + 1)
    386         retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 387                                  gtol, maxfev, epsfcn, factor, diag)
    388     else:
    389         if col_deriv:

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/lmfit/minimizer.py in __residual(self, fvars, apply_bounds_transformation)
    369 
    370         out = self.userfcn(params, *self.userargs, **self.userkws)
--> 371         out = _nan_policy(out, nan_policy=self.nan_policy)
    372 
    373         if callable(self.iter_cb):

/home/bprodz/.virtualenvs/phd_dev/lib/python3.5/site-packages/lmfit/minimizer.py in _nan_policy(a, nan_policy, handle_inf)
   1430 
   1431         if contains_nan:
-> 1432             raise ValueError("The input contains nan values")
   1433         return a
   1434 

ValueError: The input contains nan values

Однако результаты следующих проверок NaN подтверждают, что в моих данных не было значений NaN:

print(np.any(np.isnan(data)), np.any(np.isnan(time)))
False False

До сих пор я пытался преобразовать 1 и / или оба data и time из списков в numpy ndarrays, удалив 0-й временной шаг (в случае ошибки деления на 0), явно указав t как независимый и разрешив всем переменным быть отличаться. Однако все они вызывают одну и ту же ошибку.

У кого-нибудь есть идеи, что вызывает эту ошибку? Спасибо.


person Jason    schedule 18.08.2016    source источник
comment
Понятия не имею, почему это происходит, но если вы используете time = np.arange(.5,25.,.5), похоже, это сработает. В модели должна быть какая-то недопустимая операция с выбранными вами значениями времени.   -  person zarak    schedule 19.08.2016
comment
@zarak Вы еще что-нибудь меняли? У меня все еще та же ошибка .. Ура.   -  person Jason    schedule 19.08.2016
comment
Это странно. Я копирую и вставляю ваш код ровно до того места, где вы присвоили переменную time. Вы пробовали начать новую сессию? Возможно, какие-то переменные затеняются.   -  person zarak    schedule 19.08.2016
comment
@zarak Я начал новую сессию, и теперь она работает, спасибо. (Ядро перезапуска ноутбука jupyter, похоже, не очистило все) Я также попробовал np.arange(5., 25., 5.), если это было что-то связано с ints / floats, но оно выдало ту же ошибку, что и раньше. Я думаю, что буду продолжать попытки найти решение ... если это не удастся, возможно, мне придется изменить единицы во всех моих данных ...   -  person Jason    schedule 19.08.2016
comment
@zarak Вы попали в точку своим первым комментарием. Кажется, что где-то в моей модели есть ошибка, из-за которой некоторые отрицательные значения передаются в np.sqrt, который по умолчанию оценивает их как nan.   -  person Jason    schedule 19.08.2016
comment
Мой делал то же самое, пока я не добавил начальные догадки ... потом работал как по волшебству. Похоже, можно было бы выдать лучшую ошибку?   -  person David Hagan    schedule 27.04.2017


Ответы (1)


Я попытался подогнать под свою модель scipy.optimize.curve_fit и получил следующую ошибку:

/home/bprodz/.virtualenvs/phd_dev/lib/python3.4/site-packages/ipykernel/__main__.py:3: RuntimeWarning: invalid value encountered in sqrt
  app.launch_new_instance()

Это говорит о том, что проблема в моей модели, генерирующей отрицательные числа для np.sqrt(). По умолчанию для np.sqrt() при отрицательном числе выводится nan согласно этому вопросу. NB, np.sqrt может быть настроен так, чтобы вызывать ошибку, если задано отрицательное число, установив следующее: np.seterr(all='raise') источник

СОВЕТ. Я также попросил помощи в группе lmfit google и получил следующее полезный совет:

  • Рассмотрите возможность разбиения длинных формул на более мелкие части, чтобы упростить поиск и устранение неисправностей.
  • Используйте Model.eval(), чтобы проверить, какие параметры будут генерироваться при запуске функции модели.
  • np.ndarray обычно превосходит списки Python в этих (числовых) ситуациях.
person Jason    schedule 19.08.2016
comment
Большое спасибо за полезные советы и за дальнейшие действия! - person zarak; 19.08.2016