페이스북 Prophet 을 이용한 주가 폭락 자동 감지

주식 차트가 만능은 아니지만 ‘차트가 갑자기 떨어지면 공포심에 다시 오르지 않을까’ 라는 근거 없는 기대는 버릴 수가 없다. 그래서 실제로 폭락을 감지해서 매매를 해보면 어떨까 싶어, 기계적으로 폭락을 감지하는 방법을 찾아보았다. 여러 방법들이 있지만, 그 중에 페이스북에서 개발한 Prophet을 간단히 소개하고자 한다.

Prophet 알고리즘 개요

Prophet은 한마디로 요약하면, 시계열 데이터를 모델링하기 위한 파이썬 모듈이다. (‘모델링 할 수 있다’라는 내용을 쉽게 설명하면, 시계열 데이터 내 순차적 데이터를 모방할 수 있는 블랙박스를 구성할 수 있다라는 의미로 생각할 수 있다. 블랙박스는 몇 개의 또는 경우에 따라서는 수백, 수천만개의 파라미터를 포함하고 있다.)

시계열 데이터를 예측(모델링)하는 방법론에는 머신러닝 방법론 그리고 고전적인 기법 ARIMA가 있다. Prophet은 머신러닝 기법은 아니며, ARIMA라고 하는 알고리즘 방법론을 응용하고 있다. ARIMA를 이용하면, 계절마다의 반복성이나 여름철에 증가하는 전기 사용료를 모델링할 수 있다.

Prophet 은 한층 더 진보적인 방법으로, 트렌드와 주기적 특성뿐 아니라 예외적이고 이벤트와 같은 휴가철 상황까지도 모델링할 수 있도록 ARIMA 알고리즘을 확장한 것이다. 시계열 데이터는 인간 생활과 밀접한 관계가 있는 데이터이기에 결국 모델링 가능한 데이터 범주와 정확도를 높이기 위해 그런 부분까지 확장한 것이 아닐까 생각이 든다.

y(t) = g(t) + s(t) + h(t) + e(t)

with g(t) representing the trend.
s(t) represents periodic changes (weekly, monthly, yearly).
h(t) represents the effects of holidays (recall: Holidays impact businesses).
e(t) is the error term.

Prophet 설치

우선 Prophet 을 설치해보자. 아나콘다(Anaconda) 환경이 설치되어 있으면 설치는 간단하다. 그렇지만 파이썬 환경은 Cython 등 몇 가지 사전 설치 등이 더 필요하다. (아래는 아나콘다에서 설치하는 방법이며 용량이 다소 크긴 하지만 간단하게 설치하고자 한다면 아나콘다 환경을 권장) 자세한 설치 방법은 여기 참조

conda install -c conda-forge fbprophet

Prophet 사용법

사용법은 간단한다. Prophet이라는 객체를 생성한 후, 시계열 데이터를 학습(fit)하면 된다. 머신러닝에 꼭 필요한 패키지가 scikit-learn 이라는 것인데 Prophet은 scikit-learn 패키지와 인터페이스가 유사하다. 객체 생성에 필요한 여러 가지 설정값과 더불어 해당 객체를 선언하고 데이터를 이용해 학습하면 된다.

m = Prophet(daily_seasonality = True) # create Prophet class 
m.fit(data) # fit the model using time series data

Prophet 시계열 data 의 구성은 단순하다. ds 라는 컬럼에 날짜값을, y라는 컬럼에는 실제 시계열 데이터값을 삽입하면 된다.

데이터를 학습(위 코드에서 m 이라는 객체 변수가 생성되고 객체 내 학습 결과 파라미터들을 포함)했으니 이제 예측이 가능하다. 예측을 원하는 날짜수만 입력하기만 하면 된다.

future = m.make_future_dataframe(periods=365) # days in future
pred = m.predict(future)

예측한 값을 출력하면 아래와 같은 멋진 그래프를 얻을 수 있다.

m.plot(pred)
plt.title("Prediction of the Google Stock Price using the Prophet")
plt.xlabel("Date")
plt.ylabel("Close Stock Price")
plt.show()

보다 자세한 내용은 Prophet 문서 사이트 참고하길 바란다.

이상치 검출

주가 폭락은 시계열 데이터 관점에서는 이상치이다. 평균이나 기대값보다는 한참이나 벗어난 값들이라는 의미이다. Prophet을 이용하면 이러한 이상치 검출을 쉽게 할 수 있다. 위 함수 predict를 하고나면 여러 가지 컬럼들이 생성되는 데, 그 중에 yhat이 예측값이고 yhat_lower는 최소치 그리고 yhat_upper가 최대치 값들이 있다. 이러한 값들을 이용해서 이상치 검출을 한다. 즉, 이상치 검출은 단지 실제 시계열 값 y와 yhat_lower나 yhat_upper와 비교만으로 가능하다. 아래 관련 코드를 살펴보자 (pred, andf 는 파이썬 pandas DataFrame)

andf = pred[['ds', 'trend', 'yhat', 'yhat_lower', 'yhat_upper']]
andf['y'] = y # y는 실제 시계열 리스트

andf['anomaly'] = 0  # anomaly 감지 태그 컬럼 생성
andf.loc[andf['y'] > andf['yhat_upper'], 'anomaly'] = 1
andf.loc[andf['y'] < andf['yhat_lower'], 'anomaly'] = -1

이제 andf[‘anomaly’] 컬럼으로, 비정상적인 (이상치) upper (1)인 시점과 lower (-1) 인 시점들 확인이 가능해졌다.

이상치 중요도 측정

이상치 여부만으로는 조금 부족하다. 여부뿐 아니라 이상치의 정도를 의미하는 중요도(importance)를 측정해 보자. 쉽게 설명하면 약간 이상한 정도와 심하게 이상한 정도를 구별하고자 하는 것이다. 중요도는 y 값과 yhat_upper 과의 차이 또는 y값과 yhat_lower 와의 차이를 y값으로 나눠서 구한다. 다시 말해, 실제 시계열 값과 예측 최대치(또는 최소치)와의 차이에 비례한다. 아래 소스 부분을 확인하면 이해가 될 것이다.

andf['importance'] = 0  # 이상치 중요도 컬럼 추가
andf.loc[andf['anomaly'] == 1, 'importance'] = \
    (andf['y'] - andf['yhat_upper']) / andf['y']
andf.loc[andf['anomaly'] == -1, 'importance'] = \
    (andf['yhat_lower'] - andf['y']) / andf['y']
andf['score'] = andf['anomaly'] * andf['importance']

마무리…

어제까지의 데이터를 이용해 Prophet으로 학습한 후에, 오늘 현재 시점에서의 y값과 비교해, 이상치 여부와 중요도 수치를 구할 수 있다. 이로써, 금일 (특정 종목의) 주식이 폭락한 여부를 자동으로 알 수 있고 그에 따라, 자동으로 매수를 하는 프로그램도 가능하다. (위 설명에 사용된 간단한 샘플 소스)

혹시 위 내용이 도움이 되셨거나 대박 나신 분들을 댓글 공유 좀 해주시면 감사하겠습니다. ㅎ

참고 사이트

Anomaly detection in time series with Prophet library
Time-Series Forecasting: Predicting Stock Prices Using Facebook’s Prophet Model
시계열 예측을 위한 Facebook Prophet 사용하기

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중