简体   繁体   中英

Using scipy curve_fit to fit exponential curve (fitted curve does match real curve)

I'm trying to fit an exponential curve using curve_fit (scipy.optimize) but the fitted curve looks nowhere like the real curve. Right now I'm using the following code:

X=[0.0, 9.0, 18.0, 27.0, 36.0, 45.0, 54.0]
Y=[0.090316199, -0.078157925, -0.350137315, -0.695193468, -1.106773689, -1.60467115, -2.196169408]

#plot Y against X
fig = plt.figure(num=None, figsize=(9, 7),facecolor='w', edgecolor='k')
ax=fig.add_subplot(111)
ax.scatter(X,Y)

#fit using curve_fit
popt, pcov = curve_fit(func, X, Y,maxfev=10000)

#compute Y_estiamted using fitted parameters 
Y_estimated=[popt[0]*np.exp(i+popt[1])+popt[2] for i in X]

#plot Y_estiamted against X
ax.scatter(X,Y_estimated, c='r')

def func(x,a,b,c):
    return a*(np.exp(x+b))+c

The blue curve is the real curve and the red curve is the fitted curve.

在此处输入图片说明

As you can see the fitted red curve does not match the real blue curve at all. Any help would be appreciated!

i think the problem is the model function. If you change this to a function like:

def func(x, a, b, c, d):
    return a * (np.exp(d*(x + b))) + c

then it finds a nice fit: 在此处输入图片说明

i changed a few things in the code:

def func(x, a, b, c, d):
    return a * (np.exp(d*(x + b))) + c


X = [0.0, 9.0, 18.0, 27.0, 36.0, 45.0, 54.0]
Y = [0.090316199, -0.078157925, -0.350137315, -0.695193468, -1.106773689, -1.60467115, -2.196169408]


# plot Y against X
fig = plt.figure(num=None, figsize=(9, 7), facecolor='w', edgecolor='k')
ax = fig.add_subplot(111)
ax.scatter(X, Y)

# fit using curve_fit
popt, pcov = curve_fit(func, X, Y, maxfev=10000)

# compute Y_estiamted using fitted parameters
x = np.linspace(min(X), max(X), 100)
Y_estimated = func(x, *popt)

# plot Y_estiamted against X
ax.plot(x, Y_estimated, c='r')

I got a fairly good fit to an asymptotic exponential type of equation that has a single shape parameter and a small offset, "1.0 - pow(a, x) + b". Here is a graphical Python fitter using this equation with your data.

阴谋

import numpy, scipy, matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# ignore warnings within curve_fit() routine
import warnings
warnings.filterwarnings("ignore")

X=[0.0, 9.0, 18.0, 27.0, 36.0, 45.0, 54.0]
Y=[0.090316199, -0.078157925, -0.350137315, -0.695193468, -1.106773689, -1.60467115, -2.196169408]

# alias data to match previous example
xData = numpy.array(X, dtype=float)
yData = numpy.array(Y, dtype=float)

def func(x, a, b): # Asymptotic Exponential A equation with offset from zunzun.com
    return 1.0 - numpy.power(a, x) + b

# these are the same as the scipy defaults
initialParameters = numpy.array([1.0, 1.0])

# curve fit the test data
fittedParameters, pcov = curve_fit(func, xData, yData, initialParameters)

modelPredictions = func(xData, *fittedParameters) 

absError = modelPredictions - yData

SE = numpy.square(absError) # squared errors
MSE = numpy.mean(SE) # mean squared errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(yData))

print('Parameters:', fittedParameters)
print('RMSE:', RMSE)
print('R-squared:', Rsquared)

print()


##########################################################
# graphics output section
def ModelAndScatterPlot(graphWidth, graphHeight):
    f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
    axes = f.add_subplot(111)

    # first the raw data as a scatter plot
    axes.plot(xData, yData,  'D')

    # create data for the fitted equation plot
    xModel = numpy.linspace(min(xData), max(xData))
    yModel = func(xModel, *fittedParameters)

    # now the model as a line plot
    axes.plot(xModel, yModel)

    axes.set_xlabel('X Data') # X axis data label
    axes.set_ylabel('Y Data') # Y axis data label

    plt.show()
    plt.close('all') # clean up after using pyplot

graphWidth = 800
graphHeight = 600
ModelAndScatterPlot(graphWidth, graphHeight)

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