简体   繁体   中英

why am I getting OptimizeError while trying to fit a gaussian/lorentzian to data using curve_fit?

I am trying to fit a data set which may fit a gaussian or lorentzian, with scipy optimize curve_fit function. I am getting the error: "OptimizeWarning: Covariance of the parameters could not be estimated warnings.warn('Covariance of the parameters could not be estimated'," the data set looks like this: enter image description here

which , as you can see, may fit a gaussian. my code is :

def gaussian(x,a,b,c,d):
    func=a*np.exp(-((x-b)**2)/c)+d
    return func
def lorentzian (x,a,b,c):
    func=a/(((x-b)**2+a**2)*np.pi)+c
    return func

x,y_data= np. loadtxt('in 0.6 out 0.6.dat', unpack = True)

popt, pcov = curve_fit(lorentzian, x, y_data)

thank you!

You're getting this error because the fitting algorithm couldn't find an appropriate solution. No matter where it moved the parameters, the fit quality didn't change. If you provide an initial guess, you're more likely to reach the solution. Given that the function parameters are relatively easily obtained from glancing the curves, you could provide most of them. For example, the center (which you called a ) is around 545.5. Wikipedia also has a relationship for the value at the maximum for a slightly different form of your equation, which lacks the c parameter to shift the curve upwards. Providing the guess p0 = (0.1, 545.5, 0) and a bound of (0, 1E10) you get something much closer to your results, yet still unsatisfactory (next time, provide the data array, I had to use a point extractor to plot this)

在此处输入图像描述

Now, notice how you're supposed to reach a maximum value of 40, yet that seems unattainable by your model. I took the liberty of normalizing your model simply by dividing it by its maximum value and trying to fit again. I don't know if this is the appropriate normalization, but this is just to illustrate the difference. This time, the result is much more satisfactory:

在此处输入图像描述

Yet I think a lorentzian is a bit too narrow for your curve (especially evident if you set c to 0), which looks much more like a gaussian (given you provided its definition but didn't use it, I guess you probably would have used it in the future).

在此处输入图像描述

Note how I didn't have to normalize y .

In summary:

  1. Provide an initial guess to your fitting algorithm, and bounds if possible.
  2. Always plot your models and data to see what's going on.
  3. Be aware of the limits of your models, what values it can or can't reach. Use this to evaluate if a fit is even possible in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM