简体   繁体   中英

scipy curve_fit doesn't work well

I am trying to fit some data using the following code:

import numpy as np
import scipy.optimize
import matplotlib.pyplot as plt

def fseries(x, a0, a1, b1, w):
    f = a0 + (a1 * np.cos(w * x)) + (b1 * np.sin(w * x))
    return f

x = np.arange(0, 10)
y = [-45.0, -17.0, -33.0,  50.0, 48.0,  -3.0,  -1.0,   2.0,  84.0, 71.0]

res = scipy.optimize.curve_fit(fseries, x, y, maxfev=10000)

xt = np.linspace(0, 10, 100)
yt = fseries(xt, res[0][0], res[0][1], res[0][2], res[0][3])

plt.plot(x,y)
plt.plot(xt, yt, 'r')
plt.show()

Which makes this plot:

在此处输入图片说明

Any thoughts on what I am not understanding or doing wrong?

First of all, curve fitting is not a magical device that creates a good curve for any given data set. You can't fit an exponential curve well to a logarithmic data set. If you look at your data, does it look like it is well described by the function you define? Doesn't it rather look like an overlay of a linear and a sine function?
Then curve fitting is an iterative process, that is highly dependent on start values. From the scipy manual :

p0 : None, scalar, or N-length sequence, optional Initial guess for the parameters. If None, then the initial values will all be 1

Why not provide a better guess for p0 ?
Last but not least, you get back two arrays. I would read out both, even if you only need one. It simplifies your code. Try

p0 = (10, 20, 20, 1.5)
res, _popcv = scipy.optimize.curve_fit(fseries, x, y, p0, maxfev=10000)
xt = np.linspace(0, 10, 100)
yt = fseries(xt, *res)

and you get already a better fit. 在此处输入图片说明
You can improve the fit further, when you define a better fit function with

def fseries(x, a0, a1, b1, w):
    f = a0 * x + (a1 * np.cos(w * x)) + (b1 * np.sin(w * x))
    return f

在此处输入图片说明

Whether this function is useful, you have to decide. Just because it fits better the data set, doesn't mean it is the right descriptor in your situation.

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