I have a general problem that I don't know how to navigate library modules to get the result that I want. Here is an example of what I mean: Let's say I use lmfit library to do a fitting of a function:
from lmfit import Model, Parameters
#importing data
x=[-1.5933, -1.58, -1.5667, -1.5533, -1.54, -1.5267, -1.5133, -1.5, -1.4867, -1.4733, -1.46, -1.4467, -1.4333, -1.42, -1.4067, -1.3933, -1.38, -1.3667, -1.3533, -1.34, -1.3267, -1.3133, -1.3, -1.2867, -1.2733, -1.26, -1.2467, -1.2333, -1.22, -1.2067, -1.1933, -1.18, -1.1667, -1.1533, -1.14, -1.1267, -1.1133, -1.1, -1.0867, -1.0733, -1.06, -1.0467, -1.0333, -1.02, -1.0067, -0.9933, -0.98, -0.9667, -0.9533, -0.94, -0.9267, -0.9133, -0.9, -0.8867, -0.8733, -0.86, -0.8467, -0.8333, -0.82, -0.8067, -0.7933, -0.78, -0.7667, -0.7533, -0.74, -0.7267, -0.7133, -0.7, -0.6867, -0.6733, -0.66, -0.6467, -0.6333, -0.62, -0.6067, -0.5933, -0.58, -0.5667, -0.5533, -0.54, -0.5267, -0.5133, -0.5, -0.4867, -0.4733, -0.46, -0.4467, -0.4333, -0.42, -0.4067]
y=[0.0205, 0.0197, 0.0214, 0.0144, 0.0159, 0.0129, 0.0105, 0.0116, 0.0105, 0.0088, 0.0094, 0.0114, 0.009, 0.0102, 0.0099, 0.009, 0.0102, 0.0114, 0.0127, 0.011, 0.0134, 0.0143, 0.019, 0.0215, 0.0272, 0.0245, 0.0341, 0.0379, 0.0436, 0.0504, 0.0607, 0.0744, 0.0793, 0.0834, 0.1061, 0.1202, 0.1339, 0.1357, 0.1751, 0.1773, 0.1738, 0.1885, 0.201, 0.1995, 0.2058, 0.2039, 0.1893, 0.1856, 0.1693, 0.16, 0.1486, 0.1212, 0.1118, 0.0928, 0.0879, 0.0655, 0.0505, 0.0465, 0.039, 0.0308, 0.0304, 0.0259, 0.0221, 0.0205, 0.0212, 0.0196, 0.017, 0.0148, 0.0159, 0.0181, 0.0172, 0.0183, 0.0156, 0.0165, 0.0163, 0.0186, 0.0136, 0.0129, 0.0143, 0.0125, 0.0142, 0.0096, 0.0111, 0.0136, 0.0101, 0.0106, 0.009, 0.0094, 0.0079, 0.0081]
#creating params object from Parameters class
params=Parameters()
#writing initial parameters
params.add('a', value=-2.8e-04)
params.add('b', value=0.003)
params.add('int', value=0.2, min=0.01)
params.add('pos', value=-1, min=-1.2, max=0.8)
params.add('G', value=0.05, min = 0.005, max=0.5)
def gaussian(x, int1, pos1, G1):
return int1*exp(-(x-pos1)**2/G1**2)
model = Model(gaussian)
result = model.fit(y, params, x=x)
print(result.fit_report())
Now, if I want to specifically select one of the standard errors of the best fit results, I would do something like this:
result.params['a'].stderr
I know this is correct as I have tried it and it works, but I don't know how I can conclude this myself by reading the original library code. In the example above, is "result" an object of the Model class? Is stderr an attribute?
Thank you!
CodePudding user response:
When you do
from lmfit import Model
mymodel = Model(gaussian)
then mymodel
is an instance of an lmfit.Model
. This object has a method called fit
. When you run that with
result = mymodel.fit(y, params, x=x)
then result
is the value returned by Model.fit
. For lmfit.Model.fit
, that return object is an instance of an lmfit.model.ModelResult
. In Python, you cannot really know what the object returned by any method will be except by a) running the method and inspecting the results, or b) reading the actual documentation for that method and seeing what it promises the return object will be and trusting that documentation and trusting that you did not get some exception raised while running that method.
The lmfit documentation for Model.fit
does say and point to the return value will be a ModelResult
. It lists a pile of methods and attributes that this object will have. You can also inspect all of this yourself at runtime with type(result)
and dir(result)
, which answer the questions of "what kind of thing is result
?" and "what things does this result
have?".
For a ModelResult
, one of the attributes it has is params
which is an lmfit.Parameters
object -- essentially a dictionary ( a bit more that is not super-relevant here) with keys being "names of fitting parameters" and values being "fitting parameter objects". This will match very closely the params
you passed in (which is also an instance of lmfit.Parameters
) but will have values and attributes updated to reflect the result of running the fit method
-- the output Parameters. So
result.params['a']
is a lmfit Parameter
, representing one of the values varied in a fit (though your model would not really have a Parameter named a
, it would have Parameters with names int1
, pos1
, and G1
). This lmfit.Parameter
object will have several attributes: value
for the parameter value (for the fit result, this will be the best-fit value), stderr
with an estimate of the standard error, and several other attributes. As before, you can read the documentation for what those attributes are or explore this and any other object with dir()
.
None of this is particular to lmfit
, it is just how Python works. Everything is an object, some are "standard types", some are custom-built, some are simple, and some are complicated. Objects have attributes (other objects). Some of those attributes are callable, and then called "methods". Running methods will return other objects, though some return None
which is kind of like not returning anything at all.