Prophet을 활용한 Kaggle 문제 풀어보기

2021. 2. 25. 19:18Data Science/01_Machine Learning Study

반응형

 

FaceBook Prophet Library 

 

: Facebook에서 공개한 시계열 예측 오픈소스 라이브러이인 'Prophet'을 가지고 Kaggle 문제를 풀어보자

: Prophet현업 전문가들이 풍부한 도메인 지식을 바탕으로 쉽게 예측 문제를 접근할 수 있도록 도와주는 라이브러리로 소개됨

  • 자동화 된 기술은 상황에 맞게 튜닝하기 어렵고 경험적 지식을 반영하기 어려움
  • 분석가들은 도메인 지식만 풍부한 편이며 분석을 쉽게 다루지 못함
  • 비전문가가 경험적 특성을 반영할 수 있도록 필요한 부분을 자동화

: 실제로 사용해본 결과 빠르게 결과를 산출해낼 수 있으며 생각외로 좋은 성능을 보여줌

: Prophet의 하이퍼 파라미터를 소개하면서 Kaggle 문제를 교보재소개하고자 함

 

Paper: https://peerj.com/preprints/3190.pdf
Quick Start: https://facebook.github.io/prophet/docs/quick_start.html
 

Quick Start

Prophet is a forecasting procedure implemented in R and Python. It is fast and provides completely automated forecasts that can be tuned by hand by data scientists and analysts.

facebook.github.io

 


Prophet


 

 

1. Kaggle Competition(Bike Sharing Demand)

 

: 시계열 예측에 사용할 데이터는 Kaggle의 Bike Sharing Demand를 가지고 사용해보자

: 학습 데이터의 Shape는 (17379, 12)이며 해당 데이터로 테스트 데이터의 각 시간별 수요량을(count) 예측하는 문제다 

: 데이터는 시간별로 집계되어있으며 계절, 온도, 습도, 풍향 등과 관련된 변수들로 구성됨

: 이전 포스팅했던 Auto ML 라이브러리로 문제를 접근해도 되는 전형적인 구조로 초보자도 쉽게 풀어볼 수 있음

 

www.kaggle.com/c/bike-sharing-demand
 

Bike Sharing Demand

Forecast use of a city bikeshare system

www.kaggle.com

 

 

2. Data load 

 

: 위에 링크를 타고 들어가 'Bike Sharing Demand' 대회 데이터를 다운

: Prophet을 사용하기 전에 데이터 크기 및 형태를 확인

 

import pandas as pd
import numpy as np
from pandas.tseries.offsets import Day, Hour, Minute, Second


train=pd.read_csv('train.csv')
test=pd.read_csv('test.csv')


print('train shape:',train.shape)
print('test shape:',test.shape)
train.head()

kaggle bike sharing demand data shape


 

 

: Train Data를 가지고 모델링하여 6,493개의 TimeStamp의 자전거 대여 수요량을 예측해서 제출해야 함

: 제출할때는 꼭 submission df 형태를 맞춰야 함

 

sub=pd.read_csv('sampleSubmission.csv')
print('submission shape:', sub.shape)
sub.head()

submission shape


 

 

2. Prophet Import

 

: Prophet Library를 import 하는 코드는 다음과 같음

: 모델시각화 함수들을 호출 

# Prophet Library
from fbprophet import Prophet

# Prophet 시각화 도구
from fbprophet.plot import plot_plotly, plot_components_plotly
from fbprophet.plot import add_changepoints_to_plot

 

 

3. Prophet Data Setting

 

: Prophet에 데이터를 집어넣기 위해서는 x, y 를 따로 전처리를 꼭 해야함

 

1) Y 

: 변수명을 'ds', 'y'변경해야 함

: 변수명은 꼭 소문자여야만하며 이는 변경할수도 없으며 다른 변수명으로 입력시 사용할 수 없음

 

y_train_prophet_df = train[['datetime','count']]
y_train_prophet_df.columns = ['ds', 'y']
y_train_prophet_df.head()

prophet data set_y


 

2) X

: ds, y를 제외한 x 변수들을 따로 df 처리

 

x_col = [i for i in train.columns if i not in ['datetime','count']]
x_train_prophet_df = train[x_col]
x_train_prophet_df.head()

prophet data set_x


 

3) YX

: Prophet 학습시에는 꼭 df, y, x변수 순서대로 쌓인 df를 밀어넣어야 함

yx_train_prophet_df = pd.concat(
                                                   [y_train_prophet_df, x_train_prophet_df],
                                                    axis=1
                                                    )

 

 

4. Prophet Modeling_기본

 

: Prophet Modelhyper parameter 설명은 아래와 같음

: 크게 5가지1) 선형/비선형 선택, 2) 추세, 3) 계절성, 4) 휴일, 5) 기타 등으로 구분됨

: ARIMA, SARIMA 등 통계 기반 모델hyper parameter 와는 달리 기술적으로 참고해서 입력할 수 있는 para가 거의 없음

: 실제 현업을 잘 이해하고 있는 전문가들이 예측하고자 하는 문제와 관련된 이벤트, 민감도 외 기타 등등 핸들링이 용이함

 

# Applying Prophet Model

fit_default_prophet = Prophet(
                                               # 1) linear, nonlinear
                                               growth='linear',
 
                                               # 2) Trend
                                               changepoints=None, # CP가 발생하는 시점들의 list ['2012-01-01']
                                               n_changepoints=25, # CP의 수
                                               changepoint_range=0.8, # CP의 기존 데이터 수 대비 최대 비율
                                               changepoint_prior_scale=0.05, # CP 추정 민감도로 높을수록 민감

                                               # 3) Seasonality
                                               seasonality_mode='additive', # 계절성 모델: 'additive' or 'multiplicative'
                                               seasonality_prior_scale=10.0, # 계절성 추정 민감도로 높을수록 민감
                                               yearly_seasonality='auto', # 연계절성
                                               weekly_seasonality='auto',# 월계절성
                                               daily_seasonality='auto', #일계절성

                                              # 4) Holiday
                                              holidays=None, # 휴일 또는 이벤트 시점
                                              dataframe holidays_prior_scale=10.0, # 휴일 추정 민감도로 높을수록 민감

                                             # 5) Others
                                             interval_width=0.8, # 추세 예측 정확도 구간범위
                                             mcmc_samples=0, # 계절성 예측 정확도 제어
                                             )

 

 

: 기존에 만들었던 yx_df를 모델에 학습

: Prophet의 경우 예측하기 위한 사전틀이 필요(make_future_dataframe을 사용)

: Prophet의 예측결과값기존 학습 시킨 df의 크기 + 예측 df 크기 만큼 출력되며 이를 나누는 작업이 추가적으로 필요

# model 학습
fit_reg1_prophet = fit_default_prophet.fit(yx_train_prophet_df)

# Frequency에 대한 사전 df를 만듦
forecast = fit_reg1_prophet.make_future_dataframe(
                                                                                 freq='H',
                                                                                 periods=sub.shape[0]
                                                                                 )

# predict pred_reg1_prophet = fit_reg1_prophet.predict(forecast)

pred_train_reg1_prophet = np.ravel(pred_reg1_prophet.loc[:yx_train_prophet_df.shape[0]-1, ['yhat']]) pred_test_reg1_prophet = np.ravel(pred_reg1_prophet.loc[yx_train_prophet_df.shape[0]:, ['yhat']])

 

 

: 결과를 sub['count'] 로 입력

: 반올림 및 0보다 낮은 숫자를 0으로 변환하는 작업

: 결과 파일 완성

sub['count'] = pred_test_reg1_prophet
sub['count'] = sub['count'].apply(lambda x:round(x,0))
sub.loc[sub['count']<0,'count'] = 0 sub.head()

Prophet 결과


 

: 향후 시간이 남을 때 결과 제출과 시각화를 추가할 예정

반응형