시계열이 갖고 있는 법칙성을 발견해 이를 모형화하고, 또 추정된 모형을 통하여 미래의 값을 forecasting 하는 것!
변동요인을 보통 4가지로 가정하면 변동요인을 파악할 수 있다.
데이터 생성 후, fbprophet 사용해보기
# conda 가상환경에 datareader설치
conda install pandas -datareader
# terminal 혹은 conda환경에서 fbprophet 설치
pip install fbprophet
import fbprophet import Prophet
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
#시작 위치 및 간격 설졍
time = np.linspace(0, 1, 365 *2)
result = np.sin(2*np.pi * 12 * time)
# 날짜 데이터 생성
ds = pd.date_range("2018-01-01", periods=365*2, freq="D")
df = pd.DataFrame({"ds" : ds, "y": result})
# 년 단위로 학습, 하루 단위로 학습
m = Prophet(yearly_seasonality=True, daily_seasonality=True)
# 예측된 모델에 위에서 생성한 df 적용
m.fit(df)
# 앞으로의 30일 데이터 변동사항 예측
future=m.make_future_dataframe(periods=30)
forecast = m.predict(future)
# 결과 확인
m.plot(forecast)
점과 선으로 그려진 그래프는 학습에 사용된 데이터를 뜻하며, 선으로만 그려진 그래프는 향후 30일간의 미래를 예측한 것이다.
학습된 결과를 보아, 이전의 패턴과 유사한 패턴의 그래프가 그려진 것을 확인할 수 있다.
준비:
import pandas as pd
import pandas_datareader as web
import numpy as np
import matplotlib.pyplot as plt
from fbprophet import Prophet
from datetime import datetime
%matplotlib inline
pinkwink_web = pd.read_csv(
"..웹 트래픽 정보가 있는 csv 파일", encoding="utf-8", thousands=",", names=["date", "hit"], index_col = 0
)
데이터 정보 확인
pinkwin_web.info()
null값 처리
pinkwink_web = pinkwink_web[pinkwink_web["hit"].notnull()]
데이터 그려보기
pinkwink_web["hit"].plot(figsize=(12, 4), grid=True)
trend 분석을 시각화하기 위한 x축 값 만들기
time = np.arange(0, len(pinkwink_web))
traffic = pinkwin_web["hit"].values
fx = np.linspace(0, time[-1], 1000)
# 몇차원 그래프에서 가장 예측을 잘 하는지 1차, 2차, 3차, 15차, 20차원 그래프로 테스트
fp1 = np.polyfit(time, traffic, 1)
f1 = np.poly1d(fp1)
fp2 = np.polyfit(time, traffic, 2)
f2 = np.poly1d(fp2)
fp3 = np.polyfit(time, traffic, 3)
f3 = np.poly1d(fp3)
fp15 = np.polyfit(time, traffic, 15)
f15 = np.poly1d(fp15)
fp20 = np.polyfit(time, traffic, 20)
f20 = np.poly1d(fp20)
그래프 시각화
plt.figure(figsize=(12, 4))
plt.scatter(time, traffic, s=10)
plt.plot(fx, f1(fx), lw=4, label='f1')
plt.plot(fx, f2(fx), lw=4, label='f2')
plt.plot(fx, f3(fx), lw=4, label='f3')
plt.plot(fx, f15(fx), lw=4, label='f15')
plt.plot(fx, f20(fx), lw=4, label='f20')
plt.grid(True, linestyle="-", color="0.75")
plt.legend(loc=2)
plt.show()
20차원 함수인 보라색이 가장 예측을 잘 한 것으로 확인할 수 있다.
fbprophet 사용하여 미래 예측
m = Prophet(yearly_seasonality=True, daily_seasonality=True)
# 새로운 DataFrame 생성
df = pd.DataFrame({"ds":pinkwink_web.index, "y": pinkwink_web["hit"]})
# 인덱스값 새로 설정한 후 저장
df.reset_index(inplace=True)
df["ds"] = pd.to_datetime(df["ds"], format="%y. %m. %d.")
# 미래 예측 (60일)
future = m.make_future_dataframe(periods=60)
# 예측 결과는 상한/하한의 범위를 포함해서 얻어진다.
forecast = m.predict(future)
forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail()
m.plot(forecast)
데이터 출처 : yahoo finance
목적: 주식 데이터를 사용하여 해당 종목의 향후 가격을 예측해보자.
데이터 불러오기
# yahoo finance 설치
!pip install finance
# 기아 자동차의 종목코드를 가지고 기간을 입력한다.
import yfinance as yf
from pandas_datareader import data
yf.pdr_override()
start_date = "2010-03-01"
end_date = "2018-02-28"
KIA = data.get_data_yahoo("000270.KS", start_date, end_date)
KIA.head()
데이터 확인
KIA["Close"].plot(figsize=(12,10), grid=True)
accuracy 확인
가져온 데이터 중 일부 데이터만을 사용하여 가장 최근 데이터의 경향 확인해보기
# ~ 2017-11-30일까지의 데이터만 불러오기
KIA_trunc = KIA[:"2017-11-30"]
KIA_trunc.tail()
fbprophet 이용하여 미래 예측
# forecast를 위한 준비
df = pd.DataFrame({"ds": KIA_trunc.index, "y":KIA_trunc["Close"]})
df.reset_index(inplace=True)
# 필요없는 column 삭제 특성상 필요없기에 사
del df["Date"]
#
m = Prophet(yearly_seasonality=True, daily_seasonality=True)
# 향후 90일간의 데이터 예측
future = m.make_future_dataframe(periods=90)
forecast = m.predict(future)
m.plot(forecast)
예측 결과 확인:
검은 점들을 기본으로 하여 향후 90일을 예측한 결과이다. 실제 데이터인 파란색 선이 오차범위내에 포함되어 있는 것으로 보아 예측을 잘 한 것 같다.
KIA는 화요일과 수요일에 가장 높게 종목이 오르며, 여름 오기전인 월달에 가장 주가가 높다는 것을 알 수 있다. 시간 단위로 KIA 종목을 확인한다면, 오전 9시부터 장 마감 시간인 오후 3시 30분까지 일정한 패턴으로 요동치는 것을 확인할 수 있다.
데이터 불러오기 & 데이터 확인
df = pd.read_csv(".......", index_col = 0)
df
데이터를 그래프화 하였을 때, 로그함수의 성질을 발견 할 수 있다.
예측
m = Prophet(growth="logistic", daily_seasonality=True)
예측 결과 확인
future = m.make_future_dataframe(periods=1826)
future["cap"] = 8.5
forecast = m.predict(future)
m.plot(forecast)