对于具有正弦函数的数据,Scipy curve_fit失败

时间:2016-10-24 15:20:39

标签: python scipy curve-fitting sine

我正试图通过一些数据拟合曲线。我想要的功能如下:

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'来解决这个问题,但没效果。我认为(没有特别的原因)或许删除数据的自相关可以解决问题。

所以我的问题是:如何修复/绕过这个问题?我可以在上面的代码段中更改合成数据中的正弦贡献,但对于我的实际数据,我显然不能。

1 个答案:

答案 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