代码之家  ›  专栏  ›  技术社区  ›  Agos

Scipy optimize.curve_fit有时不会收敛

  •  1
  • Agos  · 技术社区  · 14 年前

    我试图使用numpy.optimize.curve_fit来估计开/关序列的频率和相位。

    from numpy import *
    from scipy import optimize
    
    row = array([0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0,])
    
    def fit_func(x, a, b, c, d):
        return c * sin (a * x + b) + d
    
    p0 = [(pi/10.0), 5.0, row.std(), row.mean()]
    result = optimize.curve_fit(fit_func, arange(len(row)), row, p0)
    print result
    

    这很管用。但在某些行上,即使它们看起来很好,它还是失败了。

    row = array([1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, 0.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, 0.0,  0.0,  0.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  0.0,  0.0,  0.0,  0.0, 0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  0.0,  0.0, 0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0, 1.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,])
    

    错误是:

    运行时误差:未找到最佳参数:平方和的实际和预测相对减少量均不超过0.000000,连续两次迭代之间的相对误差不超过0.000000

    1 回复  |  直到 14 年前
        1
  •  2
  •   Justin Peel    14 年前

    我试过了你提供的两行数据,两行都很好。我用的是Scipy 0.8.0rc3。你用的是什么版本?另一个可能有用的方法是将c和d设置为固定值,因为它们每次都应该是相同的。我把c设为0.6311786,d设为0.5。如果需要其他方法,也可以使用带零填充和围绕峰值的二次拟合的fft来查找频率。实际上,任何基音估计方法都是适用的,因为你在寻找基频。