简体   繁体   English

正弦曲线拟合问题:幅度和频率出来的太低

[英]Problems with sinusoidal curve fitting: amplitude and frequency come out too low

数据

I have some time series data, which corresponds to the black line in the image (it's a rolling mean).我有一些时间序列数据,它对应于图像中的黑线(它是滚动平均值)。 I am trying to fit a sinusoidal curve to it with no success;我试图拟合正弦曲线但没有成功; the light blue, almost straight line is the current result.浅蓝色,几乎直线是当前的结果。 (The dark blue one is a polynomial fit, disregard it for now). (深蓝色的是多项式拟合,暂时忽略它)。

What I tried is this.我试过的是这个。 I got the idea for the function from here.我从 这里得到了这个功能的想法

def objective(x, a, b, c, d):
    return a * np.sin(b - x) + c * x**2 + d

[..] [..]

from scipy import optimize

X = X.ravel() # 1D array of ordinal dates
y = y.ravel() # 1D array of temperature values

# Curvefit with the objective function.
params, _ = optimize.curve_fit(objective, X, y)

# Plot the curvefit
plt.plot(X_extended, objective(
    X, params[0], params[1], params[2], params[3]))

Even if I add guesses with very low frequencies or very high amplitudes, barely anything changes.即使我添加了非常低的频率或非常高的振幅的猜测,也几乎没有任何变化。

Any idea is appreciated.任何想法表示赞赏。 If necessary, I can try to reproduce the issue elsewhere.如有必要,我可以尝试在其他地方重现该问题。


Applying the p0 values and function that were given in the answer, the graph now looks like this:应用答案中给出的 p0 值和函数,图形现在如下所示:

新拟合的函数

Thank you!谢谢!

Without data to test, it's hard to tell exactly.没有要测试的数据,很难准确判断。 However, a good guess is that your starting parameters are off, and then a generalised least squares fit can (easily) fail.但是,一个很好的猜测是您的起始参数已关闭,然后广义最小二乘拟合可能(很容易)失败。 You're not even giving curve_fit an initial set of parameters, so the initial starting of a , b , c and d will all be set to 1.您甚至没有给curve_fit一组初始参数,因此abcd的初始起始值都将设置为 1。

Dealing with only the sinusoidal fit, for your amplitude a , you'll probably want something around 7, and for the offset d , about 27. b is harder to guess, so can be left at 0 (or 1) initially.处理正弦拟合,对于幅度a ,您可能需要大约 7 ,而对于偏移d ,大约为 27。 b更难猜测,因此最初可以保留为 0(或 1)。

But, the quadratic part of the equation will make a mess of things: the x-values are large, so it will change very fast, or rather, c should be very close to zero (close, as in very small, of order 1/x^2 , so say ~ 1e-12 , to cancel out the effects of the large quadratic variations. Any such small number will have problems fitting as well: normalising your formula / parameters (to be of order 1) beforehand is always a good idea.但是,方程的二次部分会使事情变得一团糟:x 值很大,所以它会变化得非常快,或者更确切地说, c应该非常接近于零(接近于1/x^2 , 所以说~ 1e-12 , 以抵消大二次变化的影响. 任何这样小的数字也会有拟合问题:事先规范化你的公式/参数(为 1 级)总是一个好主意。

In fact, I don't understand why you have a quadratic in your function.事实上,我不明白为什么你的函数中有二次方。 Perhaps it's the underlying model that requires this, but the figure itself shows no indication at all of quadratic behaviour.也许是底层模型需要这样做,但数字本身根本没有显示二次行为的迹象。 I would remove it.我会删除它。

Finally, while you have an x-offset b , you don't have a parameter for your the period.最后,虽然您有 x-offset b ,但您没有周期参数。 As a result, it will be fixed at 2π, which it is definitely not.结果,它会固定在 2π,而这绝对不是。 This will be the biggest hurdle in fitting your data, next to the quadratic part of the equation.这将是拟合数据的最大障碍,仅次于方程的二次部分。 The period looks to be around 300 (or one year?), or roughly 50 * 2π.该周期看起来大约是 300(或一年?),或大约 50 * 2π。

So, try with the following function:因此,请尝试使用以下功能:

def objective(x, a, b, c, d):
    return a * np.sin(b - c*x/50) + d

with starting parameters of, very roughly:具有非常粗略的起始参数:

p0 = [7, 0, 1, 27]

and see what you get.看看你得到了什么。

(If you are wondering about the 50 in the formula: it's not really necessary at these orders of magnitude, but it servers as an example of normalising c to be of order 1. You could so the same for d by replacing it with 10*d and then set its initial guess at 3. Or, if you do that, you can now leave out p0 entirely, with all parameter guesses at 1.) (如果您想知道公式中的 50:在这些数量级上并不是真的有必要,但它作为将c规范化为 1 阶的示例。您可以将d替换为10*d然后将其初始猜测设置为 3。或者,如果你这样做,你现在可以完全省略p0 ,所有参数猜测都为 1。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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