2017-12-19 3 views
1

나는 물리학 과정을 설명하는 Imaginary 함수를 가지고 있는데 이것을 데이터 세트 x_interpolate, y_interpolate에 맞추고 싶습니다. 이 함수는 Lorentzian 피크 함수의 한 형태이며 피크 찾기 알고리즘을 사용하여 찾을 수있는 f_peak (피크 위치)을 제외하고 사용자가 제공 한 초기 값이 있습니다. offset을 제외한 모든 fit 매개 변수는 양수가 될 것으로 예상되므로 이에 따라 bounds_I을 설정했습니다.curve_fit에서 맞는 매개 변수 수정하기

def Imaginary(freq, alpha, res, Ms, off): 
    numerator = (2*alpha*freq*res**2) 
    denominator = (4*(alpha*res*freq)**2) + (res**2 - freq**2)**2 
    Im = Ms*(numerator/denominator) + off 
    return Im 

pI = np.array([alpha_init, f_peak, Ms_init, 0]) 

bounds_I = ([0,0,0,0, -np.inf], [np.inf,np.inf,np.inf, np.inf]) 

poptI, pcovI = curve_fit(Imaginary, x_interpolate, y_interpolate, pI, bounds=bounds_I) 

경우에 따라 피팅 프로세스 중에 매개 변수 f_peak을 고정하고 싶습니다. 이것은 여러 가지 이유로이 일을 더 파이썬 방법이 있는지 그래서 궁금해서이 일을하지 최적의 방법입니다

bounds_I = ([0,f_peak+0.001,0,0, -np.inf], [np.inf,f_peak-0.001,np.inf, np.inf]) 

: 나는에 bounds_I을 변경하여 쉬운 솔루션을 시도? 도움 주셔서 감사합니다

답변

2

매개 변수가 고정되어 있으면 실제로 매개 변수가 아니므로 매개 변수 목록에서 제거해야합니다. 해당 매개 변수가 고정 된 값으로 대체 된 모델을 정의하고이를 맞 춥니 다. 실시 예 이하, 간략화를 위해 단순화하고 독립적으로 :

x = np.arange(10) 
y = np.sqrt(x)  
def parabola(x, a, b, c): 
    return a*x**2 + b*x + c 

fit1 = curve_fit(parabola, x, y) # [-0.02989396, 0.56204598, 0.25337086] 
b_fixed = 0.5 
fit2 = curve_fit(lambda x, a, c: parabola(x, a, b_fixed, c), x, y) 

번째 통화가 A와 C의 최적 값은 반환 [-0.02350478, 0.35048631]을 맞게. b의 값은 0.5로 고정되었다.

물론 매개 변수는 초기 벡터 pI와 경계에서도 제거해야합니다.

0

lmfit (https://lmfit.github.io/lmfit-py/)가 도움이 될 수 있습니다. 이 라이브러리는 scipy 최적화 루틴에 더 높은 수준의 인터페이스를 추가하여 최적화 및 커브 피팅에 대한 Pythonic 접근을 목표로합니다. 예를 들어, Parameter 객체를 사용하여 목표 또는 모델 함수를 수정하지 않고도 경계 및 고정 매개 변수를 설정할 수 있습니다. 커브 피팅의 경우, 사용할 수있는 고급 모델 함수를 정의합니다.

하면 예를 들어, (함수 서명에 따라 매개 변수 객체의 이름을합니다 lmfit) 매개 변수를 만들 초기 값을 제공 한 다음

from lmfit import Model 
lmodel = Model(Imaginary) 

와 함께 작성한로 Imaginary 기능을 사용할 수 있습니다 :

: 기본적으로 모든 매개 변수 언 바운드 및 적합성에 달라질 수 있지만 (모델 함수를 다시 작성하지 않고) 이러한 속성을 수정할 수 있습니다함으로써

params = lmodel.make_params(alpha=alpha_init, res=f_peak, Ms=Ms_init, off=0) 

params['alpha'].min = 0 
params['res'].min = 0 
params['Ms'].min = 0 

당신은에서와 같이 적합 다양하지 않도록 매개 변수 중 하나 (또는 ​​그 이상)을 설정할 수 있습니다

params['res'].vary = False 

이 명확하게하기 위해이 모델의 기능을 변경이 필요하지 않습니다에 훨씬 더 쉽게 변경은 고정되어 있으며, 어떤 경계가 부과 될 수 있는지 등등.

그런 다음 모델에 적합 이러한 매개 변수를 수행 할 것입니다 : 당신이

print(result.fit_report()) 

과 매개 변수에 맞는 통계, 최적 값과 불확실성에 대한 보고서를 얻을 수 있습니다

result = lmodel.fit(y_interpolate, params, freq=x_interpolate) 

을 가장 적합한 매개 변수는 result.params에 보관됩니다.

FWIW, lmfit에는 Lorentzian 및 상수 오프셋을 비롯한 많은 일반적인 형식의 모델이 내장되어 있습니다. 그래서, 당신은, l_center, l_sigmacl_amplitude라는 이름의 매개 변수를해야합니다

from lmfit.models import LorentzianModel, ConstantModel 

mymodel = LorentzianModel(prefix='l_') + ConstantModel() 

params = mymodel.make_params() 

으로이 모델을 만들 수 있습니다 (c는 상수이다)와 모델 (독립 변수에 대한 귀하의 freq을 이름 x을 사용합니다). 이 접근법은 피크 또는 배경의 기능적 형태를 변경하거나 여러 피크를 스펙트럼에 맞추고 자 할 때 매우 편리 할 수 ​​있습니다.

관련 문제