075 단변량 시계열 예측
키워드: 단변량, univariate
개요
단변량 시계열 예측은 하나의 변수만 사용하여 미래 값을 예측하는 방법입니다. 과거의 자기 자신 값만으로 미래를 예측하는 가장 기본적인 시계열 예측 방법론입니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
pycaret[full]>=3.0
단변량 vs 다변량
단변량 (Univariate):
y(t+1) = f(y(t), y(t-1), y(t-2), ...)
- 자기 자신의 과거 값만 사용
- 외부 변수 없음
다변량 (Multivariate):
y(t+1) = f(y(t), x1(t), x2(t), ...)
- 외부 변수 (exogenous) 포함
- 더 많은 정보 활용
데이터 준비
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 075 항공 승객 데이터 시뮬레이션
np.random.seed(42)
dates = pd.date_range('2010-01-01', periods=144, freq='MS') # 12년 월별
# 075 구성 요소
trend = np.linspace(100, 500, len(dates)) # 상승 추세
seasonality = 50 * np.sin(2 * np.pi * np.arange(len(dates)) / 12) # 연간 계절성
multiplicative_seasonal = 1 + 0.2 * np.sin(2 * np.pi * np.arange(len(dates)) / 12)
noise = np.random.normal(0, 20, len(dates))
# 075 승법 모델
values = trend * multiplicative_seasonal + noise
data = pd.DataFrame({
'date': dates,
'passengers': values
})
data.set_index('date', inplace=True)
# 075 시각화
plt.figure(figsize=(14, 5))
plt.plot(data.index, data['passengers'])
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.title('Monthly Airline Passengers')
plt.grid(True, alpha=0.3)
plt.savefig('airline_data.png', dpi=150)
print(f"데이터 기간: {data.index.min()} ~ {data.index.max()}")
print(f"데이터 수: {len(data)}")
기본 예측 방법
from pycaret.time_series import *
# 075 환경 설정
ts = setup(
data=data,
target='passengers',
fh=12, # 12개월 예측
fold=3,
seasonal_period=12,
session_id=42,
verbose=False
)
# 1. Naive (마지막 값 반복)
naive = create_model('naive')
# 2. Seasonal Naive (작년 같은 달 값)
snaive = create_model('snaive')
# 3. Polynomial Trend (추세만)
polytrend = create_model('polytrend')
통계 모델
ARIMA
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 Auto ARIMA (자동 파라미터 선택)
arima = create_model('auto_arima')
# 075 예측
pred_arima = predict_model(arima)
print(pred_arima)
# 075 시각화
plot_model(arima, plot='forecast')
지수 평활 (Exponential Smoothing)
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 지수 평활
exp_smooth = create_model('exp_smooth')
# 075 ETS (Error, Trend, Seasonality)
ets = create_model('ets')
# 075 비교
plot_model(exp_smooth, plot='forecast')
plot_model(ets, plot='forecast')
Theta
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 Theta 방법
theta = create_model('theta')
plot_model(theta, plot='forecast')
Prophet
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 Facebook Prophet
prophet = create_model('prophet')
# 075 예측
pred_prophet = predict_model(prophet)
# 075 시각화
plot_model(prophet, plot='forecast')
# 075 구성 요소 분해
plot_model(prophet, plot='decomp')
머신러닝 모델
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 선형 회귀 (계절성 제거 후)
lr = create_model('lr_cds_dt')
# 075 Ridge (계절성 제거 후)
ridge = create_model('ridge_cds_dt')
# 075 LightGBM (계절성 제거 후)
lgbm = create_model('lightgbm_cds_dt')
# 075 Random Forest
rf = create_model('rf_cds_dt')
모델 비교
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, fold=3, seasonal_period=12,
session_id=42, verbose=False)
# 075 전체 모델 비교
best = compare_models()
# 075 특정 모델만 비교
selected_models = compare_models(
include=['naive', 'snaive', 'arima', 'exp_smooth', 'ets', 'prophet', 'lightgbm_cds_dt']
)
예측 결과 시각화
from pycaret.time_series import *
import matplotlib.pyplot as plt
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 여러 모델 예측
models_dict = {
'ARIMA': create_model('auto_arima'),
'ETS': create_model('ets'),
'Prophet': create_model('prophet'),
'LightGBM': create_model('lightgbm_cds_dt')
}
# 075 예측
predictions = {}
for name, model in models_dict.items():
pred = predict_model(model)
predictions[name] = pred['y_pred'].values
# 075 비교 시각화
plt.figure(figsize=(14, 6))
# 075 실제 데이터
plt.plot(data.index, data['passengers'], label='Actual', color='black', linewidth=2)
# 075 예측 기간
future_dates = pd.date_range(data.index[-1] + pd.DateOffset(months=1),
periods=12, freq='MS')
colors = ['blue', 'red', 'green', 'orange']
for (name, pred), color in zip(predictions.items(), colors):
plt.plot(future_dates, pred, label=name, color=color, linestyle='--', linewidth=1.5)
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.title('Model Comparison - 12 Month Forecast')
plt.legend()
plt.grid(True, alpha=0.3)
plt.savefig('model_comparison.png', dpi=150)
예측 구간 (Prediction Interval)
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
model = create_model('auto_arima')
# 075 예측 구간 포함 예측
predictions = predict_model(model, return_pred_int=True)
print(predictions)
# 075 시각화 (구간 포함)
plot_model(model, plot='forecast') # 기본적으로 구간 표시
긴 기간 예측
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
model = create_model('auto_arima')
# 075 다양한 예측 기간
horizons = [6, 12, 24, 36]
all_predictions = {}
for h in horizons:
pred = predict_model(model, fh=h)
all_predictions[h] = pred
print(f"6개월 예측: {all_predictions[6]['y_pred'].values}")
print(f"12개월 예측: {all_predictions[12]['y_pred'].values}")
재학습 (Finalize)
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
# 075 모델 생성 (일부 데이터로 검증)
model = create_model('auto_arima')
# 075 전체 데이터로 재학습
final_model = finalize_model(model)
# 075 최종 예측
final_pred = predict_model(final_model)
print(final_pred)
# 075 저장
save_model(final_model, 'final_arima_model')
잔차 분석
from pycaret.time_series import *
ts = setup(data, target='passengers', fh=12, seasonal_period=12,
session_id=42, verbose=False)
model = create_model('auto_arima')
# 075 잔차 진단
plot_model(model, plot='diagnostics')
# 075 ACF (자기상관)
plot_model(model, plot='acf')
# 075 잔차 분포
plot_model(model, plot='residuals')
좋은 잔차의 특징
1. 정규 분포
2. 평균 0
3. 등분산
4. 자기상관 없음 (백색 잡음)
모델 선택 가이드
데이터 특성에 따른 모델 선택:
강한 계절성:
- Seasonal Naive (베이스라인)
- ETS, SARIMA
- Prophet
명확한 추세:
- ETS (추세 포함)
- ARIMA
- Polynomial Trend
복잡한 패턴:
- Prophet (휴일, 이벤트)
- LightGBM, XGBoost
- TBATS (다중 계절성)
적은 데이터:
- Naive, Seasonal Naive
- ETS
- Theta
정리
- 단변량 예측: 자기 자신의 과거 값만 사용
- 통계 모델: ARIMA, ETS, Theta
- ML 모델: LightGBM, RF (계절성 제거 후)
- Prophet: 트렌드 + 계절성 + 휴일
- 잔차 분석으로 모델 적합성 확인
다음 글 예고
다음 글에서는 다변량 시계열 예측을 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #075