8

我正在尝试使用 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 和/或两者datatime列表转换为numpy ndarrays,删除第 0 个时间步(以防除以 0 错误),明确指定t为独立并允许所有变量变化。然而,这些都抛出相同的错误。

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

4

1 回答 1

3

我尝试使用适合我的模型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 根据此问题输出。注意 np.sqrt 可以设置为如果给定负数设置以下内容时引发错误:np.seterr(all='raise') source

提示 我还在 lmfit google 小组中寻求帮助,并收到了以下有用的建议

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