2015년 1월 18일 일요일

python fitting / optimization

주어진 xdata와 ydata에 대해,
Least square method로 data를 fitting 하는 방법.

결론은 , scipy의 optimize module을 이용한다.

import scipy.optimize as optimization

def func(x,para1,para2):
   return para1*sin(para2*x)

popt, pcov = optimization.curve_fit(func,xdata, ydata, p0=(1.0,1.0))

p0는 initial guess이고

popt는 parameter fitting 의 결과를, pcov는 covariance 계산 결과를 보여준다.

least square method를 사용하므로,
cost function chi(para...) 함수를 최소로 만드는 parameter를 찾는다.

pcov는 (parameter 갯수)*(parameter 갯수) matrix로,
cost function의 parameter 값의 변화에 대한 변화값을 나타낸다.
pcov(i,j)= d^2[chi(c1,c2..)]/dc_i dc_j

몇가지 다른 fitting 방법이 있다.

1. scipy.optimize.curve_fit : 
   입력: f(x,para) , xdata, ydata, yerr(optional)

    popt, pcov = optimization.curve_fit(f,xdata, ydata, p0=(1.0,1.0))

   curve_fit은 least square 방법을 통해  sum ( ydata - f(xdata,para))^2/yerr^2  
   을 minimize 시킨다. 
   parameter의 error estimation은 sqrt(diag(pcov)) 를 이용한다.

2. scipy.optimize.leastsq :
   입력: errFunc(para,x,y) , xdata, ydata 

    popt, hess_inv, infodict, errmsg, success = optimize.leastsq(errFunc, pstart, args=(xdata, ydata), full_output=1)   

    입력하는 함수는 errFunc(para,xdata,ydata) = ydata - f(xdata,para) 
    이고,  sum ( errFunc )^2 를 minimize 시킨다. 
    parameter의 error estimation은 hess_inv 와 residual variance 를 이용한다. 
    sqrt( diag( hess_inv * resVariance)) with 
    resVariance = sum( errFunc(para,xdata,ydata)^2) /(len(ydata)-len(para)) 

3. scipy.optimize.minimize :
    입력: minFunc(para,x,y) , xdata, ydata 
    
    result = optimize.minimize(lambda p,x,y: np.sum( errFunc(p,x,y)**2 ), pstart, args=(xdata, ydata))

    이 경우 입력함수 
    minFunc(para,xdata,ydata) = sum ( ydata- f(xdata,para))^2 이고, 
    minFunc을 minimize 시킨다.  parameter의 error estimation은 leastsq 와 같이
    result.hess_inv 와 residual variance 을 이용한다. 

    그러나, minimization의 방법에 따라 hess_inv가 제공되지 않는 경우가 있다.