scipy.optimize 关于高频正弦函数
scipy.optimize on high frequency sine function
我正在使用 Python 2.7。我想知道为什么当目标是高频正弦波时 SciPy 的优化函数没有收敛到正确的函数。
import numpy as np
from scipy import optimize
test_func = lambda x: 5*np.sin(15*x+3)+1
t = linspace(0,25,100000)
y_t = test_func(t)
plot(t,y_t)
fitfunc = lambda p, x: p[0]*np.sin(p[1]*x+p[2])+p[3]
errfunc = lambda p, x, y: fitfunc(p, x) - y
p0 = [max(y_t),10,2,0]
p1, success = optimize.leastsq(errfunc, p0, args=(t,y_t))
plot(t,fitfunc(p1,t))
可以清楚地看到最终解决方案明显偏离了目标。难道我做错了什么 ?误差函数在这里适配不当吗?
感谢任何意见
你的问题是你的残差函数中有大量的局部极小值作为相移和频移相对于它们的真实值;如果没有对相位和频率的真正好的初始猜测,您将收敛到一个而不是陷入更深的全局最小值:
如果您没有关于相位和频率的更多信息,您可以从数据的 FFT 中估计它们,或者将您的公式重写为
Asin(bx + phi) + d = Acos(phi)sin(bx) + Asin(phi)cos(bx) + d
它只有一个非线性参数 (b):您可以对 b 使用网格搜索,对其余参数使用更快、更可靠的线性最小二乘拟合 (a1 = Acos(phi), a2 = Asin( phi) 和 d).
这是随频率 b
变化的均方根残差图,显示了各种最小值:
我正在使用 Python 2.7。我想知道为什么当目标是高频正弦波时 SciPy 的优化函数没有收敛到正确的函数。
import numpy as np
from scipy import optimize
test_func = lambda x: 5*np.sin(15*x+3)+1
t = linspace(0,25,100000)
y_t = test_func(t)
plot(t,y_t)
fitfunc = lambda p, x: p[0]*np.sin(p[1]*x+p[2])+p[3]
errfunc = lambda p, x, y: fitfunc(p, x) - y
p0 = [max(y_t),10,2,0]
p1, success = optimize.leastsq(errfunc, p0, args=(t,y_t))
plot(t,fitfunc(p1,t))
可以清楚地看到最终解决方案明显偏离了目标。难道我做错了什么 ?误差函数在这里适配不当吗?
感谢任何意见
你的问题是你的残差函数中有大量的局部极小值作为相移和频移相对于它们的真实值;如果没有对相位和频率的真正好的初始猜测,您将收敛到一个而不是陷入更深的全局最小值:
如果您没有关于相位和频率的更多信息,您可以从数据的 FFT 中估计它们,或者将您的公式重写为
Asin(bx + phi) + d = Acos(phi)sin(bx) + Asin(phi)cos(bx) + d
它只有一个非线性参数 (b):您可以对 b 使用网格搜索,对其余参数使用更快、更可靠的线性最小二乘拟合 (a1 = Acos(phi), a2 = Asin( phi) 和 d).
这是随频率 b
变化的均方根残差图,显示了各种最小值: