如何解决Python 中的简单余弦拟合失败
import matplotlib.pyplot as plt
from scipy import optimize
import numpy as np
def f(t,a,b):
return a*np.cos(b*t)
v = 0
x = 0.03
t = 0
dt = 0.001
time = []
pos = []
while t<3:
a = (-5*x)/0.1
v = v + a*dt
x = x + v*dt
time.append(t)
pos.append(x)
t = t+dt
pop,pcov = optimize.curve_fit(f,time,pos)
print(pop)
即使我为参数指定了初始值(例如“a”为 0.03,b 为“7”),结果拟合仍然很差(见下文,虚线是拟合函数)。
感谢您的任何提示。
解决方法
正如 Tyberius 所指出的,您需要提供更好的初始值。
这是为什么? optimize.curve_fit
使用 least_squares 找到成本函数的局部最小值。
我相信在您的情况下,您陷入了这样一个局部最小值(这不是全局最小值)。如果您查看图表,您的拟合度约为 y=0
。 (它有点波浪,因为它是余弦)
如果您稍微增加 a
,误差会增加,因此 a
保持接近于零。如果您要增加 b
以适应数据的频率,成本函数也会上升,从而保持较低的值。
如果您不提供初始值,则每个参数都从 1
开始,如下所示:
plt.plot(time,pos,'black',label="data")
a,b = 1,1
init = [a*np.cos(b*t) for t in time]
plt.plot(time,init,'b',label="a,b=1,1")
plt.legend()
plt.show()
a
会下降,而 b
会留在后面。我相信规模是一个额外的问题。如果您将数据标准化为幅度为 1,则驼峰可能更明显且更易于拟合。
如果您从一个方便的 a
值开始,b
可以从低至 5
的初始值找到它的方式:
plt.plot(time,label="data")
for i in [1,4.8,4.9,5]:
pop,pcov = optimize.curve_fit(f,time,p0=(0.035,i))
a,b = pop
fit = [a*np.cos(b*t) for t in time]
plt.plot(time,fit,label=f"$b_0 = {i}$")
plt.legend()
plt.show()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。