Help us understand the problem. What is going on with this article?

時系列解析ライブラリProphet 公式ドキュメント翻訳10(1日単位ではないデータ編)

More than 1 year has passed since last update.

Facebookが公開している時系列解析用のライブラリProphetの公式ドキュメントを翻訳していきます。

目次
1.Prophet公式ドキュメント翻訳(概要&特徴編)
2.Prophet公式ドキュメント翻訳(インストール編)
3.Prophet公式ドキュメント翻訳(クイックスタート編)
4.Prophet公式ドキュメント翻訳(飽和状態の予測編)
5.Prophet公式ドキュメント翻訳(トレンドの変化点編)
6.Prophet公式ドキュメント翻訳(周期性・イベント効果・説明変数の追加編)
7.Prophet公式ドキュメント翻訳(増加し続ける周期性編)
8.Prophet公式ドキュメント翻訳(誤差の間隔編)
9.Prophet公式ドキュメント翻訳(外れ値編)
10.Prophet公式ドキュメント翻訳(1日単位ではないデータ編)
11.Prophet公式ドキュメント翻訳(モデルの診断編)
12.Prophet公式ドキュメント翻訳(ヘルプ編)

2018/10/28公開。原文リンクは以下。
・Prophet概要&特徴:https://facebook.github.io/prophet/
・公式ドキュメント:https://facebook.github.io/prophet/docs/quick_start.html

今回の記事は1日単位ではないデータ編です。
スクリーンショット (98).png

1日単位より短い間隔のデータ

Prophetはdsカラムにタイムスタンプデータを格納しデータフレームに渡すことで、1日単位より短い間隔の時系列データについても、予測することができます。タイムスタンプの形式はYYYY-MM-DD HH:MM:SSでなければいけません。ここにあるcsvファイルを参考にしてください。1日単位より短い間隔のデータを使う場合、1日単位の周期性が自動的にフィッティングされます。今回はヨセミテ国立公園の毎日の気温を5分単位で分解したデータをProphetでフィッティングしてみましょう。

# R
df <- read.csv('../examples/example_yosemite_temps.csv')
m <- prophet(df, changepoint.prior.scale=0.01)
future <- make_future_dataframe(m, periods = 300, freq = 60 * 60)
fcst <- predict(m, future)
plot(m, fcst)
# Python
df = pd.read_csv('../examples/example_yosemite_temps.csv')
m = Prophet(changepoint_prior_scale=0.01).fit(df)
future = m.make_future_dataframe(periods=300, freq='H')
fcst = m.predict(future)
fig = m.plot(fcst)

image.png
結果のプロットで一日単位の周期性を見ることができます。

# R
prophet_plot_components(m, fcst)
# Python
fig = m.plot_components(fcst)

image.png

断片的なデータ

上で用いたデータが午前12時から午前6時までの気温の観測値しか、入っていなかった場合を想像してください。

# R
df2 <- df %>%
  mutate(ds = as.POSIXct(ds, tz="GMT")) %>%
  filter(as.numeric(format(ds, "%H")) < 6)
m <- prophet(df2)
future <- make_future_dataframe(m, periods = 300, freq = 60 * 60)
fcst <- predict(m, future)
plot(m, fcst)
# Python
df2 = df.copy()
df2['ds'] = pd.to_datetime(df2['ds'])
df2 = df2[df2['ds'].dt.hour < 6]
m = Prophet().fit(df2)
future = m.make_future_dataframe(periods=300, freq='H')
fcst = m.predict(future)
fig = m.plot(fcst)

image.png
予測結果はあまりよくないようです。先ほどすべての時間帯のデータを使って予測した結果よりも、未来の予測にかなり大きな変動が見られます。ここで問題なのは、Prophetが1日の一部のデータ(午前12時から午前6時)を、丸1日の周期性にあてはめようとしていることです。そのため、1日単位の周期性をあてはめる際に、データにない時間帯は適当にフィッティングしています。これでは予測が成立しているとは到底言えません。解決策は、データが存在する時間帯についてのみ、予測を立てるということです。以下では、そのことを実装するためにfutureデータフレームに午前12時から午前6時のみのデータを入れるという制約を設けています。

# R
future2 <- future %>% 
  filter(as.numeric(format(ds, "%H")) < 6)
fcst <- predict(m, future2)
plot(m, fcst)
# Python
future2 = future.copy()
future2 = future2[future2['ds'].dt.hour < 6]
fcst = m.predict(future2)
fig = m.plot(fcst)

image.png
他の断片的なデータに対しても、同じやり方を適用することができます。たとえば、時系列データが平日のみを含んでいる場合、週単位の周期性をあてはめることはできないため、平日のみの周期性をあてはめるように指定します。

月単位のデータ

月単位のデータをProphetのモデルにフィッティングすることもできます。ただProphetでは、モデリングするデータは連続した時系列データであるという前提があります。そのため、月単位のデータをモデルにフィッティングしても、予測結果は日単位のものを返すため、おかしな結果になってしまいます。今回はアメリカの小売り店の売上を10年分予測します。

# R
df <- read.csv('../examples/example_retail_sales.csv')
m <- prophet(df, seasonality.mode = 'multiplicative')
future <- make_future_dataframe(m, periods = 3652)
fcst <- predict(m, future)
plot(m, fcst)
# Python
df = pd.read_csv('../examples/example_retail_sales.csv')
m = Prophet(seasonality_mode='multiplicative').fit(df)
future = m.make_future_dataframe(periods=3652)
fcst = m.predict(future)
fig = m.plot(fcst)

image.png
ここでは、断片的なデータのトピックで扱ったデータセットと同じ問題が起きています。年単位の周期性にデータをあてはめる際に、それぞれの月の最初の日のデータしかなく、その他の日については予測不能か、過学習になってしまっています。この問題は周期性の不確かな部分についてMCMCサンプリングを行うことで、解決できます。

# R
m <- prophet(df, seasonality.mode = 'multiplicative', mcmc.samples = 300)
fcst <- predict(m, future)
prophet_plot_components(m, fcst)
# Python
m = Prophet(seasonality_mode='multiplicative', mcmc_samples=300).fit(df)
fcst = m.predict(future)
fig = m.plot_components(fcst)

image.png
今回の周期性には毎月1日はデータが存在するため、各月の初めのあたりは誤差の幅が小さくなっています。ただ、1ヶ月の中間あたりの誤差の幅は大きくなっています。Prophetのモデルに月単位のデータをフィッティングする場合は、月単位の予測のみを立ててください。make_future_dataframefreqという引数を指定することで予測ができます。

# R
future <- make_future_dataframe(m, periods = 120, freq = 'month')
fcst <- predict(m, future)
plot(m, fcst)
# Python
future = m.make_future_dataframe(periods=120, freq='M')
fcst = m.predict(future)
fig = m.plot(fcst)

image.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした