[ZeroBase] 시계열데이터 (Time Series Data)

시계열 데이터란?

  • 시계열 데이터란 일정한 시간 동안 수집된 일련의 순차적으로 정해진 데이터 셋의 집합이다.
  • 시계열 데이터의 특징으로는 시간에 관해 순서가 매겨져 있다는 점과, 연속한 관측치는 서로 상관관계를 가지고 있다.

시계열 데이터 분석 목적:

시계열이 갖고 있는 법칙성을 발견해 이를 모형화하고, 또 추정된 모형을 통하여 미래의 값을 forecasting 하는 것!

시계열 데이터 예시:


시계열 데이터 종류 (4가지):

변동요인을 보통 4가지로 가정하면 변동요인을 파악할 수 있다.

  • 추세변동
  • 계절변동
  • 순환변동
  • 불규칙변동

추세변동

  • 시계열의 장기간에 걸친 점진적이고 지속적인 변화 상태를 나타낸 것을 의미함
  • 시간의 흐름에 따른 시계열자료들의 상승경향이나 하강경향의 상태를 의미함

계절변동

  • 관측된 시계열 잘들을 1년 단위 혹은 더 짧은 기간의 주기로 기록 했을 때, 기후 등과 같은 자연의 조건, 사회적 관습, 혹은 제도 등의 영향을 받아서 계절적인 차이를 나타내는 것
  • 시계열 자료에서 주기적인 패턴을 갖고 반복적으로 나타나는 주기 변동
  • 보통 분기별, 월별자료에서 나타남

순환변동

  • 수년간의 간격을 두고 상승과 하락이 주기적으로 나타나는 변동으로 의미
  • 기후 조건, 사회적 관습 등과 같은 계절변동으로 설명되지 않는 장기적인 주기변동
  • 순환변동을 계절변동과 혼동할 수 있겠지만, 계절변동으로 설명되지 않는 장기적인 변동을 의미함.

불규칙변동

  • 사전적으로 예상할 수 없는 특수한 사건에 의해 야기되는 변동(지진, 전쟁, 홍수, 파업)
  • 명확히 설명될 수 없는 요인에 의해 발생되는 우연변동

시계열 데이터 분석 (feat. Fbprophet 사용)

1. 📋Fbprophet 연습!

데이터 생성 후, 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일간의 미래를 예측한 것이다.

학습된 결과를 보아, 이전의 패턴과 유사한 패턴의 그래프가 그려진 것을 확인할 수 있다.


2. 📺시계열 데이터 실전 이용

(1). Web Traffic 예측

  1. 준비:

    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
    )
  2. 데이터 정보 확인

    pinkwin_web.info()

  1. null값 처리

    pinkwink_web = pinkwink_web[pinkwink_web["hit"].notnull()]
  2. 데이터 그려보기

    pinkwink_web["hit"].plot(figsize=(12, 4), grid=True)

  3. 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)
  4. 그래프 시각화

    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차원 함수인 보라색이 가장 예측을 잘 한 것으로 확인할 수 있다.

  5. 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)

  1. 결과 확인


(2). 주식 데이터 예측

데이터 출처 : yahoo finance

목적: 주식 데이터를 사용하여 해당 종목의 향후 가격을 예측해보자.

  1. 데이터 불러오기

    # 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()
  2. 데이터 확인

    KIA["Close"].plot(figsize=(12,10), grid=True)

  1. accuracy 확인

    가져온 데이터 중 일부 데이터만을 사용하여 가장 최근 데이터의 경향 확인해보기

    # ~ 2017-11-30일까지의 데이터만 불러오기
    KIA_trunc = KIA[:"2017-11-30"]
    KIA_trunc.tail()
  2. 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)
  3. 예측 결과 확인:

검은 점들을 기본으로 하여 향후 90일을 예측한 결과이다. 실제 데이터인 파란색 선이 오차범위내에 포함되어 있는 것으로 보아 예측을 잘 한 것 같다.
  1. m.plot_components(forecast):

KIA는 화요일과 수요일에 가장 높게 종목이 오르며, 여름 오기전인 월달에 가장 주가가 높다는 것을 알 수 있다. 시간 단위로 KIA 종목을 확인한다면, 오전 9시부터  장 마감 시간인 오후 3시 30분까지 일정한 패턴으로 요동치는 것을 확인할 수 있다.

(3). 특이한 형태의 시계열 데이터 예측

  1. 데이터 불러오기 & 데이터 확인

    df = pd.read_csv(".......", index_col = 0)
    df

    데이터를 그래프화 하였을 때, 로그함수의 성질을 발견 할 수 있다.

  2. 예측

    m = Prophet(growth="logistic", daily_seasonality=True)
  3. 예측 결과 확인

    future = m.make_future_dataframe(periods=1826)
    future["cap"] = 8.5
    forecast = m.predict(future)
    m.plot(forecast)

좋은 웹페이지 즐겨찾기