Python-曲线拟合产生不正确的拟合

Python-曲线拟合产生不正确的拟合,python,numpy,scipy,curve-fitting,Python,Numpy,Scipy,Curve Fitting,我试图拟合此数据分布的正弦波曲线,但由于某些原因,拟合不正确: 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

我试图拟合此数据分布的正弦波曲线,但由于某些原因,拟合不正确:

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()

在这种情况下,这种拟合使得对数据的估计极为低估。你知道为什么吗

以下是此处提供的数据:


你知道这是为什么吗?

如果你对频率的猜测是错的,正弦波很难拟合。这是因为,如果数据中有足够数量的周期,猜测将与一半的数据不同步,而与一半的数据同相,即使是频率上的一个小错误。在这一点上,直线比不同频率的正弦波更适合。顺便说一下,这就是傅里叶变换的工作原理

我可以想出三种方法来充分估计频率,以允许非线性最小二乘算法接管:

  • 盯着它看。减去GUI甚至命令行中两个峰值的x值。如果您有非常低的噪声数据,则可以非常轻松地自动化此过程
  • 使用离散傅里叶变换。如果数据是一个分量的正弦波,则第一个非恒定峰值将给出频率。我发现这需要一些额外的调整,因为采样频率通常不是正弦波频率的倍数。在这种情况下,抛物线拟合峰值周围的三个点(包括峰值在内的三个点)会有所帮助
  • 查找数据穿过垂直偏移的位置。这类似于#1,但对于相对无噪声的数据更易于自动化。波长是一对交点之间距离的两倍 使用#1,我可以清楚地看到你的波长是50。因此,
    b
    的初始猜测应该是
    2*np.pi/50
    。另外,不要忘记添加相移参数以允许拟合水平滑动:
    a*sin(b*t+d)+C

    您需要通过
    p0
    参数将初始猜测传递到
    curve\u fit
    。一个好的眼球估计值是
    p0=(0.55,np.pi/25,0.0,-np.pi/25*12.5)
    。数据中的相移似乎是向右的四分之一周期,因此为12.5


    我目前正在编写一个算法,用一个单一的频率分量拟合嘈杂的正弦波,我将提交给SciPy。将在我完成时更新

    我已经成功地使用遗传算法来提供初始参数估计,但我的经验是,你的#1建议似乎效果最好。请注意,这里“C”的初始参数估计值只是数据的平均值。@JamesPhillips。对于足够扭曲的数据(我确实看到过一些例子),最好先估计振幅,然后取峰值之间距离的一半。但老实说,除了频率,相移是唯一偶尔需要2到3次以上的曲线拟合迭代才能确定的参数。我的计划是做一个简化的KDE,以获得比FFT更可靠的频率