【问题标题】:Using a guess with scipy curve_fit使用 scipy curve_fit 进行猜测
【发布时间】:2015-01-16 21:28:06
【问题描述】:

我有一个函数,我想在知道曲线拟合误差的情况下进行曲线拟合。我正在尝试使用 scipy.optimize.curve_fit 来执行此操作,但遇到了问题。现在我的代码是:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

pi = np.pi
sqrt = np.sqrt
mean = np.mean

A = 1
T_2 = 100
nu_0 = 10
phi_0 = 0
n = .001
nu_s = 500
T = 1000

t = np.linspace(0, T, num = (nu_s*T))

def S_n(A,t,T_2,nu_0,phi_0,n,nu_s,T):
    return (A/np.sqrt(2))*np.exp(-t/T_2)*np.cos(2*pi*nu_0*t+phi_0)

S = S_n(A,t,T_2,nu_0,phi_0,n,nu_s,T) + np.random.normal(0, n, nu_s*T)

guess = np.array([A,T_2,nu_0,phi_0,n,nu_s,T])
print guess

popt, pcov = curve_fit(S_n,t,S, guess)
print popt
perr = sqrt(np.diag(pcov))
print perr

这给了我无限的错误。我不确定我的猜测是否正确,因为在等式中,除 t 之外的所有内容都保持不变,所以我是否将 t 排除在我的猜测之外,因为它不再是数组,因为 t 是一个序列。当我将 t 排除在猜测之外时,我在这里所做的我收到的每个变量的值都与我最初给出的值相去甚远,并且出现无限错误。如果我在猜测中包含 t,那么我会得到一个错误。

【问题讨论】:

    标签: python scipy curve-fitting data-analysis


    【解决方案1】:

    你没有考虑到curve_fit的参数顺序:

    定义:curve_fit(f, xdata, ydata, p0=None, sigma=None, **kw)

    文档字符串: 使用非线性最小二乘法将函数 f 拟合到数据中。

    假设ydata = f(xdata, *params) + eps

    参数

    f : 可调用 模型函数 f(x, ...)。它必须采取独立的 变量作为第一个参数和适合的参数 分开剩余的参数。

    如果你做一个函数:

    def Sm(t, A,T_2,nu_0,phi_0,n,nu_s,T):
        return S_n(A, t, T_2,nu_0,phi_0,n,nu_s,T)
    

    (请注意前 2 个参数的顺序已更改) 并将其传递给curve_fit,它将起作用。

    不过,清理原始函数可能更符合 Python 风格:

    def S_n(t, A, T_2, nu_0, phi_0, n, nu_s, T):
        return (A/np.sqrt(2))*np.exp(-t/T_2)*np.cos(2*pi*nu_0*t+phi_0)
    
    S = S_n(t, A, T_2, nu_0, phi_0, n, nu_s, T) + np.random.normal(0, n, nu_s*T)
    

    然后您可以将S_n 传递给curve_fit 不变,以及Sguess

    为了清楚起见,以下代码产生了所需的拟合:

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    
    def S_n(t, amplitude, sigma,freq0,phase):
        return (amplitude/np.sqrt(2))*np.exp(-t/sigma)*np.cos(2*np.pi*freq0*t+ phase)
    
    amplitude = 1
    sigma = 100
    freq0 = 10
    phase = 0
    n = .001
    sample_freq = 500
    period = 1000
    
    t = np.linspace(0, period, num = (sample_freq*period))
    S = S_n(t, amplitude, sigma,freq0,phi_0) + np.random.normal(0, n, sample_freq*period)
    
    guess = np.array([amplitude, sigma, freq0, phase ])
    print guess
    popt, pcov = curve_fit(S_n,t,S, guess)
    print popt
    print(np.all(np.isfinite(pcov)))
    # output
    [  1 100  10   0]
    [  1.00000532e+00   1.00000409e+02   1.00000000e+01  -1.49076430e-05]
    True
    

    【讨论】:

    • 您是说将 def Sm 与其他所有内容分开添加然后有 curve_fit(S_n,t,Sm,guess)?这不包括我需要的随机噪声。或者你的意思是有curve_fit(Sm,t,S,guess)?如果是这样,那我应该改变我的猜测吗?
    • @jakeowen 做最后一部分:致电curve_fit(Sm,t,S,guess) 并留下其他一切。您可以按原样保留guess:它的顺序正确。基本上curve_fit 将调用模型函数Sm,在这种情况下,提供给它的第二个参数t 作为模型函数的第一个参数。 guess 将作为额外参数添加到模型函数的调用中。
    • 它仍然给我同样的问题。当我使用 curve_fit(Sm,t,S,guess) 运行它时,输出为 [ 2.28727542e+00 -8.16926439e+01 4.39912861e+03 1.04075178e+06 1.00000000e-03 5.00000000e+02 1.00000000 ] [ inf inf inf inf inf inf inf].
    • @jakeowen,加入我的chat
    • @jakeowen 那是因为你的模型有 3 个参数根本没有被使用:n, nu_s, T。这也解释了here(我赞成)。如果你去掉这 3 个未使用的参数(也在 guess 中),那么 pcov 将返回有限值。我已更改我的答案以反映您正在使用的变量并为它们提供更具描述性的标题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多