使用scipy curve_fit进行猜测

时间:2015-01-16 21:28:07

标签: python scipy curve-fitting data-analysis

我有一个功能,我希望曲线拟合,知道曲线拟合的误差。我尝试使用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,那么我会收到错误。

1 个答案:

答案 0 :(得分:1)

您没有将参数的顺序考虑到curve_fit

  

定义:curve_fit(f,xdata,ydata,p0 =无,sigma =无,** 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,它会起作用。

尽管如此,清理原始功能可能更加pythonic:

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