如何使用pylab和numpy将正弦曲线拟合到我的数据? [英] How do I fit a sine curve to my data with pylab and numpy?

查看:68
本文介绍了如何使用pylab和numpy将正弦曲线拟合到我的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于一个学校项目,我试图证明经济遵循相对正弦曲线的增长方式.除了公认的狡猾之外,我还建立了一个python模拟程序,以显示即使我们让某种程度的随机性成立,我们仍然可以产生相对正弦的东西.我对自己生成的数据感到满意,但现在我想找到某种方法来获取与数据非常匹配的正弦图.我知道您可以进行多项式拟合,但是您可以进行正弦拟合吗?

For a school project I am trying to show that economies follow a relatively sinusoidal growth pattern. Beyond the economics of it, which are admittedly dodgy, I am building a python simulation to show that even when we let some degree of randomness take hold, we can still produce something relatively sinusoidal. I am happy with my data that I'm producing but now Id like to find some way to get a sine graph that pretty closely matches the data. I know you can do polynomial fit, but can you do sine fit?

非常感谢您的帮助.让我知道您是否想查看代码的任何部分.

Thanks for your help in advance. Let me know if there's any parts of the code you want to see.

推荐答案

您可以使用

You can use the least-square optimization function in scipy to fit any arbitrary function to another. In case of fitting a sin function, the 3 parameters to fit are the offset ('a'), amplitude ('b') and the phase ('c').

只要您对参数进行合理的初次猜测,优化就可以很好地收敛.幸运的是,对于正弦函数,可以很容易地对其中的2个进行初次估算:可以通过取数据的均值来估算偏移量.幅度通过RMS(3 *标准偏差/sqrt(2)).

As long as you provide a reasonable first guess of the parameters, the optimization should converge well.Fortunately for a sine function, first estimates of 2 of these are easy: the offset can be estimated by taking the mean of the data and the amplitude via the RMS (3*standard deviation/sqrt(2)).

注意:作为以后的编辑,还添加了频率拟合.这不能很好地工作(可能导致极差的拟合).因此,根据您的判断,我的建议是除非频率误差小于百分之几,否则不要使用频率拟合.

Note: as a later edit, frequency fitting has also been added. This does not work very well (can lead to extremely poor fits). Thus, use at your discretion, my advise would be to not use frequency fitting unless frequency error is smaller than a few percent.

这将导致以下代码:

import numpy as np
from scipy.optimize import leastsq
import pylab as plt

N = 1000 # number of data points
t = np.linspace(0, 4*np.pi, N)
f = 1.15247 # Optional!! Advised not to use
data = 3.0*np.sin(f*t+0.001) + 0.5 + np.random.randn(N) # create artificial data with noise

guess_mean = np.mean(data)
guess_std = 3*np.std(data)/(2**0.5)/(2**0.5)
guess_phase = 0
guess_freq = 1
guess_amp = 1

# we'll use this to plot our first estimate. This might already be good enough for you
data_first_guess = guess_std*np.sin(t+guess_phase) + guess_mean

# Define the function to optimize, in this case, we want to minimize the difference
# between the actual data and our "guessed" parameters
optimize_func = lambda x: x[0]*np.sin(x[1]*t+x[2]) + x[3] - data
est_amp, est_freq, est_phase, est_mean = leastsq(optimize_func, [guess_amp, guess_freq, guess_phase, guess_mean])[0]

# recreate the fitted curve using the optimized parameters
data_fit = est_amp*np.sin(est_freq*t+est_phase) + est_mean

# recreate the fitted curve using the optimized parameters

fine_t = np.arange(0,max(t),0.1)
data_fit=est_amp*np.sin(est_freq*fine_t+est_phase)+est_mean

plt.plot(t, data, '.')
plt.plot(t, data_first_guess, label='first guess')
plt.plot(fine_t, data_fit, label='after fitting')
plt.legend()
plt.show()

我假设您知道正弦波的周期数.如果您不这样做,则安装起来会有些棘手.您可以通过手动绘制来尝试猜测周期数,并尝试将其作为第6个参数进行优化.

I assumed that you know the number of periods in the sine-wave. If you don't, it's somewhat trickier to fit. You can try and guess the number of periods by manual plotting and try and optimize it as your 6th parameter.

这篇关于如何使用pylab和numpy将正弦曲线拟合到我的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆