BSTSモデル(R)からの予測は完全に失敗しています


15

ベイジアン構造時系列モデルに関するこのブログ投稿を読んだ後、以前にARIMAを使用していた問題のコンテキストでこれを実装することを検討しました。

私はいくつかの既知の(しかしノイズの多い)季節的要素に関するデータを持っています-これには間違いなく年次、月次、週次の要素があり、特別な日(連邦政府や宗教の祝日など)による影響もあります。

bstsパッケージを使用してこれを実装しましたが、コンポーネントと予測は単に期待どおりに見えませんが、間違ったことは何もしていないと言えます。私の実装が間違っているか、不完全であるか、その他の問題があるかどうかは明確ではありません。

フルタイムシリーズは次のようになります。

全データ

データの一部のサブセットでモデルをトレーニングできます。モデルは一般に適合性の点で見栄えがよくなります(プロットは下にあります)。これを行うために使用しているコードは次のとおりです。

library(bsts)

predict_length = 90
training_cut_date <- '2015-05-01'
test_cut_date <- as.Date(training_cut_date) + predict_length

df = read.csv('input.tsv', sep ='\t')

df$date <- as.Date(as.character(df$date),format="%Y-%m-%d")
df_train = df[df$date < training_cut_date,]

yts <- xts(log10(df_train$count), order.by=df_train$date)

ss <- AddLocalLinearTrend(list(), yts)
ss <- AddSeasonal(ss, yts, nseasons = 7)
ss <- AddSeasonal(ss, yts, nseasons = 12)
ss <- AddNamedHolidays(ss, named.holidays = NamedHolidays(), yts)

model <- bsts(yts, state.specification = ss, niter = 500, seed=2016)

モデルは合理的に見えます:

モデルプロット

しかし、予測をプロットすると、最初に傾向が完全に間違っており、次に不確実性が非常に急速に増加します-対数軸上にy軸を作成せずに予測と同じプロットに不確実性バンドを表示できないポイントまで規模。この部分のコードは次のとおりです。

burn <- SuggestBurn(0.1, model)
pred <- predict(model, horizon = predict_length, burn = burn, quantiles = c(.025, .975))

純粋な予測は次のようになります。

純粋な予測

そして、初期分布にスケールバックすると(点線がトレーニングから予測への移行を示しているため、問題は明らかです:

完全なディストリビューション

私は、季節のトレンドを追加し、季節のトレンドを削除し、AR項を追加し、AddLocalLinearModelをAddGeneralizedLocalLinearTrendに変更し、モデルの調整に関する他のいくつかのことを試みましたが、問題を解決し、予測をより意味のあるものにしませんでした。場合によっては方向が変わるため、0に低下するのではなく、予測は時間の関数として増加し続けます。モデルがこのように壊れている理由を私は絶対に理解していません。どんな提案も大歓迎です。


2
なぜデータを投稿しないと私は助けようとします...このアプローチはあまりにも多くの前提が組み込まれているため、このアプローチを使用していないため、モデルが壊れている理由に答えることはできません。差し控えられた値の数、開始日、および原産国に関する正確な情報。
IrishStat

コメントありがとうございます。ご覧になる時間がある場合に備えて、ここに生データをアップロードしました。データの範囲は2013年の初めから今年の終わりまでです。また、ARIMAモデルを使用して予測を試みましたが、その予測はホールドアウトデータとも一致しませんでした。ホールドアウトデータは、使用したいトレーニングデータの量に応じて、基本的に2015年または2016年のほんの一部です。
-anthr

私は私のメールアドレスにcsvファイルを送ってください...それをダウンロード中に問題が生じています
IrishStat

回答:


26

ここにスティーブ・スコット。bstsパッケージを書きました。いくつかの提案があります。第一に、季節性成分は、あなたが思っていることをしていない。7シーズンのコンポーネントを追加しようとしているので、正しく機能するはずなので、毎日のデータがあると思います。しかし、あなたは毎年の季節的な要素を12日ごとに繰り返すように言っています。毎日のデータで毎月の季節コンポーネントを取得するのは少し難しいですが、で52週間の季節を行うことができます AddSeasonal(..., nseasons = 52, season.duration = 7)

このseasonal.duration引数は、各シーズンの持続時間をモデルに指示します。nseasons引数には、多くの季節がサイクル内にあるどのようにそれを伝えます。サイクルの合計時点数はseason.duration * nseasonsです。

2番目の提案は、トレンドの別のモデルを検討することです。LocalLinearTrendモデルは非常に柔軟ですが、この柔軟性は、長期的な予測では望ましくない変動として表示することができます。もう少し構造を含む他のトレンドモデルがいくつかあります。 GeneralizedLocalLinearTrend(わかりにくい名前についてはごめんなさい)は、トレンドの「勾配」コンポーネントがランダムウォークではなくAR1プロセスであると想定しています。将来を予測する場合、これがデフォルトのオプションです。あなたが試みる場合がありますので、ご使用の時系列変化のほとんどは、季節性から来ているようだAddLocalLevel、あるいはAddAr代わりにAddLocalLinearTrend

最後に、一般に、奇妙な予測を取得していて、モデルのどの部分に責任があるかを知りたい場合は、モデルがplot(model, "components")要求した個々の部分に分解されるのを確認してください。


参考までに、私も自分のデータに関して非常によく似た問題を抱えています。これも毎日の問題です。ここにリストされているすべての提案を実装しましたが、どれも役に立たないようです。
ZakJ 16

1
@スティーブスコットスティーブ、お邪魔してすみません、複数の時系列をモデル化しようとしていて、階層混合モデルフレームワークを使用している場合、パッケージを使用してこれをモデル化できますか?ところで、あなたのパッケージに感謝します!
トンマーゾGuerrini

4

デフォルトの書き込みも変更できると思います。bstを使用したので、ホールドアウト期間の統計としてMAPEを使用してバーン値とナイター値のグリッドを作成しました。また、モデルがそのような変動を予測するためにデータに大きな変動がある場合は、代わりにAddStudentLocalLinearTrendを使用してみてください


1
データポイントが少ない(20)
SCallan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.