I want to fit a random time series segment to a predefined list of functions. For demo purposes, I only use the sine function and a demo time series.
amplitude = 1
omega = 2
phase = 0.5
offset = 4
def sine(x, a, b, c, d):
"""Sine function"""
return a*np.sin(b*x+c) + d
x = np.linspace(0,100, 1000)
parameters = [amplitude, omega, phase, offset]
demo_values = sine(x, *parameters)
As mentioned in the title I make use of the scipy.optimize.curve_fit
method to try to find the parameters, as such:
from scipy.optimize import curve_fit
popt, err = curve_fit(f=sine, xdata=x, ydata=demo_values)
fitted = sine(x, *popt)
When comparing the curve-fitted parameters with the original parameters I find them to be quite different. I do not know what I am doing wrong.
print(f"Scipy params: {popt}")
print(f"Original params: {parameters}")
>>> Scipy params: [0.02834886 1.15624779 1.8580548 4.00011998]
>>> Original params: [1, 2, 0.5, 4]
NB. As mentioned in the introduction I do not want to find a solution for only the sine function, as I would like to extend this flow for other functions as well. I have seen on SO that using the p0 variable significantly increases the accuracy, but I do not know how to make an initial guess in a generic way (for any curve).
I tried to curve fit a simple Sine curve with the
scipy.optimize.curve_fit
function and expected the library to handle that quite nicely. Unfortunately, that was not the case. I have also seen that other posts related to my question use a p0 (initial guess) variable, which I don't know how to create for a generic curve.