为什么这个配件这么糟糕?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def fit(x, a, b, c, d):
return a * np.sin(b * x + c) + d
xdata = np.linspace(0, 360, 1000)
ydata = 89.9535 + 60.9535 * np.sin(0.0174 * xdata - 1.5708)
popt, pcov = curve_fit(fit, xdata, ydata)
plt.plot(xdata, 89.9535 + 60.9535 * np.sin(0.0174 * xdata - 1.5708))
plt.plot(xdata, fit(xdata, popt[0], popt[1], popt[2], popt[3]))
plt.show()
拟合的曲线似乎很奇怪,或者我可能会错过使用它,感谢任何帮助。
结果如下:
答案 0 :(得分:0)
curve_fit
找到最小二乘问题的 local 最小值。在这种情况下,有许多局部最小值。
解决这个问题的一种方法是使用尽可能好的初始猜测。对于多个局部最小值的问题,curve_fit
的初始猜测的所有默认值都非常糟糕。对于您的功能,关键参数是b
,即频率。如果您知道该值很小,即大约为0.01,则使用0.01作为初始猜测:
In [77]: (a, b, c, d), pcov = curve_fit(fit, xdata, ydata, p0=[1, .01, 1, 1])
In [78]: a
Out[78]: 60.953499999999998
In [79]: b
Out[79]: 0.017399999999999999
In [80]: c
Out[80]: -102.10176491487339
In [81]: ((c + np.pi) % (2*np.pi)) - np.pi
Out[81]: -1.570800000000002
In [82]: d
Out[82]: 89.953500000000005
答案 1 :(得分:0)
作为替代方案,仅绘制原始数据并使用它来初步猜测参数。对于周期函数,可以容易地估计周期和幅度。在这种情况下,猜测不需要太近。
然后我在 curve_fit :
中使用了这些 popt, pcov = curve_fit(fit, xdata, ydata, [ 80., np.pi/330, 1., 1. ])
它返回的结果基本上是原始值。
array([ 6.09535000e+01, 1.74000000e-02, -1.57080000e+00,
8.99535000e+01])