AI/머신러닝

시계열 다루기 2일차

edcrfv458 2025. 2. 27. 15:50

목차

  1. 통계적 시계열 모델 전처리
  2. ARIMA 모델
  3. 다중 타겟 예측 모델 (Multi Outuput Regressor, Multi Output Classifier)
  4. Prophet

통계적 시계열 모델 전처리

 

statsmodels 라이브러리

  • 시계열 데이터를 추세, 계절성, 불규칙성 성분으로 나누어 plot 그리는 작업
    • period: 1년 기준으로 주기를 나타내는 변수 (월별이면 12, 주별이면 52, 일별이면 365)
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(df2['#Passengers'],
 model='additive', period=12)

# 분해된 성분 출력
fig = decomposition.plot()
plt.show()
  1. Additive (덧셈 모델)
    1. 시계열 데이터 = 추세 + 계절성 + 잔차 (변화량이 일정한 크기로 발생하는 데이터에 적합)
    2. 계절성의 크기가 일정한 경사용
  2. multiplicative (곱셈 모델)
    1. 시계열 데이터 = 추세 × 계절성 × 잔차 (분들이 곱해지는 모델로, 변화가 비율적으로 발생하는 데이터에 적합)
    2. 계절성이 증가하거나 감소하는 경우 사용
  3. 잔차 (Residuals)
    1. 원본 데이터에서 추세와 계절성을 제거한 후 남는 변동성
    2. 만약, 잔차(Residual)에 특정 패턴이 보이면 추가적인 계절성이나 주기성이 존재할 가능성이 있음

 

비정상성과 정상성

  • 기본적으로 통계적 데이터에서는 비정상 데이터를 정상성 데이터로 변환해야 함
  • 하지만 통계적 모델이 아닌 경우 변환하지 않아도 됨
  • 비정상성 데이터
    • 시간이 지날수록 데이터의 평균이 증가/감소 하는 경우
    • 계절성이 포함되어 특정 주기마다 패턴이 달라지는 경우
    • 시간이 지날수록 데이터의 변동성이 증가하는 경우
  • 정상성 데이터
    • 안정적인 데이터
    • 추세나 계절성이 없고, 데이터의 평균과 분산이 일정한 경우
    • 시계열의 통계적 특징(평균, 분산, 자기 상관)이 변하지 않음
  • 정상적이지 않은 시계열의 데이터의 경우 처리
    • 로그 변환: 분산이 커지는 경향을 가지는 시계열을 안정화
    • 차분: 추세를 제거하는 효과 (.diff, ...)
    • 계절 차분: 계절 추세를 제거하는 효과

 

변환해야 하는 이유

  • 시계열 데이터가 정상성을 띠고 있어야 ARIMA 분석을 통해 미래 시계열 값 예측이 가능
  • 비정상성을 띤다면 평균과 분산이 다르기 때문에 임의의 시점 t-1, t에서 얻은 모델은 t+1 ~ t+n 에서 사용할 수 없음

 

변환하는 방법

  1. 차분: 추세 제거
    1. 1차, 2차 ... 
  2. 로그 변환: 지수적 성장 또는 비대칭적인 분포를 선형적이고 정규 분포에 가까운 형태로 변환
  3. 로그 차분: 시계열 데이터에서 추세와 변동성을 동시에 안정화
    1. 로그 변환 후 차분
  4. 계절 차분: 일정한 주기로 반복되는 계절성 제거
    1. .diff(periods=12) : 계절성 제거

ARIMA 모델

 

ACF, PACF

  • ACF (자기 상관 함수)
    • 시계열 데이터의 특정 시점과 이전 시점 간의 상관 관계를 나타내는 함수
    • 시계열 데이터의 전체적인 패턴 파악하는데 유용하며, 데이터가 얼마나 주기적으로 반복되는지 확인 가능
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf

# ACF (자기상관 함수) 그래프 그리기
plt.figure(figsize=(8, 6))
plot_acf(df, lags=10, ax=plt.gca())
plt.title("ACF (자기상관 함수)")
plt.show()

#lags=1: 현재 시점과 바로 이전 시점(1단계 이전)의 자기상관.
#lags=2: 현재 시점과 2단계 이전 시점의 자기상관.
#lags=20: 현재 시점과 20단계 이전까지의 자기상관을 모두 계산하여 그림.
  • PACF (부분 자기상관 함수)
    • 자기상관 함수에서 단순히 이전 시점 간 상관만을 고려하는 것이 아님
    • 특정 시점의 값이 이전 값들과 어떤 관계가 있는지를 고려하는 직접적인 상관만을 추출하는 함수
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_pacf

# PACF (부분 자기상관 함수) 그래프 그리기
plt.figure(figsize=(8, 6))
plot_pacf(df, lags=10, ax=plt.gca())
plt.title("PACF (부분 자기상관 함수)")
plt.show()
  • lags 파라미터 값은 보통 주기보다는 크고 2배보다는 작게..? 설정

 

ARIMA 모델

  • 시계열 데이터의 자기상관성(AR), 차분(D), 이동 평균(MA) 이용해 미래 값을 예측하는 시계열 통계 모델
  • ARIMA(p, d, q) 
    • d: 시계열 plot 보고 정상성 여부 확인하고, 차분 진행하고, 차분 후의 plot을 보고 여부를 확인하는 프로세스 진행
      • 이미 차분한 데이터를 넣는다면 d = 0
    • p와 q의 경우는 보통 ACF, PACF를 보고 결정
      • p: PACF에서 첫 번째 유의미한 지점(즉, 자기상관이 급격히 0으로 떨어지는 시점)
      • q: ACF에서 첫 번째 유의미한 지점(즉, 자기상관이 급격히 0으로 떨어지는 시점)
  • 결론: ARIMA(1, 2, 0)
    • ACF와 PACF를 통해 비정상성 분석이 가능
      • ACF 값이 서서히 감소하는 패턴 ➡️ 추세를 포함하고 있을 가능성이 높음
      • 여러 Lag(시차)에서 지속적으로 유의미한 값 ➡️ 추세 제거 필요
      • 특정 주기마다 강한 피크를 가짐 ➡️ 계절성 제거 필요
  • AR(p): 현재 값이 과거 값들의 선형 결합으로 표현되는 모델 (추세가 강한데이터)
  • MA(q): 현재 값이 과거 오차(White noise)의 선형 결합으로 표현되는 모델
    • 과거 오차 기반으로 미래 예측
  • AR(p) + MA(q): 자기회귀(AR) + 이동 평균(MA) 요소 동시에 반영
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA


# ARIMA 모델 정의 (p=1, d=1, q=1 예시)
model = ARIMA(df, order=(1, 1, 1))  # p=1, d=1, q=1
model_fit = model.fit()

# 예측 (5단계 예측)
forecast = model_fit.forecast(steps=5)

# 예측 결과 출력
print("예측 결과:", forecast)

 

SARIMA 모델

  • ARIMA 모델에 계절성 추가한 모델
  • 수식
    • (p, d, q): ARIMA와 동일
    • (P, D, Q, s): 계절성 차수
      • P: 계절성 자기회귀
      • D: 계절 차분
      • Q: 계절성 이동 평균
      • s: 계절 주기
        • 찾기
          • s 결정: 데이터 주별이면 52, 월별이면 12
          • D 찾기: 계절 주기만큼 차분 수행 후 정상성 확보되면 D=1, 필요하면 추가 차분
          • P, Q 찾기: 계절 차분 후, ACF/PACF 에서 계절 패턴 분석하여 결정
  • 특징
    • 계절성이 있는 데이터에 적합
    • 비정상성 + 계절성까지 해결 가능

다중 타겟 예측 모델

 

MultiOutputRegressor, MultiOutputClassifier

  • MultiOutputRegressor: 다중 출력 회귀 위한 모델
  • MultiOutputClassifier: 다중 출력 분류 위한 모델
from sklearn.multioutput import MultiOutputRegressor
from sklearn.multioutput import MultiOutputClassifier

# XGBoost 모델을 MultiOutputRegressor로 감싸기
xgb_model = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=100, random_state=42)
multi_output_model = MultiOutputRegressor(xgb_model)

# 모델 학습 (X -> Y 16개 예측)
multi_output_model.fit(X_train, Y_train)

# 예측 수행
Y_pred = multi_output_model.predict(X_test)

# 평가 (예: RMSE)
rmse_list = [mean_squared_error(Y_test.iloc[:, i], Y_pred[:, i], squared=False) for i in range(Y.shape[1])]
print(f"전체 Y값 평균 RMSE: {np.mean(rmse_list):.4f}")

prophet 모델

 

Facebook Prohet

  • 트렌드, 계절성, 휴일 효과 등을 반영해 자동으로 예측 가능한 모델
  • 장점
    • 빠르고 쉬운 설정(자동화된 하이퍼 파라미터 튜닝 제공)
    • 결측치와 이상치에 강함
    • 계절성(주간, 월간, 연간) 및 공휴일 등의 외부 요인 반영 가능
  • 단점
    • 단순한 선형 모델 기반으로 복잡한 패턴 학습하는데 한계
    • 데이터의 양이 많아야 신뢰도 높은 예측 가능
from fbprophet import Prophet
import pandas as pd

# 데이터 준비
df = pd.read_csv('time_series.csv')  # 'ds' 컬럼(날짜), 'y' 컬럼(값)

# 모델 생성 및 학습
model = Prophet()
model.fit(df)

# 미래 데이터 예측
future = model.make_future_dataframe(periods=30)  # 30일 예측
forecast = model.predict(future)

# 결과 시각화
model.plot(forecast)