簡體   English   中英

對scipy curve_fit進行猜測

[英]Using a guess with scipy curve_fit

我有一個要知道曲線擬合誤差的曲線擬合函數。 我正在嘗試使用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,那么我會得到一個錯誤。

您沒有考慮到參數curve_fit的順序:

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

Docstring:使用非線性最小二乘法將函數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)

(注意前兩個參數的順序已更改),並將其傳遞給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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM