들어가면서
내가 처음으로 입사했을 때 회사는 월별 주요 지표를 예측하는 프로세스가 Excel의 회귀 분석 기능 활용했다.
저도 작년까지는 이러한 회귀분석과 Cohort 추이분석을 바탕으로 필요한 예측치를 산출하고 있었다.
다만, 시계열 분석을 공부하는 과정에서 이런 방식이 가지는 한계를 느낄 수 있었다.
그래서 시계열 공부를 시작해 그 과정에서 메타로 제작한 프로페트 모델을 알고 이를 실무에 도입하고 있다.
prophet 모델이 Excel에서 제공하는 회귀 분석 기능과 비교하여 갖는 이점은 다음과 같습니다.
- 계절성 및 휴일 패턴 고려: Prophet 모델은 시계열 데이터에서 계절성 및 휴일 패턴을 고려하여 예측할 수 있습니다.
이것은 Excel의 회귀 분석에서 별도로 처리해야하기 때문에 복잡하고 번거롭습니다. - 비선형 추세 모델링: Prophet 모델은 비선형 추세 모델링에 적합합니다.
따라서 Excel 회귀 분석보다 정확한 예측을 제공할 수 있습니다. - 데이터 전처리 필요성 감소: Prophet 모델은 일반적으로 데이터 전처리가 필요하지 않습니다.
반면 Excel 회귀 분석에서는 데이터 전처리를 수행해야 합니다. - 다중 변수 처리: Prophet 모델은 여러 변수를 처리하는 데 도움이 됩니다.
예를 들어, 다른 변수의 영향을 받는 패턴을 예측하는 데 도움이 됩니다.
Excel의 회귀 분석은 일반적으로 단일 변수를 예측하는 데 사용됩니다. - 정확도 및 예측 불확실성 분석: Prophet 모델은 예측의 정확성과 예측 불확실성을 분석할 수 있습니다.
이것은 Excel의 회귀 분석에서는 제공되지 않습니다. - 빠른 예측 시간: Prophet 모델은 대규모 데이터 세트의 빠른 예측 시간을 제공합니다.
반면 Excel의 회귀 분석은 대규모 데이터 세트에서 느려질 수 있습니다.
이 때문에, 프로펫트를 활용한 보다 정확하고 유연한 시계열 분석을 실시하는 방향으로 개선하고 있다.
오늘 정리한 콘텐츠는 이러한 Prophet 모델의 성능을 높일 수 있는 기본적인 작업이다.
바로 한국의 공휴일 내용을 매핑하는 것이다.
비즈니스에서 지표를 보면 영업일과 비영업일에 따라 차이가 나오는 경우가 많다.
예를 들어, B2C의 경우 오히려 금요일 밤부터 주말에 높게 표시되는 지표가 있을 수 있습니다.
한편 B2B 서비스의 경우 비교적 영업일 수치가 높아지는 경우가 많을 것이다.
이 때문에, 시계열 모델로 휴일의 구분을 진행하면, 보다 정확한 예측값을 산출할 수 있을 것이다.
코드 작성
1.
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from prophet import Prophet #prophet 라이브러리 불러오기
from prophet.diagnostics import cross_validation
from prophet.plot import plot_cross_validation_metric
from prophet.diagnostics import performance_metrics
먼저 pandas, numpy, plotly.graph_objs, matplotlib.pyplot 등의 라이브러리를 로드합니다.
그런 다음 datetime 및 timedelta 라이브러리를 사용하여 날짜와 시간과 관련된 함수를 사용할 수 있도록 로드합니다.
또한 Prophet 라이브러리에서 모델링 및 성능 평가에 필요한 함수를 호출합니다.
그런 다음 Prophet 모델링에 대한 Prophet() 함수를 호출합니다.
이 함수는 Prophet 모델을 생성하는 데 사용되며 모델 생성 후 이 함수를 사용하여 모델의 하이퍼파라미터를 설정하고 예측을 수행할 수 있습니다.
마지막으로, cross_validation, plot_cross_validation_metric, performance_metrics 함수를 사용하여 Prophet 모델의 성능 평가를 수행할 수 있습니다.
cross_validation 함수는 Prophet 모델의 교차 검증을 수행하고 plot_cross_validation_metric 함수를 사용하여 교차 검증 결과를 시각화할 수 있습니다.
performance_metrics 함수는 교차 검증 결과를 통해 모델의 성능 지표를 계산합니다.
이는 모델의 성능을 평가하고 개선할 수 있다.
2.
#데이터 로드
join_raw = pd.read_csv('../join_data.csv')
join_raw('register_month') = pd.to_datetime(join_raw('register_month'), format="%Y-%m-%d")
join_raw('register_day') = pd.to_datetime(join_raw('register_day'), format="%Y-%m-%d")
df_train = join_raw(('register_day', 'user_total'))
df_train = df_train.rename(columns={'register_day': 'ds', 'user_total':'y'})
다음은 데이터를 호출해야 합니다.
특히 데이터를 호출하고 해당 데이터의 값을 String으로 저장하는 경우 시계열 분석을 위해 DataFrame으로 변환하는 작업을 수행해야 합니다.
3.
import holidays
date_list=pd.date_range(start="20210101", end='20231231', freq='D')
# 한국 휴일 객체 생성
kr_holidays = holidays.KR()
holiday_df = pd.DataFrame(columns=('ds','holiday'))
holiday_df('ds') = sorted(date_list)
holiday_df('holiday') = holiday_df.ds.apply(lambda x: 'holiday' if x in kr_holidays else 'non-holiday')
지금 오늘 콘텐츠의 핵심입니다.
한국의 공휴일 정보를 이용하여 2021년 1월 1일부터 2023년 12월 31일까지의 모든 날짜에 대한 공휴일 여부를 데이터 프레임으로 생성한다.
holidays 라이브러리를 사용하여 한국의 공휴일 정보를 호출한 후 pd.date_range 함수를 사용하여 2021년 1월 1일부터 2023년 12월 31일까지의 모든 날짜 목록을 생성합니다.
그런 다음 pd.DataFrame 함수를 사용하여 휴일 여부를 저장하는 빈 데이터 프레임을 만듭니다.
holiday_df(‘ds’) 에는 생성된 모든 일자의 리스트가 포함되어 holiday_df(‘holiday’) 에는 그 일자가 공휴일인가 어떤가가 포함됩니다.
여기서 lambda 함수를 사용하여 날짜가 한국의 공휴일인 경우 ‘holiday’를 저장하고, 그렇지 않으면 ‘non-holiday’를 저장합니다.
이와 같이 생성된 holiday_df 데이터 프레임을 나중에 Prophet 모델 등에서 독립 변수로 활용하여 시계열 예측 분석을 수행할 수 있습니다.
4.
# Prophet 객체 생성
n = Prophet(holidays=holiday_df, weekly_seasonality=True, daily_seasonality=True)
Prophet() 함수를 호출하여 모델 객체를 만들고 n 변수에 할당합니다.
함수의 인수로 holidays, weekly_seasonality, daily_seasonality를 전달합니다.
- holidays는 Prophet 모델에서 공휴일 정보를 활용하기 위한 인수이며, holiday_df 변수에 저장된 공휴일 정보를 전달하고 그 날짜가 공휴일인지 여부를 반영하여 예측 결과를 출력한다.
- weekly_seasonality 및 daily_seasonality는 각각 주와 계절성을 고려하여 모델링을 수행할지 여부를 설정하는 요인입니다.
이 값이 True이면 Prophet 모델은 계절성 요소를 반영하여 예측 결과를 출력합니다.
따라서, 상기의 코드는 Prophet 모델 오브젝트를 생성하고, 이것을 n변수에 할당하면서, 공휴일 정보와 주별, 일별의 계절성을 고려하여 모델링을 행하는 것을 설정하는 코드이다.
5.
# 모델 학습
n.fit(df_train)
#2023년 3월을 포함한 미래의 날짜값 생성(예측할 기간 설정)
future_n = n.make_future_dataframe(periods=31, freq='d')
#예측값 생성
forecast_n = n.predict(future_n)
n.fit(df_train) 은 Prophet 모델 객체인 n 에 df_train 데이터를 학습시키는 코드입니다.
df_train은 Prophet 모델을 학습하는 데 사용되는 시계열 데이터를 저장하는 Pandas DataFrame 객체입니다.
n.make_future_dataframe(periods=31, freq=’d’) 는 periods 인수에 전달된 값(31)만의 향후 날짜 값을 생성하는 코드입니다.
freq 인수는 향후 날짜 값을 생성할 때 각 날짜 간의 간격을 의미합니다.
“d”는 일 단위로 간격을 두는 것을 의미합니다.
즉, 31일의 향후 날짜 값을 생성하고 Future_n 변수에 할당합니다.
n.predict(future_n) 는 Prophet 모델 객체 n 과 future_n 을 활용하여 향후 예측값을 생성하는 코드입니다.
forecast_n 변수에는 예측 결과가 저장됩니다.
따라서, 상기 코드는 Prophet 모델 객체 n에 df_train을 학습한 후 31일의 미래 날짜 값을 생성하고 이를 이용하여 forecast_n 변수에 예측 결과를 저장하는 코드이다.
6.
# 성능 평가
df_n_cv = cross_validation(n, initial="300 days", period='60 days', horizon = '30 days')
df_n_p = performance_metrics(df_n_cv)
fig3 = plot_cross_validation_metric(df_n_cv, metric="mape")
cross_validation(n, initial=”300 days”, period=’60 days’, horizon = ’30 days’) 는 학습된 Prophet 모델 객체 n에 대해 교차 검증(cross-validation)을 수행하고, 이에 따라 모델의 예측 성능을 평가하는 코드다.
초기 인자는 처음 300일 동안의 데이터를 트레이닝 데이터로 사용하는 것을 의미하며, period 인수는 검증 데이터와 트레이닝 데이터 사이의 간격을 설정합니다.
여기서는 60일 간격으로 검증 데이터와 훈련 데이터를 구분한다.
horizon 계수는 예측 기간을 의미하며 여기에서는 30 일을 예측하도록 설정합니다.
performance_metrics(df_n_cv)는 cross_validation 함수에 의해 생성된 교차 검증 결과인 df_n_cv를 활용하여 모델의 성능을 측정하는 함수이다.
df_n_cv는 예측 결과와 실제 값의 차이(mae, mse, rmse, mape, mdape)에 대한 정보를 포함하는 DataFrame 객체입니다.
performance_metrics 함수는 이 정보를 기반으로 모델의 성능 지표(mean absolute percentage error, mean absolute scaled error)를 반환합니다.
plot_cross_validation_metric(df_n_cv, metric=”mape”) 은 cross_validation 함수에 의해 생성된 교차 검증 결과인 df_n_cv 를 활용하여 모델의 성능을 가시화하는 함수이다.
metric 인수를 사용하여 어떤 성능 지표(mae, mse, rmse, mape, mdape)를 사용할지 설정합니다.
plot_cross_validation_metric 함수는 예측 결과와 실제 값의 차이를 기반으로 교차 검증 결과를 시각화합니다.
따라서, 상기 코드는 Prophet 모델의 성능을 교차 검증으로 평가하고, 이에 기초하여 성능 지표 및 시각화 결과를 생성하는 코드이다.
성능 평가를 진행한 결과, 다음과 같이 결과물이 나타난다.
(TO-BE)
horizon 30 days 00:00:00
mse 5585.983818
rmse 74.73944
mae 48.337485
mape 0.198669
mdape 0.101449
smape 0.201137
coverage 0.708333
Name: 27, dtype: object
(AS-IS)
horizon 30 days 00:00:00
mse 6290.790264
rmse 79.314502
mae 51.748078
mape 0.227036
mdape 0.178369
smape 0.183599
coverage 0.708333
Name: 27, dtype: object
공휴일에 매핑한 후 예측의 정확도가 약간 향상된 것을 확인할 수 있었다.