简体   繁体   中英

Exponential decay curve fitting with scipy.optimize

I am trying to fit a curve with the curve_fit function in SciPy. By changing the inital values of the model the quality of the fit is changing but I am not able to find the best fit through my data. Here is how my fit looks like

在此处输入图像描述

My question is how can I improve this fit and what is the best way of selecting the initial values of the model. I have attached the raw data which I want to fit an exponential curve to it.

This is the data which I am using

y = [ 338.52656636  337.43934446  348.25434126  308.42768639  279.24436171
  269.85992004  279.24436171  249.25992615  239.53215125  219.96215705
  220.41993469  220.30549028  220.30549028  195.07049776  180.364391
  171.20883816  180.24994659  180.13550218  180.47883541  209.89104892
  220.19104587  180.02105777  595.45426801  324.50712607  150.60884426
  170.97994934  171.20883816  170.75106052  170.75106052  159.76439711
  140.88106937  150.37995544  140.88106937 1620.70451979  140.42329173
  150.37995544  140.53773614  284.68047121 1146.84743797  170.97994934
  150.60884426  145.74495682  141.10995819  121.53996399  121.19663076
  131.38218329  170.40772729  140.42329173  140.82384716  145.5732902
  140.30884732  121.53996399  700.39979247 2783.74584185  131.26773888
  140.76662496  140.53773614  121.76885281  126.23218482  130.69551683]

and here is my code:

from numpy import arange
from pandas import read_csv
from scipy.optimize import curve_fit
from matplotlib import pyplot


def expDecay(t, Amax, tau):
    return Amax/tau*np.exp(-t/tau)

Amax = []
Tau = []

ydata = y
x = array(range(len(y)))
xdata = x


popt, pcov = curve_fit(expDecay, x, y,
                           p0=(10000, 5),
                           bounds=([0., 2.], [10000., 30]),)
Amax.append(popt[0])
Tau.append(popt[1])


plt.plot(xdata, expDecay(xdata, *popt), 'k-', label='Pred.');
plt.plot(ydata);
plt.ylim([0, 500])   
plt.show()

The deviation is due to the outliers. After eliminating them:

在此处输入图像描述

Note about eliminating the outliers.

Since the definition of outlier is subjective a software able to do this will probably be more or less interactive. I built my own very rudimentary software. The principle is:

A first nonlinear regression is done with all the points. With the function and parameters obtained the values of y are computed for each point. The absolute difference between the "y computed" and the "y values" from the given data file are compared. This allows to eliminate the point the further away.

Another nonlinear regression is done with the remaining points. The same procedure eliminates a second point.

And so on until a specified criteria be reached to stop. That is the subjective part.

With your data (60 points) the point n.54 was eliminated first. Then the point n.34, then n.39 and so on. The process stops after eliminating 6 points. Eliminating more points doesn't improve much the LMSE.

The curve above is the result of the last nonlinear regression with the 54 remaining points.

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