헬창 개발자

7. 시계열 데이터를 다뤄보자 본문

데이터 분석

7. 시계열 데이터를 다뤄보자

찬배 2022. 4. 27. 23:18
💡
학습환경은 코랩에서 진행하였습니다.

 

학습 목표

  • 페이스북에서 만든 prophet이라는 LSTM 모델를 이용하여 주가를 예측해보자

0. 시계열 & 예측모델 ?????????????

  • 시계열 데이터란?

일정한 시간동안 수집 된 일련의 순차적으로 정해진 데이터 셋의 집합 입니다.

시계열 데이터의 특징으로는 시간에 관해 순서가 매겨져 있다는 점과, 연속한 관측치는 서로 상관관계를 갖고 있습니다.

시계열 데이터의 분석 목적은 시계열이 갖고 있는 법칙성을 발견해 이를 모형화하고, 또 추정된 모형을 통하여 미래의 값을 예측하는 것입니다.

 

  • 시계열 예측모델이란?

이전에 관측된 값을 기반으로 미래의 값을 예측할 수 있는 모형이다.

RNN(Recurrent Neural Network) 순환 신경망

Xt: 입력층의 입력 벡터, Ht: 출력층의 출력 벡터, A: RNN 셀 / 메모리 셀

 

학습한 데이터를 가지고 그 다음 순서에 정답데이터로 사용해 학습을 이어가는 신경망이다.

RNN은 비교적 short sequence에서만 효과를 보이는 단점이 존재하는데 time step이 길어질 수록 앞의 정보가 뒤로 충분히 전달되지 못하는 현상이 발생하게 된다.

그림처럼 첫번 째 입력값인 x1의 정보량의 깊이가 time step이 흐를 수록 색이 얕아지고 정보량이 손실되어가는 과정을 의미한다.

뒤로 갈수록 x1의 정보량은 손실되고, long sequence의 경우에는 x1의 전체 정보에 대한 영향력은 의미가 미미해진다. 이를 장기 의존성 문제라고 한다.

 

LSTM(Long Short Term Memory) 장단기 기억 신경망

 

RNN은 단기 메모리만을 가지고 학습을 했다면, LSTM은 단기 메모리와 장기 메모리를 나눠 학습 후, 두 메모리를 병합해 이벤트 확률을 예측한다. 그래서 과거의 정보를 훨씬 잘 반영한다는 장점이 있다. LSTM 모델 내에는 4가지 게이트가 존재한다.

  1. forget gate 장기메모리에서 학습에 크게 고려하지 않아도 될 정보를 삭제
  1. input gate 추가되는 새로운 정보 중에서 '정말 필요한 정보'만을 가져가기 위한 게이트
  1. cell state update 단기메모리와 이벤트가 함께 들어가 최근에 학습한 정보 반영 + 불필요 정보 삭제
  1. output gate 기억 셀에서 얼마만큼 다음 은닉 상태 벡터로 전달

 

1. 시계열 데이터 모델이 필요한 이유

주식 거래로 수익을 내기 위해서는 팔 때와 살 때를 합리적으로 결정해야한다.

이를 위해서 주식 가격을 정확하게 모델링해야 한다. 시계열 데이터 모델링이 필요한 이유다.

과거 데이터를 순서대로 보고 미래에 어떻게 될지 정확하게 예측하기 위해서 적합한 기계학습 모델이 필요하다.

 

시계열 데이터 학습 중요 요인

추세(Trend)란?

데이터가 장기적으로 증가하거나 감소하는 것이며, 추세가 꼭 선형적일 필요는 없다.

순환(Cycle)이란?

경기변동과 같이 정치, 경제, 사회적 요인에 의한 변화로, 일정 주기가 없으며 장기적인 변화 현상이다.

계절성(Seasoanl)이란?

주, 월, 분기, 반기 단위 등 특정 시간의 주기로 나타나는 패턴이다.

불규칙요소(Random, Residual)란?

설명될 수 없는 요인 또는 돌발적인 요인에 의하여 일어나는 변화로, 예측 불가능한 임이의 변동을 의미한다. 원래 데이터에서 추세, 순환, 계절성은 뺀 나머지를 불규칙 요소라 한다.

 

 

사용 모델 : Facebook Prophet

Prophet은 Additive 모델이라는 모델링 방법에 기반한 시계열 예측모델로 시계열 데이터의 트렌드성(연간/월간/일간)을 예측하는 것에 초점이 맞추어져 있다.

Additive 모델 : 회귀모델 종류

2. 시계열 분석으로 주식 데이터 분석하기

  • 모듈 import
#시각화 코드
import platform
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
plt.rcParams['axes.unicode_minus'] = False
from fbprophet import Prophet #사용 모델
#코랩 환경에서 pip install Prophet 설치진행

 

  • 주식 데이터를 가져오자
import yfinance as yf # 주식 데이터 모듈
samsung_df = yf.download('005930.KS', #삼성전자 코드
                      start='2020-01-01',
                      end='2022-04-21',
                      )

samsung_df = samsung_df[["Close"]] # 종가 데이터만 가져옴
samsung_df = samsung_df.reset_index()
samsung_df.columns = ['ds', 'y']

samsung_df

 

  • 삼성전자 주식 그래프 시각화
fig, ax = plt.subplots(figsize=(15, 8))
samsung_df.plot(ax=ax)

  • 데이터셋 분류
samsung_train_df = samsung_df[:500] # 훈련 셋
samsung_test_df = samsung_df[500:] # 테스트 셋

 

 

 

  • 모델 학습
prophet = Prophet(seasonality_mode = 'additive', # 계절성 모델
                 yearly_seasonality=26, # 연 계절성
                 weekly_seasonality=3, # 주 계절성
                 daily_seasonality=10, # 일 계절성
                 seasonality_prior_scale = 4, # 계절의 유연성을 제어하는 파라미터
                 changepoint_prior_scale=0.2, # 추세에 따라 데이터를 유연하게 반영하는 파라미터
                 holidays_prior_scale=3 # 휴일의 영향에 따라 유연성을 조절하는 파라미터
                  ).add_country_holidays(country_name='KR') # 한국 휴일 추가

prophet.fit(samsung_train_df)

모델의 결과를 향상 시킬려면 다음과 같은 방법이 필요하다.

  1. 데이터의 상한 하한의 설정
  1. 변동 포인트의 설정
  1. 계절성의 조정
  1. 특별 이벤트의 추가
  1. 신뢰 구간의 조정

 

자세한 하이퍼 파라미터 설명은 ...

https://facebook.github.io/prophet/docs/saturating_forecasts.html

 

future_data = prophet.make_future_dataframe(periods = 70, freq = 'd') #70일 데이터 예측
forecast_data = prophet.predict(future_data)
forecast_data[['ds','yhat', 'yhat_lower', 'yhat_upper']].tail(5)

 

  • fbprophet 모델의 학습 결과를 시각화
fig1 = prophet.plot(forecast_data)

fbprophet 모델의 학습 결과를 시각화한 결과이다. 그래프의 검은 점은 실제 가격을 나타낸 것이고, 파란 선은 예측 가격을 나타낸 것이다.

학습 데이터셋에 대해서는 거의 정확한 예측을 하고 있다. 하지만 시계열 데이터 분석에서 학습 데이터를 잘 예측하는건 큰 의미가 없다.

 

fig2 = prophet.plot_components(forecast_data)

다음 그래프는 fbprophet에서 제공하는 트렌드 정보 시각화 그래프이다.

앞서 seasonality_mode 파라미터를 설정해놓은 경우에만 이 시각화가 가능하다.

우리는 이를 통해 시계열 데이터가 어떤 흐름을 가지고 변화하는지를 살펴볼 수 있다.

 

  • Testset 평가

이번에는 테스트셋을 평가 해보자. 다음 코드의 실행 결과를 보자.

plt.figure(figsize=(15, 10))

# 예측 70일의 데이터 
pred_y = forecast_data.yhat.values[-70:]

# 실제 70일의 데이터 
test_y = samsung_test_df.y.values

# 예측 70일의 데이터 최소값
pred_y_lower = forecast_data.yhat_lower.values[-70:]
# 실제 70일의 데이터 최대값
pred_y_upper = forecast_data.yhat_upper.values[-70:]

# 모델이 예측한 가격 그래프
plt.plot(pred_y, color = 'gold')

# 모델이 예측한 최저 가격 그래프
plt.plot(pred_y_lower, color = 'red')

# 모델이 예측한 최고 가격 그래프
plt.plot(pred_y_upper, color = 'blue')

# 실제 가격 그래프
plt.plot(test_y, color = 'green')

plt.legend(['예측값', '최저값','최대값','실제값'])
plt.title("값 비교")

 

  • RMSE로 평가 평균 제곱근 오차(Root Mean Square Error; RMSE)를 의미하는 RMSE를 구해보자.
from sklearn.metrics import mean_squared_error, r2_score
from math import sqrt

rmse = sqrt(mean_squared_error(pred_y, test_y))
print(rmse)

 

  • 파라미터 미세조정을 안한다면????????????

10일치 데이터로 평가

3. 마무리

주식 시장은 매우 예측 불가하고 휘발성이다.

개인이 기본적인 인공지능으로 시장을 예측하기엔 불가능에 가깝다.

인공지능으로 예측을 했다면 누구나 부자가 됐을것이다.

주식 가격을 예측하는게 아니고 대응의 영역인것 같다.

Comments