時系列データの予測がしたい

時系列データというのは時刻など時間の何かがインデックスになってるデータのことだそうで、例えば毎日の平均気温とかがそうです。全くもってランダムだったりするかもしれませんが、気温のように

  • 24 時間周期とか 1 年周期で上がったり下がったりしながら
  • でも温暖化してるんじゃない? と上がっているような、氷河期に向かうときは下がっていくような
  • 隕石が落ちたり噴火があったりで空が何かで覆われると涼しく (寒く?) なったり
  • そもそも毎日の天気とかエルニーニョとか暑めだったり寒めだったり

  • 周期性 (複数あるかも、季節性とも)
  • 長期的なトレンド (温暖化とか氷河期とかは周期性かもしれませんが...)
  • 例外的なイベントによる外れ値的なものたち
  • 観測や環境によるノイズ

などの成分に分けて理解しようとするのが基本のようです。

予測をしようと思ったら、周期とトレンドはそのまま伸ばしてみつつ、例外的といってもバレンタインのチョコの売り上げとかは予測できる例外と思ってみたりトレンドの変更点も分かれば追加してみたりしつつ、未来のことを予測してみようというのが時系列の予測です。

どんなもんがあるのかなと思って少し調べてみたので、忘れないようにメモっておきます。

前処理

成長というのは倍々で起こることもあるので、そんなときは log を取ると真っ直ぐになって嬉しいです。漸化式のように、差を取ると分かりやすくなることもあるかもしれません。そんな感じで、与えられている数列を操作して別の数列を作ってそれで予測を立てて、逆の手順で欲しかった予測値を出すことがあります。「前処理大全」でも少し時系列データの前処理に触れられています。

AR-MA 系、若しくは ARIMA

AR は Autoregressor の、MA は Moving Average の略です。それぞれ、次の値は「過去の幾つかの値の線形結合 + ノイズになってる」、「過去のノイズの線形結合 + ノイズ」になっているという過程で線形結合の係数を探していくやりかたです。ノイズは正規分布を仮定して。

  • 前処理として 1 階差分を 1 回以上取るのを Integrated と言うらしく ARIMA と言ってみたり
  • 季節性 = Seasonality で複数階の差分を取って考えてみて SARIMA と言ってみたり
  • 外的要因 = eXternal REGressor を考えて ARIMAX と言ってみたり
  • ノイズが大きさをダイナミックにしてみて (Conditional Heteroscedasticity) ARCH と言ってみたり
  • お互いに関係がありそうな複数の時系列をベクトルにして AR して VAR (Vector AR) と言ってみたり

色々なバリエーションがあります。詳しくは Wikipedia自己回帰移動平均モデルとかARCHモデルを。

例えば、アメリカセンサス局が作った X-12-ARIMA っていう実装があるらしく操作マニュアル日本銀行がウェブページに置いています。そんだけ古典的で枯れているということのようです。

時系列分析と状態空間モデルの基礎」という本が丁寧で分かりやすいでした。写経のし甲斐がある。

TRAMO-SEATS

スペイン銀行が作ったらしいです。X-12-ARIMA の後継で X-13ARIMA-SEATS というのがあるのですが、「季節調整法に関する最近の動向:X-12-ARIMA から X-13ARIMA-SEATS へ」によると ARIMA も TRAMO-SEATS もいけるようにしたもののようです。ヨーロッパ政府機関などでは TRAMO-SEATS が主流のようですね。使ってないのでこれ以上何も言えないのですが、「R {seasonal} パッケージで X13-ARIMA-SEATSを使う」とのことで R でもいけるみたいです。

状態空間モデル

状態空間という、予測したい値とは別に何か (多次元かもしれない) 時系列データを考えて、そっちの予測と状態から欲しかった観測値の関係のパラメータを探していくモデル。ARIMA と表現できるモデルが結構被っているみたいなんだけど、実際どこまで被っているのかは未確認。でも ARIMA と違って解釈は状態空間に意味を込めやすく楽らしい。ARIMA は過去のデータの線型結合を取りますが、それは確かに理解しづらそう。

1 つ制約があって、状態空間は直前の値にだけ依存するようにしています。マルコフ性、って言うのかな。

状態空間の遷移も状態からの観測も関数なら何でもいいんだけど、何でもいいと色々大変なので、線型に絞って考えることが多くそれでも色々良いみたい。状態遷移にも観測にもノイズを乗せるのですが、これも正規分布を仮定することが基本のようです。ただ、それだと表現力が限られたりもするのでそこから逸脱して、となると色々な方法を使わないと状態遷移・観測の関数の推測が難しくなっていって色々な方法が提案されています。「状態空間モデル」というフレームワークがあって、状態遷移・観測に応じて様々な関数推測の方法があるみたい。

状態空間モデルは「時系列分析と状態空間モデルの基礎」でも扱われていますが、「基礎からわかる時系列分析」だと数式てんこ盛りで、信号処理の話などを引用しつつ説明してくれています。

EWMA (Exponential Weighted Moving Average)

ごめんなさい、「基礎からわかる時系列分析」で Holt-Winters っていう方法が紹介されてて EWMA の一種だって書いてあったんです。名前からしてきっと Linux の load average と同じような計算しているに違いありません。というか、これは AR-MA に入れるべきか? 1つブログ記事を紹介してお茶を濁します: 異常検知のための未来予測:オウム返し的手法からHolt-Winters Methodまで

Wiener-filter

ごめんなさい、「基礎からわかる時系列分析」で Wiener-filter っていう方法が (ry。カルマンフィルタってのが状態空間モデルでの予測の方法で出てきますが、「フィルタ」って付いてるやつは信号処理由来のにおいがプンプンしますね。「やる夫で学ぶディジタル信号処理」がとてつもなく分かりやすくて感動しました。

ランダムフォレスト

ランダムフォレストで回帰ができるので、これで時系列予測しちゃいます。こんな感じで

Prophet

Facebook が作った、業務知識さえあれば使える、みたいなのを目指してるライブラリです。数値を見る、というよりは曲線をフィットさせる、という考えかた、らしい。「fb Prophet の解剖で学ぶベイズ時系列モデリング」で Stan による実装の話が紹介されています、素晴しすぎる。

実際、

  • 何も考えずに時系列データを入れるだけで「いい感じ」にやってくれ
  • トレンドの変換点も頻度指定ありで勝手に推測してくれたり細かい日付けの指定ができたり
  • 季節性も勝手に判断してくれたり強制させたり時前で好みの季節性指定できたり
  • 祝日なども複数の種類を簡単に指定して前後何日くらい影響があるか指定できたり

分かり易く色々なパラメータが指定できて良い感じでした。

DeepAR

Amazon の実装で、RNN (recurrent neural network) 使っています。近々、近々試そうと思っています。SageMaker 含めて。

実装

ARIMA・ランダムフォレスト・状態空間モデル・prophet は Python でも R で何かしら実装があります。prophet はどっちも結局 Stan への wrapper だそうですが、他のやつは実装によって色々挙動や調整のし易さが違いそうですね...。ARIMA とランダムフォレスト枯れているというか説明も沢山ありそうで prophet の次に手軽そうでした。

100% な予測はありえないので、コスパとか相性を見ながら良い方法が選べるといいですね!