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

时间:2017-02-10 22:26:25

标签: 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, 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()

enter image description here

这种拟合极其低估了数据。任何想法为什么会这样?

以下是此处提供的数据:https://www.dropbox.com/sh/72jnpkkk0jf3sjg/AAAb17JSPbqhQOWnI68xK7sMa?dl=0

知道为什么会这样做吗?

1 个答案:

答案 0 :(得分:3)

如果您的频率猜测关闭,则正常波很难适应。这是因为在数据中有足够数量的周期时,猜测将与一半数据异相,并且即使频率中的小误差也与其一半同相。此时,直线提供比不同频率的正弦波更好的拟合。这就是傅立叶变换工作的方式。

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

  1. 眼球吧。在GUI中甚至在命令行中减去两个峰的x值。如果您的噪声数据非常低,则可以非常轻松地自动执行此过程。
  2. 使用离散傅立叶变换。如果您的数据是一个组件的正弦波,则第一个非恒定峰值将为您提供频率。我发现这需要一些额外的调整,因为采样频率通常不是正弦波频率的倍数。抛物线适合峰值周围的三个点(包括峰值的三个点)可以帮助解决这种情况。
  3. 查找数据穿过垂直偏移的位置。这类似于#1,但对于相对无噪声的数据更容易自动化。波长是一对交叉点之间距离的两倍。
  4. 使用#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。我完成后会更新。