【问题标题】:ValueError: The input contains nan values - from lmfit model despite the input not containing NaNsValueError:输入包含 nan 值 - 尽管输入不包含 NaN,但来自 lmfit 模型
【发布时间】:2016-08-18 20:54:49
【问题描述】:

我正在尝试使用 lmfit (link to docs) 构建模型,但我似乎无法找出为什么我在尝试拟合模型时不断得到 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 和/或 datatime 转换为 numpy ndarrays,删除第 0 个时间步(以防除以 0 错误),明确指定t 是独立的并允许所有变量变化。然而,这些都抛出相同的错误。

有没有人知道是什么导致了这个错误被抛出?谢谢。

【问题讨论】:

  • 我不知道为什么会这样,但如果你使用time = np.arange(.5,25.,.5),它似乎可以工作。使用您选择的时间值的模型中一定存在某种非法操作。
  • @zarak 你还有什么改变吗?我仍然遇到同样的错误.. 干杯。
  • 这很奇怪。我将您的代码完全复制并粘贴到您分配time 变量的位置。您是否尝试过从新的会话开始?也许有些变量被遮蔽了。
  • @zarak 我开始了一个新会话,现在它正在工作,谢谢。 (jupyter notebook 的重启内核似​​乎并没有清除所有内容)我也尝试了np.arange(5., 25., 5.),以防它与 ints/floats 有关,但它抛出了与以前相同的错误。我想我会继续努力寻找解决方案......失败了,也许我需要在我的数据中更改单位......
  • @zarak 你的第一条评论一针见血。我的模型中似乎有一个错误,导致一些负值被传递给np.sqrt,默认情况下将它们评估为nan

标签: python lmfit


【解决方案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 as per this question. 注意,如果给定负数,np.sqrt 可以设置为引发错误,设置如下:np.seterr(all='raise')source

TIP 我也在 lmfit google 群里求助,收到了以下helpful advice

  • 考虑将长公式拆分成更小的部分,以便更轻松地进行故障排除
  • 使用Model.eval() 测试通过模型函数运行时某些参数会产生什么
  • 在这些(数字)情况下,np.ndarray 通常优于 python 列表

【讨论】:

  • 非常感谢您提供有用的提示和跟进!
猜你喜欢
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 2021-04-19
  • 2020-11-03
  • 1970-01-01
  • 2019-10-12
相关资源
最近更新 更多