본문 바로가기

프로그래밍/AI:ML:DL

Prophet plot 그래프 설명

prophet plot 그래프 설명

https://mikulskibartosz.name/prophet-plot-explained-31df79087e24

Bartosz Mikulski 2018-11-14

Prophet 이 만들어낸 플롯을 보고 당황했다. 문서에서 설명을 찾아봤지만 없었다. 구글링을 해도, 스택오버플로우에서조차 설명을 찾을 수 없었다.

이해하기를 포기하거나, 아니면, 소스코드를 파보는 두가지 방법 밖에 없었다. 다행히도 prophet 의 plot 함수 소스코드를 보니, 모든 것이 명확해졌다.

예제

문서를 보면, 위키백과의 Peyton Manninng 페이지의 일간 페이지뷰 로그를 입력데이터로 사용한다. 첫번째 단계로, 데이터셋을 다운로드하고, 라인플롯으로 플로팅해 보았다.

import fbprophet
import matplotlib.pyplot as plt
import pandas as pd
!curl -O https://raw.githubusercontent.com/facebook/prophet/master/examples/example_wp_log_peyton_manning.csv
data = pd.read_csv("example_wp_log_peyton_manning.csv")
data["ds"] = pd.to_datetime(data["ds"])
fig = plt.figure(facecolor='w', figsize=(10, 6))
plt.plot(data.ds, data.y)

그림에서 각각의 데이터포인트를 알아볼 수 없고, 두꺼운 푸른색 라인 뿐이다. 그러나 이것은 에러가 아니다. 단지 데이터포인트가 서로 너무 가까이 있을 뿐이다. 이 관찰은 이후에도 중요하니 기억.

두번째 단계로, Prophet 모델을 만들어 데이터를 이용해 fit (훈련)하여, 예측을 만들어 낼 것이다. 예측이 준비되면, prophet의 plot 함수를 이용해 플롯을 그린다.

model = fbprophet.Prophet()
model.fit(data)
future = model.make_future_dataframe(periods=365)
forecast = model.predict(future)
plot = model.plot(forecast)

이 그림을 처음 봤을 때, 난 아무것도 이해할 수 없었다. 저 진한 푸른색 영역은 뭔가? uncertainty interval인가? 옅은 푸른색 영역은? 검정색 점들은 또 무엇인가?

설명

소스코드를 보면서, 함수를 실행해 보자. 여기 plot 함수의 소스코드가 있다.

def plot(
    m, fcst, ax=None, uncertainty=True, plot_cap=True, xlabel='ds', ylabel='y',
    figsize=(10, 6)
):
    if ax is None:
        fig = plt.figure(facecolor='w', figsize=figsize)
        ax = fig.add_subplot(111)
    else:
        fig = ax.get_figure()
    fcst_t = fcst['ds'].dt.to_pydatetime()
    ax.plot(m.history['ds'].dt.to_pydatetime(), m.history['y'], 'k.')
    ax.plot(fcst_t, fcst['yhat'], ls='-', c='#0072B2')
    if 'cap' in fcst and plot_cap:
        ax.plot(fcst_t, fcst['cap'], ls='--', c='k')
    if m.logistic_floor and 'floor' in fcst and plot_cap:
        ax.plot(fcst_t, fcst['floor'], ls='--', c='k')
    if uncertainty:
        ax.fill_between(fcst_t, fcst['yhat_lower'], fcst['yhat_upper'],
                        color='#0072B2', alpha=0.2)
    ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2)
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    fig.tight_layout()
    return fig

함수를 한줄 한줄 따라가보자.

"ax" 인자를 지정하지 않았다. 그래서 함수는 새로운 plot 을 생성할 것이다.

figsize=(10, 6), xlabel='ds', ylabel='y'
fig = plt.figure(facecolor='w', figsize=figsize)
ax = fig.add_subplot(111)

다음엔 훈련에 사용했던 데이터를 나타내는 검은 점들을 그린다.

fcst_t = fcst['ds'].dt.to_pydatetime()
ax.plot(model.history['ds'].dt.to_pydatetime(), model.history['y'], 'k.')

다음 줄에선 예측(forecast)을 플로팅 한다.

ax.plot(fcst_t, fcst['yhat'], ls='-', c='#0072B2')

앞에서처럼, 라인을 그려야 하지만, 두께가 있는 푸른색 영역으로 그려진다.

이 포스팅 앞쪽에서 입력 데이터를 라인플롯으로 그렸을 때에도 데이터포인트가 너무 많아서 선이 아닌 영역으로 그려졌었다.

그럼 다음은? "cap", "floor"인자를 특별히 지정하지 않았기 때문에, 함수는 uncertainty interval 을 그릴 것이다.

ax.fill_between(fcst_t, fcst['yhat_lower'], fcst['yhat_upper'], color='#0072B2', alpha=0.2)

마지막으로, 격자와 레이블을 그린다.

ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2)
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
fig.tight_layout()

다른 플롯들과 마찬가지로, prophet 예측 플롯도 각 요소를 하나하나 떼어서 보면 이해하기 쉬워진다.