Issue
I am trying to fit some (few) discrete experimental values with a custom model using the curve_fit package. The problem is I get the warning (?): “OptimizeWarning: Covariance of the parameters could not be estimated” and of course no reliable values for the parameters.
I read that this issue is consequence of the discrete nature of my dataset and that I could solve it using the LMFIT package. According to some examples I found, I should define a linear space and then assign my experimental values to the corresponding x points. Unfortunately this procedure would introduce too many errors due to the low number of points I have. So I wonder if there is a way to overcome this problem with the curve_fit package. I use it, inside the same code, to fit with exponential models other data (same number of elements) without any problem.
Thank you for any hints In details, reducing the code to the essential:
xa= array([0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.7, 0.72, 0.74, 0.76, 0.78, 0.8, 0.82], dtype=object)
ya= array([0.40168, 0.40103999999999995, 0.40027999999999997, 0.39936, 0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292, 0.39144, 0.38976, 0.38788, 0.38580000000000003, 0.38348], dtype=object)
from scipy.optimize import curve_fit
def fit_model(x, a, b):
return (1 + np.exp((a - 0.57)/b))/(1 + np.exp((a-x)/b))
popt_an, pcov_an = curve_fit(fit_model, xa, ya, maxfev=100000)
Solution
I would probably call your hardwired non-x-dependent factor its own variable (say, 'c') and use this:
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
xa = np.array([0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.7, 0.72, 0.74,
0.76, 0.78, 0.8, 0.82])
ya = np.array([0.40168, 0.40103999999999995, 0.40027999999999997, 0.39936,
0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292,
0.39144, 0.38976, 0.38788, 0.38580000000000003, 0.38348])
def modelfunc(x, a, b, c):
return (1 + c)/(1 + np.exp((a-x)/b))
my_model = Model(modelfunc)
params = my_model.make_params(a=1, b=-0.1, c=-0.5)
result = my_model.fit(ya, params, x=xa)
print(result.fit_report())
plt.plot(xa, ya, label='data')
plt.plot(xa, result.best_fit, label='fit')
plt.legend()
plt.show()
that will print out a report of
[[Model]]
Model(modelfunc)
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 29
# data points = 14
# variables = 3
chi-square = 7.6982e-10
reduced chi-square = 6.9984e-11
Akaike info crit = -324.734898
Bayesian info crit = -322.817726
[[Variables]]
a: 1.29660513 +/- 6.9684e-04 (0.05%) (init = 1)
b: -0.16527738 +/- 2.7098e-04 (0.16%) (init = -0.1)
c: -0.59507868 +/- 1.6502e-05 (0.00%) (init = -0.5)
[[Correlations]] (unreported correlations are < 0.100)
C(a, b) = -0.995
C(b, c) = -0.955
C(a, c) = 0.925
Answered By - M Newville
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.