Table of Contents

ML

prophet 모델 예측 이후 성능 높이는 방법

꼬꼬마코더 2024. 7. 3. 23:34
728x90

1. 추가 데이터 통합

  • 외부 데이터: 공휴일, 기후 조건, 경제 지표 등 외부 데이터를 모델에 포함시키면 예측의 정확도를 높일 수 있습니다. Prophet은 공휴일과 특별 이벤트를 모델에 포함시키는 기능을 제공합니다.
  • 프로모션 데이터: 판매 촉진 행사 정보가 있다면, 이를 모델에 포함시켜 판매량 증가 예측을 개선할 수 있습니다.

2. 하이퍼파라미터 조정

  • 계절성 조정: 주간, 연간 계절성의 파라미터를 조정하거나, 데이터에 맞는 새로운 계절성을 정의할 수 있습니다.
  • 변경점(changepoint) 조정: Prophet 모델의 변경점 감도를 조정하여 모델이 추세의 변화를 더 잘 감지하도록 할 수 있습니다. changepoint_prior_scale의 값을 조정해 보세요.

3. 피쳐 엔지니어링

  • 라그 변수: 과거 판매 데이터의 라그 값을 독립 변수로 추가하여 모델의 입력 특성으로 사용합니다. 이는 시계열의 자기 상관성을 모델링하는 데 도움이 됩니다.
  • 이동 평균: 이동 평균을 특성으로 추가하여 데이터의 잡음을 줄이고 안정성을 높일 수 있습니다.

4. 앙상블 방법

  • 모델 앙상블: Prophet 외에 ARIMA, LSTM 등 다른 시계열 모델을 함께 사용하고, 각 모델의 예측 결과를 합쳐 최종 예측을 도출하는 방법을 시도해 볼 수 있습니다.
  • 스태킹(Stacking): 다양한 모델의 예측을 입력으로 사용하는 메타 모델을 구축하여 예측의 정확도를 높일 수 있습니다.

5. 크로스 밸리데이션

  • 시계열 크로스 밸리데이션: Prophet의 시계열 크로스 밸리데이션 기능을 활용하여 모델의 예측 성능을 평가하고, 과적합을 방지합니다.

changepoint_prior_scale 파라미터는 Prophet 모델에서 추세 변경점의 유연성을 조절합니다. 이 파라미터를 조정하면 모델이 데이터의 추세 변화를 얼마나 민감하게 감지할지 결정할 수 있습니다. 값이 높을수록 모델은 더 많은 추세 변화를 감지하려고 하며, 값이 낮을수록 변화에 덜 민감하게 됩니다.

changepoint_prior_scale의 기본 설정

  • 기본값은 0.05이며, 일반적으로 적당한 시작점을 제공합니다.

changepoint_prior_scale 변경하기

Prophet 모델을 초기화할 때 changepoint_prior_scale 값을 설정할 수 있습니다. 다음은 이 파라미터를 조정하여 모델을 생성하는 예시 코드입니다:

from prophet import Prophet

# 모델 초기화, changepoint_prior_scale을 조정
model = Prophet(changepoint_prior_scale=0.1)  # 추세 변경점을 더 유연하게 감지

# 데이터 로딩 및 모델 학습
df = pd.read_csv('your_data.csv')
model.fit(df)

# 미래 데이터프레임 생성 및 예측
future = model.make_future_dataframe(periods=60)
forecast = model.predict(future)

# 예측 결과 확인
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

성능 평가 및 최적화

changepoint_prior_scale 값을 조정할 때, 너무 높은 값은 과적합을 유발하고, 너무 낮은 값은 모델이 중요한 추세 변화를 감지하지 못할 수 있습니다. 따라서 다양한 값을 실험하여 최적의 값을 찾는 것이 중요합니다.

크로스 밸리데이션을 통한 최적화

Prophet의 크로스 밸리데이션 기능을 사용하여 다양한 changepoint_prior_scale 값에 대한 모델의 성능을 평가할 수 있습니다. 다음은 Prophet의 크로스 밸리데이션을 사용하는 방법입니다:

from prophet.diagnostics import cross_validation, performance_metrics

# 크로스 밸리데이션 실행
df_cv = cross_validation(model, initial='730 days', period='180 days', horizon = '365 days')

# 성능 메트릭 계산
df_p = performance_metrics(df_cv)
print(df_p.head())

# 다양한 changepoint_prior_scale 값에 대해 반복 실행하여 최적의 값을 찾습니다.

이러한 접근 방식을 통해 모델의 changepoint_prior_scale 파라미터를 조정하고 최적화하는 과정을 시스템적으로 수행할 수 있습니다. 이를 통해 데이터의 특성에 가장 잘 맞는 설정을 찾아 예측 성능을 향상시킬 수 있습니다.

Prophet의 크로스 밸리데이션 기능에서 initial, period, horizon은 예측 모델의 성능을 평가하는 데 사용되는 시간 기간을 정의합니다. 이들 파라미터는 시계열 데이터에서의 교차 검증 설정을 결정하는 데 중요한 역할을 합니다. 각각의 의미를 구체적으로 살펴보겠습니다:

1. initial

  • initial은 모델 학습에 사용할 데이터의 최소 크기를 정의합니다. 이 값은 문자열 형식으로 제공되며, 일반적으로 "730 days"와 같이 일 단위로 설정됩니다. 예를 들어 "730 days"라고 설정하면, 첫 번째 교차 검증 폴드에서 모델 학습을 위해 처음 2년간의 데이터가 사용됩니다.

2. period

  • period은 교차 검증을 수행할 때 각 교차 검증 단계 사이의 간격을 지정합니다. 예를 들어, period='180 days'로 설정하면, 데이터의 다음 교차 검증 폴드는 첫 번째 폴드의 시작점에서 180일 후에 시작됩니다. 이 파라미터는 모델의 안정성과 변화에 대한 적응력을 평가하는 데 중요합니다.

3. horizon

  • horizon은 각 교차 검증 단계에서 모델이 예측할 기간의 길이를 정의합니다. "365 days"와 같이 설정하면, 각 교차 검증 모델은 학습 데이터 이후의 365일 동안의 데이터를 예측하게 됩니다. 이는 모델의 장기 예측 성능을 평가하는 데 사용됩니다.

크로스 밸리데이션 설정 예시

from prophet.diagnostics import cross_validation
from prophet import Prophet

# 모델 생성
model = Prophet()
model.fit(df)  # 여기서 df는 학습 데이터프레임

# 크로스 밸리데이션 실행
df_cv = cross_validation(model, initial='730 days', period='180 days', horizon='365 days')

# 결과 분석

이 설정은 시계열 데이터가 충분히 긴 경우에 적합합니다. 모델의 학습과 예측을 위한 데이터 기간(initial), 검증 데이터를 업데이트하는 빈도(period), 그리고 예측을 수행할 기간(horizon)을 효과적으로 조절하여 모델의 예측 성능과 일반화 능력을 평가할 수 있습니다. 이를 통해 실제 운영 환경에서 모델이 어떻게 수행될지 더 잘 이해할 수 있습니다.


라그 변수(Lag Variable)는 시계열 데이터 분석에서 매우 중요한 개념으로, 특정 시간 단위(예: 일, 주, 월) 만큼 이전의 데이터 값을 현재 데이터의 설명 변수로 사용하는 것을 의미합니다. 즉, 과거의 데이터를 현재의 예측에 사용하는 것입니다.

라그 변수의 사용 목적

  1. 자기 상관성 파악: 시계열 데이터는 자주 자기 상관성(autocorrelation)을 보이는데, 이는 현재의 값이 과거의 값들과 관련이 있다는 것을 의미합니다. 라그 변수를 사용함으로써 모델은 이러한 상관성을 학습하고 예측에 활용할 수 있습니다.

  2. 시계열의 계절성 및 트렌드 반영: 계절성이나 트렌드 같은 시계열의 특성을 모델링할 때 라그 변수를 통해 이러한 패턴을 포착할 수 있습니다.

  3. 예측 정확도 향상: 과거 데이터의 정보를 통합함으로써, 예측 모델의 정확도를 개선할 수 있습니다.

라그 변수의 예

예를 들어, 하루치 매출 데이터를 분석한다고 가정해 봅시다. 이 경우, '오늘의 매출'을 예측하기 위해 '어제의 매출'(Lag 1), '그제의 매출'(Lag 2), '3일 전의 매출'(Lag 3) 등을 변수로 사용할 수 있습니다.

라그 변수 생성 방법

Python에서는 pandas 라이브러리를 사용하여 간단하게 라그 변수를 생성할 수 있습니다. 아래는 라그 변수를 생성하는 코드 예시입니다.

import pandas as pd

# 예제 데이터 생성
data = {
    'date': pd.date_range(start='2020-01-01', periods=10),
    'sales': [145, 180, 160, 196, 210, 200, 220, 215, 250, 240]
}
df = pd.DataFrame(data)

# 라그 변수 생성
df['lag_1'] = df['sales'].shift(1)  # 어제 매출
df['lag_2'] = df['sales'].shift(2)  # 그제 매출

print(df)

출력 결과

        date  sales  lag_1  lag_2
0 2020-01-01    145    NaN    NaN
1 2020-01-02    180  145.0    NaN
2 2020-01-03    160  180.0  145.0
...

라그 변수를 사용할 때 주의해야 할 점은, 데이터의 시작 부분에서는 라그 값이 존재하지 않기 때문에 NaN 값이 발생한다는 것입니다. 이를 처리하기 위해 데이터의 처음 부분을 제거하거나, 적절한 값(예: 0, 평균값)으로 채울 수 있습니다.

라그 변수는 모델이 과거의 정보를 바탕으로 현재를 예측하는 데 도움을 주므로, 시계열 예측 문제에서 매우 유용하게 활용됩니다.


이동 평균(Moving Average)을 이용한 피쳐 엔지니어링은 시계열 데이터에서 추세나 계절성을 부드럽게 하고, 잡음을 줄이기 위해 사용됩니다. 이동 평균은 과거 데이터의 평균을 계산함으로써, 데이터의 불규칙성을 감소시키고, 중요한 추세를 보다 명확하게 드러내는 데 도움을 줍니다.

이동 평균의 종류

  1. 단순 이동 평균(Simple Moving Average, SMA): 고정된 개수의 최근 데이터 포인트들의 평균을 계산합니다.
  2. 지수 이동 평균(Exponential Moving Average, EMA): 더 최근의 데이터에 더 큰 가중치를 두어 계산합니다.
  3. 가중 이동 평균(Weighted Moving Average, WMA): 각 데이터 포인트에 서로 다른 가중치를 주어 평균을 계산합니다.

이동 평균을 이용한 피쳐 엔지니어링 방법

Python에서 pandas 라이브러리를 사용하여 이동 평균을 계산하고 피쳐로 활용하는 방법은 다음과 같습니다.

예시: 단순 이동 평균을 이용한 피쳐 생성

import pandas as pd
import numpy as np

# 예제 데이터 생성
data = {
    'date': pd.date_range(start='2020-01-01', periods=100),
    'sales': np.random.randint(100, 200, size=100)
}
df = pd.DataFrame(data)

# 7일 단순 이동 평균(SMA) 계산
df['7_day_SMA'] = df['sales'].rolling(window=7, min_periods=1).mean()

# 30일 단순 이동 평균(SMA) 계산
df['30_day_SMA'] = df['sales'].rolling(window=30, min_periods=1).mean()

print(df.head(10))

이 코드는 각 판매 데이터에 대해 7일 및 30일 단순 이동 평균을 계산합니다. rolling() 메서드는 윈도우 크기를 지정하며, min_periods=1는 최소 한 개의 데이터 포인트가 있으면 평균을 계산하도록 설정합니다.

결과

        date  sales   7_day_SMA  30_day_SMA
0 2020-01-01    172  172.000000  172.000000
1 2020-01-02    136  154.000000  154.000000
2 2020-01-03    150  152.666667  152.666667
3 2020-01-04    165  155.750000  155.750000
4 2020-01-05    154  155.400000  155.400000
...

이동 평균의 장점

  • 데이터의 부드러움: 이동 평균은 데이터의 단기 변동을 줄이고 장기 추세를 보여줍니다.
  • 특성 강화: 시계열 데이터에서 장기 추세나 계절적 변동을 강조하는 데 유용합니다.

주의점

  • 시간 지연: 이동 평균을 사용하면 데이터의 시간 지연이 발생할 수 있으므로, 실시간 시스템이나 빠른 반응이 필요한 시스템에서는 주의해서 사용해야 합니다.
  • 데이터의 손실: 이동 평균을 계산할 때 윈도우의 처음 부분에서는 계산되지 않는 데이터가 발생할 수 있습니다.

앙상블 모델을 구성할 때 서로 다른 모델들의 성능 차이를 평가하는 것은 중요한 과정입니다. 앙상블 방법을 사용하는 주된 목적은 개별 모델의 예측 성능을 향상시키는 것이므로, 선택된 모델들이 서로 보완적인 성능을 보여야 합니다.

모델 성능 차이 평가 기준

  1. 손실 함수 값의 차이: 모델 간 손실 함수(예: MSE, RMSE, MAE 등)의 차이가 작더라도, 앙상블에 포함시키기 전에 각 모델의 성능이 데이터의 어떤 측면을 잘 포착하는지 분석해야 합니다. 예를 들어, 한 모델은 특정 유형의 데이터에서 더 잘 작동하고 다른 모델은 다른 유형에서 더 잘 작동할 수 있습니다.

  2. 예측 정확도의 분산: 손실 함수의 차이가 크지 않더라도, 모델들이 예측하는 결과의 분산을 고려해야 합니다. 예측 결과의 분산이 다르다면, 이들을 조합함으로써 전체 예측의 안정성을 높일 수 있습니다.

  3. 모델의 독립성: 앙상블에 사용되는 모델들이 가능한 독립적이어야 하며, 각각 다른 알고리즘, 특성 선택, 데이터 분할 방식을 사용해야 합니다. 이렇게 함으로써 서로 다른 오류를 보이는 모델들을 조합하여 전체 성능을 향상시킬 수 있습니다.

앙상블을 고려할 때의 접근 방법

  • 다양성 테스트: 서로 다른 모델의 조합이 실제로 성능 향상에 기여하는지 확인하기 위해 다양성 테스트를 수행합니다. 이는 모델이 서로 다른 유형의 오류를 만들어내는지 확인하는 과정을 포함합니다.

  • 크로스 밸리데이션: 다양한 모델 조합을 크로스 밸리데이션을 통해 평가하여 최적의 모델 조합을 찾습니다. 크로스 밸리데이션은 각 모델의 성능을 보다 객관적으로 평가할 수 있게 해줍니다.

  • 성능 향상의 한계: 앙상블의 추가적인 복잡성과 계산 비용이 성능 향상을 정당화하는지 평가해야 합니다. 매우 작은 성능 향상을 위해 계산 비용이 크게 증가하는 경우, 이는 비효율적일 수 있습니다.

예시

모델 A와 모델 B가 있고, 각각의 RMSE가 0.5, 0.48이라고 가정해봅시다. 차이가 크지 않아 보이지만, 이 두 모델이 서로 다른 유형의 오류 패턴을 가지고 있다면, 앙상블을 통해 두 모델의 장점을 결합할 수 있습니다. 다른 방법으로, 하나의 모델이 특정 조건에서 훨씬 더 나은 성능을 보일 수 있으므로, 이를 파악하는 것이 중요합니다.

종합적으로, 손실 함수 값의 차이가 작더라도 앙상블을 구성할 때는 모델 간의 독립성과 다양성, 예측의 안정성을 주요 고려 사항으로 삼아야 합니다. 이를 통해 전체적인 성능 향상을 꾀할 수 있습니다.

모델 앙상블(Model Ensemble)은 여러 다른 모델의 예측을 결합하여 최종적인 예측을 향상시키는 방법입니다. 이 접근법은 각 모델의 장점을 이용하고, 단점을 상쇄시키기 위해 사용됩니다. 대표적인 앙상블 기법으로는 배깅(Bagging), 부스팅(Boosting), 스태킹(Stacking) 등이 있습니다.

앙상블의 예

1. 배깅 (Bagging)

배깅은 "Bootstrap Aggregating"의 줄임말로, 랜덤 포레스트(Random Forest)가 이에 속합니다. 배깅은 데이터셋의 부트스트랩 샘플(원본 데이터에서 중복을 허용하여 랜덤하게 추출한 샘플)을 사용하여 여러 모델을 독립적으로 학습시키고, 이들의 결과를 평균내거나 다수결로 결합하는 방법입니다.

예시: 랜덤 포레스트
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

# 데이터 로드
data = load_boston()
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.3, random_state=42)

# 랜덤 포레스트 모델 학습
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# 예측
predictions = model.predict(X_test)

2. 부스팅 (Boosting)

부스팅은 약한 예측 모델들을 순차적으로 개선해나가면서 강한 예측 모델을 구축하는 방법입니다. 대표적인 예로는 AdaBoost, Gradient Boosting, XGBoost 등이 있습니다. 이들은 이전 모델이 잘못 예측한 데이터에 더 큰 가중치를 주어 다음 모델을 학습시키는 방식으로 작동합니다.

예시: XGBoost
import xgboost as xgb

# 데이터 로드 및 DMatrix 생성
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

# 파라미터 설정
params = {
    'max_depth': 3,
    'eta': 0.1,
    'objective': 'reg:squarederror',
    'eval_metric': 'rmse'
}

# 모델 학습
bst = xgb.train(params, dtrain, num_boost_round=100)

# 예측
predictions = bst.predict(dtest)

3. 스태킹 (Stacking)

스태킹은 여러 다른 모델의 예측 결과를 새로운 데이터셋으로 사용하여, 이를 기반으로 다른 메타 모델(meta-model)을 학습시키는 방법입니다. 이는 모델 간의 다양한 강점을 결합할 수 있는 강력한 방법으로, 복잡한 문제에서 특히 유용합니다.

예시: 스태킹
from sklearn.ensemble import StackingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR

# 스태커 생성
estimators = [
    ('lr', LinearRegression()),
    ('svr', SVR())
]
stacking_regressor = StackingRegressor(estimators=estimators, final_estimator=RandomForestRegressor(n_estimators=10))

# 모델 학습
stacking_regressor.fit(X_train, y_train)

# 예측
predictions = stacking_regressor.predict(X_test)

이러한 앙상블 기법들은 각기 다른 상황과 데이터 특성에 맞게 적절하게 선택하여 사용될 수 있으며, 예측 성능을 크게 향상시킬 수 있는 잠재력을 가지고 있습니다.