我试图在这个数据分布中拟合正弦波曲线,但由于某种原因,拟合是不正确的:
import matplotlib.pyplot as plt
import numpy as np
import scipy as sp
from scipy.optimize import curve_fit
#=======================
#====== Analysis =======
#=======================
# sine curve fit
def fit_Sin(t, A, b, C):
return A* np.sin(t*b) + C
## The Data extraciton
t,y,y1 = np.loadtxt("new10_CoCore_5to20_BL.txt", unpack=True)
xdata = t
popt, pcov = curve_fit(fit_Sin, t, y)
print "A = %s , b = %s, C = %s" % (popt[0], popt[1], popt[2])
#=======================
#====== Plotting =======
#=======================
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.plot(t, y, ".")
ax1.plot(t, fit_Sin(t, *popt))
plt.show()
这种拟合极其低估了数据。任何想法为什么会这样?
以下是此处提供的数据:https://www.dropbox.com/sh/72jnpkkk0jf3sjg/AAAb17JSPbqhQOWnI68xK7sMa?dl=0
知道为什么会这样做吗?
答案 0 :(得分:3)
如果您的频率猜测关闭,则正常波很难适应。这是因为在数据中有足够数量的周期时,猜测将与一半数据异相,并且即使频率中的小误差也与其一半同相。此时,直线提供比不同频率的正弦波更好的拟合。这就是傅立叶变换工作的方式。
我可以想出三种方法来很好地估计频率,以允许非线性最小二乘算法接管:
使用#1,我可以清楚地看到你的波长为50.因此b
的初始猜测应为2*np.pi/50
。另外,不要忘记添加相移参数以允许适合水平滑动:A*sin(b*t + d) + C
。
您需要通过p0
参数向curve_fit
传递初始猜测。良好的眼球估计是p0=(0.55, np.pi/25, 0.0, -np.pi/25*12.5)
。数据中的相移似乎是右边的四分之一周期,因此是12.5。
我目前正在编写一个算法,用于拟合嘈杂的正弦波,我将提交给SciPy。我完成后会更新。