我正试图通过一些数据拟合曲线。我想要的功能如下:
def f(x,a,b,c):
return a +b*x**c
使用scipy.optimize.curve_fit时,我没有得到任何结果:它返回(默认)初始参数:
(array([ 1., 1., 1.]),
array([[ inf, inf, inf],
[ inf, inf, inf],
[ inf, inf, inf]]))
我尝试过再现数据,发现正弦函数导致了问题(数据包含每日变化):
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
xdata=np.random.rand(1000) + 0.002 *np.sin(np.arange(1000)/(1.5*np.pi))
ydata=0.1 + 23.4*xdata**0.56 + np.random.normal(0,2,1000)
def f(x,a,b,c):
return a +b*x**c
fit=curve_fit(f,xdata,ydata)
fig,ax=plt.subplots(1,1)
ax.plot(xdata,ydata,'k.',markersize=3)
ax.plot(np.arange(0,1,.01), f(np.arange(0,1,.01),*fit[0]))
fig.show()
我显然希望curve_fit能够返回接近[0.1,23.4,.56]的东西。
请注意,正弦函数似乎并没有真正影响数据('xdata')的值,因为xdata的第一项介于0和1之间,我在-0.002和+0.002之间添加了一些东西,但它确实导致拟合程序失败。我发现值0.002接近失败的“临界”值;如果它更小,程序不太可能失败,反之亦然。在0.002时,程序经常失败。
我试过通过同时改组'xdata'和'ydata'来解决这个问题,但没效果。我认为(没有特别的原因)或许删除数据的自相关可以解决问题。
所以我的问题是:如何修复/绕过这个问题?我可以在上面的代码段中更改合成数据中的正弦贡献,但对于我的实际数据,我显然不能。
答案 0 :(得分:0)
您可以消除模型函数中负x值生成的NaN:
def f(x,a,b,c):
y = a +b*x**c
y[np.isnan(y)] = 0.0
return y
将所有NaN替换为0可能不是最佳选择。您可以尝试邻居值或进行某种推断。
如果您输入生成的测试数据,则必须确保其中没有NaN。因此,在数据生成之后直接进行如下操作:
if xdata.min() < 0:
print 'expecting NaNs'
ydata[np.isnan(ydata)] = 0.0