【问题标题】:Trying to fit a trig function to data with scipy尝试使用 scipy 将三角函数拟合到数据中
【发布时间】:2020-04-05 03:56:23
【问题描述】:

我正在尝试使用scipy.optimize.curve_fit 拟合一些数据。我有read the documentationthis StackOverflow post,但似乎都没有回答我的问题。

我有some data,它很简单,2D 数据看起来近似于三角函数。我想用一个通用的三角函数来拟合它 使用scipy

我的做法如下:

from __future__ import division
import numpy as np
from scipy.optimize import curve_fit



#Load the data
data = np.loadtxt('example_data.txt')
t = data[:,0]
y = data[:,1]


#define the function to fit
def func_cos(t,A,omega,dphi,C):
    # A is the amplitude, omega the frequency, dphi and C the horizontal/vertical shifts
    return A*np.cos(omega*t + dphi) + C

#do a scipy fit
popt, pcov = curve_fit(func_cos, t,y)

#Plot fit data and original data
fig = plt.figure(figsize=(14,10))
ax1 = plt.subplot2grid((1,1), (0,0))

ax1.plot(t,y)
ax1.plot(t,func_cos(t,*popt))

这个输出:

蓝色是数据,橙色是拟合。显然我做错了什么。有什么指点吗?

【问题讨论】:

  • 请上传'example_data.txt'的样本数据,否则难以重现。
  • 可以通过some_data超链接访问

标签: python scipy curve-fitting scipy-optimize


【解决方案1】:

如果没有为参数p0 的初始猜测提供值,则假定每个参数的值为1。来自文档:

p0:array_like,可选
参数的初始猜测(长度 N)。如果为 None,则初始值将全部为 1(如果函数的参数数量可以使用自省确定,否则会引发 ValueError)。

由于您的数据具有非常大的 x 值和非常小的 y 值,1 的初始猜测与实际解决方案相差甚远,因此优化器不会收敛。您可以通过提供可以从数据中猜测/近似的合适的初始参数值来帮助优化器:

  • 幅度:A = (y.max() - y.min()) / 2
  • 偏移量:C = (y.max() + y.min()) / 2
  • 频率:在这里我们可以通过将连续的 y 值相乘来估计过零的次数,并检查哪些乘积小于零。这个数字除以总 x 范围给出频率,为了以pi 为单位,我们可以将该数字乘以piy_shifted = y - offset; oemga = np.pi * np.sum(y_shifted[:-1] * y_shifted[1:] < 0) / (t.max() - t.min())
  • 相移:可设置为零,dphi = 0

所以综上所述,可以使用以下初始参数猜测:

offset = (y.max() + y.min()) / 2
y_shifted = y - offset
p0 = (
    (y.max() - y.min()) / 2,
    np.pi * np.sum(y_shifted[:-1] * y_shifted[1:] < 0) / (t.max() - t.min()),
    0,
    offset
)
popt, pcov = curve_fit(func_cos, t, y, p0=p0)

这给了我以下拟合函数:

【讨论】:

  • 太完美了,谢谢!是我一个人,还是看起来有点垂直移位?
  • @user1887919 看起来,但这是最小化两个函数之间差异的版本。在峰值周围,拟合函数似乎发生了变化,但这具有斜率非常一致的好处。考虑到峰只占 x 范围的一小部分,而斜率占很大一部分,这样可以最大限度地减少差异。您可以尝试将偏移量的初始猜测设置为 amplitude + offset 之类的值,但它会再次收敛到此解决方案。
猜你喜欢
  • 2013-02-12
  • 1970-01-01
  • 2019-04-07
  • 2016-01-14
  • 1970-01-01
  • 2023-03-10
  • 2020-06-12
  • 2020-07-07
  • 2018-11-15
相关资源
最近更新 更多