본문으로 바로가기

| 서론 

오늘은 R을 활용한 변곡점 탐색이라는 주제로 이야기를 해볼까 한다


데이터를 분석하다보면 시계열 등의 데이터에 대해서 변경점을 찾아야 할 때가 있다.

주식을 예로 들면 주식 차트가 우상향을 그리다가 어느 시점에 가격이 떨어지면서 우하향을 그릴때 그 지점이 정확하게 언제인지를 탐색해야 하는 것이다.

센서데이터의 경우 센서 값이 다양한 그래프를 그리게 되는데 이때 큰 변화를 일으키는 정확한 시점을 찾아야 하는 경우도 같은 예이다..


필자도 이와 같은 기능이 필요해 탐색하던 중 구글에서 다음과 같은 주제의 좋은 글을 발견했다.


'Finding inflection points in R from smoothed data'
▶ 출처 : https://stats.stackexchange.com/questions/76959/finding-inflection-points-in-r-from-smoothed-data

'LOESS Curve Fitting' 

▶ 출처 : http://www.statsdirect.com/help/nonparametric_methods/loess.htm


원리는 간단하다

R의 loess function을 이용해 변경점을 찾는 것이다.

loess 함수는 LOcally Weighted Scatter-plot Smoother 의 약자로 국소적 회귀를 찾는 방법중 하나로 보면 된다.

국소적 회귀에 대해서는 다른 블로깅에서 언급 하기로 하고 바로 활용으로 들어가보자. (우리에겐 시간이 없으니~)


| 변곡점 탐색 실습

우선 예제로 다음과 같이 임의의 점을 찍어 plot으로 선을 그려보자.

x = seq(1,20)

y = c(4,5,6,5,5,6,7,8,7,7,6,6,7,8,9,4,6,5,10,13)

plot(x,y,type="l",ylim=c(3,15))





여기에 다시 loess 함수를 이용해 적합선을 그려보면 다음과 같이 나온다.

lo <- loess(y~x, span= 0.75)

xl <- seq(min(x),max(x), (max(x) - min(x))/1000)

out = predict(lo,xl)

lines(xl, out, col='red', lwd=2)

span 0.75 적용


lo <- loess(y~x, span= 0.2)

xl <- seq(min(x),max(x), (max(x) - min(x))/1000)

out = predict(lo,xl)

lines(xl, out, col='red', lwd=2)

span 0.2 적용



결과를 보면 span  값을 어떻게 조절하냐에 따라서 smoothing이 달라지는 것을 알 수 있다.

좀더 정확한 지점을 더 많이 찾아야 한다면 span  값을 조절하면 된다.


이제는 여기에 꺾인 지점을 찾아야 하는데 다음 코드가 추가해보자.

infl <- c(FALSE, diff(diff(out)>0)!=0)

points(xl[infl ], out[infl ], col="blue")

xl[infl ] #변곡점 출력

> xl[infl ]

[1]  8.410  9.759 12.020 14.756


> xl[infl ]

 [1]  2.995  4.496  7.992  9.208  9.797 11.507 14.813 16.105 17.036 17.853

위 변곡점의 파란색 지점이 loess 회귀선의 변경이 일어난 점을 표시한 것이다.

diff 함수를 써서 부호가 바뀌는 지점을 표시한 간단한 원리다.


| 결론

이처럼 loess 함수를 활용하면 이처럼 쉽게 변곡점을 찾을 수 있다.

탐색 속도도 빠르고 정확한 지점을 찾을 수 있기 때문에 여러 분석 요건에 활용할 수 있지 않을까 싶다.


| 참고

▶ 출처 : https://stats.stackexchange.com/questions/76959/finding-inflection-points-in-r-from-smoothed-data

▶ 출처 : http://www.statsdirect.com/help/nonparametric_methods/loess.htm



공감 되셨다면 아래 버튼을 ~


댓글을 달아 주세요