logo

시계열 예측

시계열 예측

기본 예측 기법

  • 실습 데이터 준비: (맥주 생산량)
    beer = pd.read_excel('beer.xlsx', parse_dates=True, index_col='quarter')
    # 예측할 미래 시점(20분기) 인덱스 생성
    future = pd.date_range(beer.index[-1], periods=20, freq='Q') # 'Q': 분기말 빈도
    
  • 평균 기법 (Average Method): 과거 전체 데이터 평균으로 미래 값 예측.
    pred_avg = pd.DataFrame({
        'production': beer.production.mean()}, 
        index=future)
    beer.production.plot()
    pred_avg.production.plot()
    
  • 단순 기법 (Naïve Method): 마지막 관측 값으로 미래 값 예측. (랜덤 워크 시 최적)
    pred_naive = pd.DataFrame({
        'production': beer.production.iloc[-1]}, 
        index=future)
    beer.production.plot()
    pred_naive.production.plot()
    
  • 계절성 단순 기법 (Seasonal Naïve Method): 마지막 동일 계절 값으로 예측.
    import numpy as np
    # 마지막 1년(4분기) 값 반복 사용 (np.tile: 배열 반복)
    last_season = beer.production.iloc[-4:]
    pred_seasonal_naive = pd.DataFrame({
        'production': np.tile(last_season, 5)}, 
        index=future) # 20분기=5년
    beer.production.plot()
    pred_seasonal_naive.production.plot()
    
  • 표류 기법 (Drift Method): 마지막 관측 값 + 과거 평균 변화량(추세) 적용 예측.
    num = len(beer.production) - 1
    drift = (beer.production.iloc[-1] - beer.production.iloc[0]) / num # 전체 기간 평균 변화량
    last = beer.production.iloc[-1]
    pred_drift = pd.DataFrame({
        'production': last + np.arange(1, 21) * drift}, 
        index=future) # 1~20 시점 예측
    beer.production.plot()
    pred_drift.production.plot()
    
  • 표류 + 계절성 단순 기법 결합: 계절성 예측값 + 표류 예측값.
    pred_drift_seasonal = pd.DataFrame(
        {'production': pred_seasonal_naive['production'] + np.arange(1, 21) * drift}, 
        index=future)
    beer.production.plot()
    pred_drift_seasonal.production.plot()
    

Prophet

  • Facebook 개발 시계열 예측 라이브러리.
  • 설치: conda install -y -c conda-forge prophet (또는 pip install prophet)
  • 특징:
    • 시계열 = 추세(trend) + 주기적변화(seasonality) + 휴일효과(holiday) 분해 모델링.
    • 추세 변화점(changepoint) 자동/수동 감지.
    • 정상 시계열 아니어도 사용 가능.
    • 다양한 옵션(계절성 주기, 휴일 등) 설정 용이.
  • 기본 사용법:
    from prophet import Prophet
    import pandas as pd
    
    # 데이터 로드 (컬럼명 'ds', 'y' 필수)
    # df = pd.read_excel('manning.xlsx') # 예시 데이터
    # df.rename(columns={'Date': 'ds', 'Visits': 'y'}, inplace=True) # 컬럼명 변경 필요시
    
    # 모델 생성 및 학습
    m = Prophet()
    m.fit(df)
    
    # 미래 날짜 생성
    future = m.make_future_dataframe(periods=365) # 향후 365일 예측
    
    # 예측 수행
    forecast = m.predict(future)
    
    # 예측 결과 확인 (주요 컬럼)
    print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
    # ds:날짜, yhat:예측값, yhat_lower/upper: 불확실성 구간(신뢰구간 유사)
    
    # 예측 결과 시각화
    fig1 = m.plot(forecast)
    plt.show()
    
    # 성분 분해 시각화 (추세, 주별/연별 계절성 등)
    fig2 = m.plot_components(forecast)
    plt.show()
    
  • 추세 변화점 (Changepoint):
    • 자동 감지 시각화:
      from prophet.plot import add_changepoints_to_plot
      fig = m.plot(forecast)
      a = add_changepoints_to_plot(fig.gca(), m, forecast) # gca(): 현재 그래프 축 가져오기
      plt.show()
      
    • 수동 지정:
      m = Prophet(changepoints=['2014-01-01']) # 특정 날짜 지정
      # ... fit, predict, plot ...
      
  • 휴일 효과:
    • 휴일 정보 담은 DataFrame 별도 생성 (컬럼: holiday, ds, lower_window, upper_window).
    • 모델 생성 시 holidays 인자 전달.
      # h1, h2: 플레이오프, 슈퍼볼 날짜 DataFrame (슬라이드 311 참고)
      # holidays = pd.concat([h1, h2])
      m = Prophet(holidays=holidays)
      # ... fit, predict, plot_components ...
      
    • 국가별 공휴일 자동 추가:
      m = Prophet()
      m.add_country_holidays(country_name='US') # 미국 공휴일 추가
      # ... fit, predict ...
      
  • 계절성 옵션:
    • 기본: 연(yearly), 주(weekly), 일(daily) 자동 감지 및 적용.
    • 끄기: m = Prophet(weekly_seasonality=False)
    • 임의 주기 추가:
      # name:이름, period:주기(일), fourier_order: 복잡도(클수록 변동성 높음)
      m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
      
  • 조건부 계절성: 특정 조건 만족 시에만 적용되는 계절성.
    • 데이터에 조건 열 추가 (on_season, off_season 등).
    • add_seasonalitycondition_name 지정.
      # 예: 시즌 중에만 적용되는 주별 계절성
      m.add_seasonality(name='weekly_on_season', period=7, fourier_order=3,
                        condition_name='on_season')
      
  • 외부 독립변수(Regressor) 추가: (미래 값 알아야 예측 가능)
    m = Prophet()
    m.add_regressor('Unemployment') # 실업률 변수 추가
    m.add_regressor('Income')      # 소득 변수 추가
    m.fit(df) # 학습 데이터에는 해당 변수 포함되어야 함
    
    # 예측 시 future 데이터프레임에도 해당 변수 값 필요
    # forecast = m.predict(future_with_regressors)
    
    # 추가된 독립변수 계수 확인
    from prophet.utilities import regressor_coefficients
    print(regressor_coefficients(m))
    
  • 성장 한계 설정 (Logistic Growth): 데이터가 특정 상한/하한 수렴 시.
    • 데이터에 'cap'(상한), 'floor'(하한) 열 추가.
    • 모델 생성 시 growth='logistic' 지정.
      df['cap'] = 8.5 # 상한값 설정
      m = Prophet(growth='logistic')
      m.fit(df)
      # 예측 시 future에도 'cap' 열 필요
      # future['cap'] = 8.5
      # forecast = m.predict(future)
      # m.plot(forecast)