본 포스팅은 이전의 curve_fit 포스팅에 이어서 curve_fit 을 이용해 피팅을 하는 알고리즘과 수학적인 증명에 대한 포스팅 입니다.
curve_fit을 어떻게 사용하는지에 대한 간단한 설명은 이전 포스팅에 있습니다.
2021.06.19 - [자연과학도를 위한 프로그래밍 (Python+MATLAB)/확장성이 좋은 파이썬 (Python)] - [SciPy. Curve_Fit] 쓰기위해서 배우는 최소한의 curve_fit 함수
간단하게 복습하면 scipy에서 curve_fit은 다음과 같이 불러와 사용할 수 있다.
import numpy as np from scipy.optimize import curve_fit def func(x, a, b): return a * x + b x = np.linspace(0,100) y = func(x, 1, 2) yn = y + 0.9 * np.random.normal(size=len(x)) popt, pcov = curve_fit(func, x, yn)
x, y는 분석하고자 하는 데이터이고 func는 피팅하는데 필요한 모델이다.
노이즈가 섞인 yn을 피팅모델 func에 따라서 분석할 수 있으며
피팅결과는 func을 특정할 수 있는 파라매터가 주어진다. (이 코드에선 a, b)
이 파라매터 a, b는 popt에 저장되며
오류정보는 pcov에 저장된다.
표준편차로 오류를 계산하기 위해서는 다음과 같은 코드를 이용할 수 있다.
perr = np.sqrt(np.diag(pcov))
어떤 수학적인 기술로 피팅이 이뤄지고
오차는 어떤 방식으로 계산되는지는 다음의 책에서 소개되어있다.
Introduction to Python for Science & Engineering : David J. Pine
이 책의 Chapter 8 Curve Fitting에 따르면 curve_fit 이 카이제곱을 최소화 하는 방법으로 피팅을 한다고 한다.
카이제곱은 다음의 식을 의미한다.
f(x)는 피팅을 위해 사용했던 모델 func (y = a * x + b) 을 의미한다.
카이제곱이 최소가 되는 a, b 쌍이 최적의 피팅이 되는 것이라 설명하고 있다.
이런 방법을 Levenberg-Marquardt 방법이라고 한다.
블로그를 찾아보니 다음의 블로그에서 자세하게 설명이 되어있고
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=tlaja&logNo=220735045887
쉽게 생각하면 실제값과 피팅값 사이의 차의 합들이 최소가 되도록 하는데
여러 방법들 (gradient descent, parabolic extrapolation)마다 가지는 단점이 있으므로 Levenberg-Marquardt는 두 방법을 합친 수학적인 방식이다.
좌표계를 a, b로 만들었을때 카이제곱은 a와 b의 함수로 나타낼 수 있다.
gradient descent 방법은 a와 b가 최적값(피팅값)에서 멀리 떨어져있을때 카이제곱값을 빠르게 감소시키고(카이제곱이 최소가 되는게 최적의 피팅값을 계산하는 방법이다)
parabolic extrapolation 방법은 a와 b가 최적값(피팅값)에 가까울 때 카이제곱을 효과적으로 감소시킨다.
Levenberg-Marquardt는 피팅에 효과적이지만 만약 inital guesses(코딩에서 p0 옵션값)가 최적값과 매우 떨어져있는 경우 올바른 값을 도출할 수 없다.
pcov는 popt 값들의 uncertainty에 대한 정보가 2-D Matrix로 나와있다.
피팅 파라매터들의 uncertainties를 pcov에서 꺼내기 위해서는 먼저 대각화를 하고
(대각화에는 numpy 라이브러리의 diag가 쓰인다. 원론적으로는 for문을 사용할 수도 있다)
그후에 루트를 취한다.
3줄요약
1. curve_fit은 Levenberg-Marquardt 방법을 이용해 피팅을 한다
2. Levenberg-Marquardt 방법은 카이제곱을 최소로 하는 방법이다
3. pcov에서 uncertanties를 구할 수 있다.
[파이썬 find_peaks 함수] 신호처리의 꽃 피크 찾기 (2) | 2021.10.09 |
---|---|
[Pandas 웹 크롤링] ]pd.read_html로 NIST Atomic spectrum line 테이블 가져오기 (0) | 2021.06.20 |
[SciPy. Curve_Fit] 쓰기위해서 배우는 최소한의 curve_fit 함수 (0) | 2021.06.19 |
[실험데이터 분석 Pandas 기초] csv데이터의 헤더에서 측정정보 추출하기 (0) | 2021.06.16 |
[파이썬 데이터분석공부] Pandas와 Numpy 무엇을 써야할까? (0) | 2021.06.15 |