Using the Model.fit method on my model produces `ValueError: The input contains nan values`

2,121 views
Skip to first unread message

Dave

unread,
Aug 19, 2016, 2:56:17 AM8/19/16
to lmfit-py
Hi, I'm trying to fit a model using the lmfit.Model object and its .fit() method. However I get `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)


Full traceback:

---------------------------------------------------------------------------
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


I've checked for NaNs using:

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

So far I've tried converting 1 and/or both of data and time from lists to numpy ndarrays, removing the 0th time step (in case there was a dividing by 0 error), explicitly specifying the t as being independent and allowing all variables to vary. However the same error is thrown. The only way I've been able to get the `.fit()` to run is by changing 'time' to `time = np.arange(.5, 25., .5)` as per [this comment](http://stackoverflow.com/questions/39027346/valueerror-the-input-contains-nan-values-from-lmfit-model-despite-the-input-n#comment65406383_39027346) on StackOverflow. Does anybody have any suggestions as to what could be causing my problem? Thanks in advance!

Matt Newville

unread,
Aug 19, 2016, 9:51:38 AM8/19/16
to lmfit-py
Hi Dave,

Those are all good things to try.  I'll make a few suggestions:
   1. using ndarrays instead of lists is *always* better.   lmfit will try to auto-convert, and that's clearly working for your data, but ndarrays are really different from python lists -- they have a homogeneous type for each element.  lmfit and the underlying scipy code really, really needs to use ndarrays.
   2. your model function is  kind of a mess.   This is a problem because it makes it very hard to understand what it is actually calculating.  Break it up into smaller components that each fit on one line and combine those.   This is not just cosmetic, it is important to being able to diagnose your problem.
   3. When you find yourself having parameter values with magnitudes larger than 1e6 or smaller than 1e-6, definitely change the scale to be closer to 1 and add a constant scaling in your model or objective function.

It seems that NaNs are being generated in your model function.  This may not be too surprising as it looks like you're doing a lot of dividing and exponentiation of values with different scales, and taking sqrt() of unbound parameters.  The minimization routine is free to try any value for the parameters, and perhaps some values are causing NaNs (say, negative values for the parameters that are inside sqrt()).

I would suggest trying to simply evaluate the model with various parameter values, using `Model.eval()`.   With the model broken into smaller chunks (step 2 above), you can print out the partial results and see where the NaN is coming from.   You can also print out the partial results during the fit.

Finally, but as a last resort, you can specify `nan_policy` in `Model.fit`, for example `nan_policy=omit` will remove NaNs in the residual, and should then run to completion.  But it is certainly better to figure out why this is happening than to just suppress the cases where it does happen.
 
--Matt

Dave

unread,
Aug 19, 2016, 12:04:53 PM8/19/16
to lmfit-py, newv...@cars.uchicago.edu
Hi Matt,

Thanks a lot for your help! I'll make the changes you suggested and update.

I was actually coming back to add that since posting I'd tried running the model through scipy.optimize.curve.fit() (in an .ipynb session) and I got:

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


So it looks like the problem is indeed with my model function. According to this question on StackOverflow np.sqrt will return NaN (or rather 'nan') by default in cases where it's given negative number (numpy can be set to raise an error instead using np.seterr(all='raise') ).

Thanks for the tips especially regarding rewriting my function in manageable pieces and using Model.eval() to test certain case, these will definitely be very useful for auditing my changes and writing tests in future! Also didn't know about the differences advantages of using np.ndarrays (of to read up on this!).

Thanks again!
Dave. 

Anusha Kodimela

unread,
Aug 24, 2018, 4:25:44 PM8/24/18
to lmfit-py
Hello Matt!

I am facing the same issue with my model which is not much complex than the one mentioned in this post.Would the exponent in the model cause the issue?I have tried to find the issue in google before asking it here,but the google itself has directed me to this group.Can we do set parameter hint for an independent variable to eliminate the error?

import matplotlib.pyplot as plt
import pandas as pd
from lmfit import Model
import numpy as np


def ssexp_if(x, a, b, c):
arg = (b * x) ** c
return a * np.exp(-2 * arg)


gmodel = Model(ssexp_if)
params = gmodel.make_params(a=14.5, b=-3, c=1)

datafile = pd.read_excel(r'C:\Users\Desktop\Trial10.xls')
x = datafile.iloc[ :20 , 0]

y = gmodel.eval(params, x=x, nan_policy='omit')
print(pd.isnull(x))
result = gmodel.fit(y, params, x=x)
pandas.isnull()
print(result.fit_report())

plt.plot(x, y, 'bo')
plt.plot(x, result.init_fit, 'k--')
plt.plot(x, result.best_fit, 'r-')
plt.show()

values of x from the excel:
3.750000e-08
5.000000e-08
6.250000e-08
7.500000e-08
8.750000e-08
1.000000e-07
1.125000e-07
1.250000e-07
1.375000e-07
1.500000e-07
1.625000e-07
1.750000e-07
1.875000e-07
2.000000e-07
2.250000e-07
2.500000e-07
2.750000e-07
3.000000e-07
3.250000e-07
3.500000e-07
3.500000e-07

error:
0     False
Traceback (most recent call last):
1     False
  File "C:/Users/PycharmProjects/CurveFitting_Python/CurveFitting_Lmfit.py", line 20, in <module>
2     False
    result = gmodel.fit(y, params, x=x)
3     False
4     False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\lmfit\model.py", line 873, in fit
5     False
    output.fit(data=data, weights=weights)
6     False
7     False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\lmfit\model.py", line 1217, in fit
8     False
    _ret = self.minimize(method=self.method)
9     False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\lmfit\minimizer.py", line 1811, in minimize
10    False
    return function(**kwargs)
11    False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\lmfit\minimizer.py", line 1364, in leastsq
12    False
    lsout = scipy_leastsq(self.__residual, variables, **lskws)
13    False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\scipy\optimize\minpack.py", line 394, in leastsq
14    False
    gtol, maxfev, epsfcn, factor, diag)
15    False
16    False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\lmfit\minimizer.py", line 517, in __residual
17    False
    nan_policy=self.nan_policy)
18    False
  File "C:\Users\PycharmProjects\CurveFitting_Python\venv\lib\site-packages\lmfit\minimizer.py", line 2021, in _nan_policy
19    False
    raise ValueError("The input contains nan values")
Name: 2.5e-08, dtype: bool
ValueError: The input contains nan values

Matt Newville

unread,
Aug 24, 2018, 6:38:21 PM8/24/18
to lmfit-py
Anusha,

On Fri, Aug 24, 2018 at 3:25 PM Anusha Kodimela <anushak...@gmail.com> wrote:
Hello Matt!

I am facing the same issue with my model which is not much complex than the one mentioned in this post.
 

You are facing the same issue as someone else experienced 2 years ago?  What do you mean by that?     

Is it just that you are getting messages about NaNs?   That seems to be a common problem that many people ask about.

Would the exponent in the model cause the issue?

Maybe.  Exponentials can certainly give Inf, which is going to cause similar problems.

I have tried to find the issue in google before asking it here,but the google itself has directed me to this group.Can we do set parameter hint for an independent variable to eliminate the error?

No, independent variables do not have any attributes such as hints.  You can set hints for parameters for a Model, or place bounds on Parameters.

Since you are responding to a two-year-old thread, I would have assumed you had read the advice given there, specifically:

       I would suggest trying to simply evaluate the model with various parameter values, using `Model.eval()`.  

But I am not at all confident that you did, so I will repeat myself:   If you have not done so already, trying evaluating your model function with various inputs that you think are reasonable and plot the results to get a rough comparison with the data you are trying to fit.  

And again, as I said earlier, you can use `nan_policy='omit'`.  Weirdly, you used this is `Model.eval()` but not in `Model.fit()`.  

If you are still getting NaNs from your model function, figure out where they are coming from and get rid of them.  

Please read the docs and examples.

--Matt 

Reply all
Reply to author
Forward
0 new messages