【问题标题】:Scipy.optimize.curve_fit does not fitScipy.optimize.curve_fit 不适合
【发布时间】:2018-02-10 20:48:15
【问题描述】:

假设我想使用scipy.optimize.curve_fit 拟合正弦函数。我不知道函数的任何参数。为了获得频率,我进行傅里叶变换并猜测所有其他参数——幅度、相位和偏移。运行我的程序时,我确实很健康,但这没有意义。问题是什么?任何帮助将不胜感激。

import numpy as np
import matplotlib.pyplot as plt
import scipy as sp

ampl = 1
freq = 24.5
phase = np.pi/2
offset = 0.05
t = np.arange(0,10,0.001)

func = np.sin(2*np.pi*t*freq + phase) + offset

fastfft = np.fft.fft(func)
freq_array = np.fft.fftfreq(len(t),t[0]-t[1])

max_value_index = np.argmax(abs(fastfft))
frequency = abs(freq_array[max_value_index])

def fit(a, f, p, o, t):
    return a * np.sin(2*np.pi*t*f + p) + o

guess = (0.9, frequency, np.pi/4, 0.1)
params, fit = sp.optimize.curve_fit(fit, t, func, p0=guess)

a, f, p, o = params
fitfunc = lambda t: a * np.sin(2*np.pi*t*f + p) + o

plt.plot(t, func, 'r-', t, fitfunc(t), 'b-')

【问题讨论】:

    标签: python numpy scipy curve-fitting scipy-optimize


    【解决方案1】:

    您的程序中的主要问题是一个误解,scipy.optimize.curve_fit 是如何设计的以及它对拟合函数的假设:

     ydata = f(xdata, *params) + eps
    

    这意味着 fit 函数必须将 x 值的数组作为第一个参数,然后是函数参数(不按特定顺序),并且必须返回 y 值的数组。这是一个例子,如何做到这一点:

    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.optimize 
    
    #t has to be the first parameter of the fit function 
    def fit(t, a, f, p, o):
        return a * np.sin(2*np.pi*t*f + p) + o
    
    ampl = 1
    freq = 2
    phase = np.pi/2
    offset = 0.5
    t = np.arange(0,10,0.01)
    
    #is the same as fit(t, ampl, freq, phase, offset)
    func = np.sin(2*np.pi*t*freq + phase) + offset
    
    fastfft = np.fft.fft(func)
    freq_array = np.fft.fftfreq(len(t),t[0]-t[1])
    
    max_value_index = np.argmax(abs(fastfft))
    frequency = abs(freq_array[max_value_index])
    
    guess = (0.9, frequency, np.pi/4, 0.1)
    #renamed the covariance matrix
    params, pcov = scipy.optimize.curve_fit(fit, t, func, p0=guess)
    a, f, p, o = params
    
    #calculate the fit plot using the fit function
    plt.plot(t, func, 'r-', t, fit(t, *params), 'b-')
    plt.show()
    

    如您所见,我还更改了计算图的拟合函数的方式。您不需要其他函数 - 只需将 fit 函数与参数列表一起使用,fit 程序就会返回。
    另一个问题是您调用了协方差数组fit - 覆盖了之前定义的函数fit。我也解决了这个问题。
    P.S.:当然现在你只看到一条曲线,因为完美的拟合覆盖了你的数据点。

    【讨论】:

    • 很好的答案!注意到我的错误
    猜你喜欢
    • 1970-01-01
    • 2013-03-15
    • 2018-06-27
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多