상세 컨텐츠

본문 제목

[Python] 기울기가 달라지는 수치데이터 Fitting 하기 - 1 : piecewise 함수

프로그래밍/Python

by 척척석사 민준 2020. 8. 28. 21:58

본문

728x90

기울기가 변하는 함수를 피팅하는 법

출처 : https://en.wikipedia.org/wiki/Townsend_discharge

플라즈마를 측정하는 많은 방법중 가장 오래된 방법이 전류와 전압을 측정하는 방법이다. 플라즈마라는 이름을 붙여준 랭뮤어가 사용했던 방법도 결국 전류와 전압을 분석한 데이터였다. (Mott-Smith, H. M.; Langmuir, Irving (1926). "The Theory of Collectors in Gaseous Discharges". Phys. Rev. 28 (4): 727–763) 플라즈마가 발생하면 전류와 전압이 위의 사진과 같이 방전의 상태에 따라서 비선형적으로 변화하게 된다. 

파이썬 코드 이야기를 하다가 갑자기 플라즈마를 꺼내게 된 이유는... 내 졸업논문의 성패가 저 비선형적인 플라즈마 측정 데이터를 분석하는데에 있기 때문이다. 실험을 한번 할때마다 최소 열번이상의 측정을 한다. 조건에 따라서도 측정하고 시간에 따라서도 측정한다. 학회에 내보낼 데이터는 양이 적으니 저녁과 주말이 있는 삶을 포기하면 된다. 데이터를 하나하나 자르고 피팅하고... 1000개 정도의 데이터는 그럴 수 있다. 그런데 그런 데이터가 만개, 십만개가 되어버리면 결과해석은 커녕 분석만 하다가 세월을 낭비하게 될 것이다. 수십년전 선배들은 그 많은걸 손으로 했다지만 지금은 컴퓨터가 있고 알파고의 시대이지 않는가? 이런 것에 인생을 낭비하기엔 하고 싶은게 너무 많다. 

내가 분석해야 하는 데이터는 위의 그림처럼 비선형적인 데이터이다. 그나마 다행인건 이론적으로 선형증가한다고 알려져있다. 다만 그 기울기가 어떤 조건에서 급격하게 바뀐다! 

아래의 그림처럼 데이터의 관계가 어떤 변곡점을 기준으로 바뀌게된다. 미끄럼틀처럼 말이다. 

출처 : https://qastack.kr/datascience/8457/python-library-for-segmented-regression-a-k-a-piecewise-regression

이런 데이터를 중학교때에 배웠다. 조건부 함수라고 중학생때 힘들게 하더니, 나중에 고등학교 가서 미분배울때 한번더 괴롭혔던 나쁜 함수다. 배울때는 조건이 주어지고 그 조건에 따라 그래프를 그리라고 했다. 지금 해야하는 것은 그려진 그래프를 가지고 조건을 찾아내야 하는 신유형이다. 주입식 교육의 한계가 느껴진다. 이제 어떻게하지;

piecewise 함수 : piecewise ( 입력배열 'x'  , 조건 , 출력함수 'y(x)' )

파이썬에서는 piecewise 라는 함수를 이용하면 손쉽게 조건부함수를 만들 수 있다. numpy 라이브러리에 있는 함수라서 수치데이터를 입력받고 수치데이터로 출력할 수 있다. piecewise 함수를 사용하는 방법은 간단하다. 아래 예제를 보자.

import numpy as np 
x = np.linsapce(-2.5, 2.5 6)
result = np.piecewise(x, [x < 0, x >=0], [-1, 1])

result = [-1, -1, -1, 1, 1, 1]

(출처 : Numpy 라이브러리 홈페이지,  https://numpy.org/doc/stable/reference/generated/numpy.piecewise.html

 

x가 입력변수이고 -2.5 부터 2.5까지 6개의 같은 간격의 수로 이루어져있다. 

조건은 x < 0 이면 -1 을 출력하고 x >= 0 이면 1을 출력한다는 의미아다. 

 

그럼 piecewise 를 이용해 어떤 점을 기준으로 기울기가 변하는 직선을 그리게 하려면 어떻게 해야할까?

x < x0 이면 기울기가 s1인 직선의 방정식을 출력하고

x >= x0 이면 기울기가 s2인 직선의 방정식을 출력하는 것이다. 

lambda 라는 함수를 이용하면 직선의 방정식을 쉽게 만들 수 있다. 

직선의 방정식이 y - y0 = s*(x-x0) 이니까 (x0, y0는 지나는 점) lambda 함수를 이용해 다음과 같이 표현가능하다. 

lambda x : s1*x - s1*x0 + y0
lambda x : s2*x - s2*x0 + y0

조건에 따라 직선의 기울기가 변하는 함수는 다음과 같이 표현할 수 있다. 

import numpy as np

np.piecewise(x, [x < x0], [lambda x : s1*x - s1*x0 + y0 , lambda x : s2*x - s2*x0 + y0])

 

piecewise 함수가 정확히 어떤 값을 출력해주는지 어떤 매커니즘으로 출력을 하는건지에 대해서는 좀더 공부를 한 후에 수정하겠다. piecewise 함수와 curve_fit 함수를 이용해 x0 , y0, s1, s2 를 모두 얻을 수 있었는데 이는 다음 글에서 계속하겠다. 

 

참고

1. numpy 라이브러리 설명 :

2. https://qastack.kr/datascience/8457/python-library-for-segmented-regression-a-k-a-piecewise-regression

728x90

관련글 더보기