9.1 定常性と差分化

定常な時系列とは、その統計的性質が系列の観測時点に依存しない15時系列のことです。ですから、トレンドや季節性のある時系列は、時点が異なれば値も変わるので、定常ではありません。他方、ホワイトノイズ系列は、どこを観測しようがどの時点もだいたい同じように見えるので、定常です。

紛らわしいケースもあります。循環性のある(けれど、トレンドも季節性もない)時系列は定常です。循環は固定長ではないので、系列を観測するまでは、循環の山と谷がどこになるか確信を持てないからです。

一般的に、定常な時系列には長期に予測可能なパターンがありません。時間プロットすると、定常な時系列は均一分散でだいたい横ばい(多少の循環はあるかもですが)になります。

定常な時系列はどれ? (a) Google株価終値(2015年)、(b) Google株価の日次変化(2015年)、(c) 米国年次ストライキ数、(d) 米国新築戸建て住宅の月次販売戸数、(e) 米国卵1ダースの年次価格 (実質価格)、(f) オーストラリア・ビクトリア州の月次豚屠殺数、(g) Hudson Bay Companyが商うカナダ山猫の年間毛皮数、(h) オーストラリア四半期ビール生産量、(i) オーストラリア月次ガス生産量

図 9.1: 定常な時系列はどれ? (a) Google株価終値(2015年)、(b) Google株価の日次変化(2015年)、(c) 米国年次ストライキ数、(d) 米国新築戸建て住宅の月次販売戸数、(e) 米国卵1ダースの年次価格 (実質価格)、(f) オーストラリア・ビクトリア州の月次豚屠殺数、(g) Hudson Bay Companyが商うカナダ山猫の年間毛皮数、(h) オーストラリア四半期ビール生産量、(i) オーストラリア月次ガス生産量

9.1にプロットした9つの系列を検討してみましょう。どれが定常だと思いますか?

明らかな季節性があるので、(d)、(h)、(i)は除外です。トレンドや水準変化があるので、(a)、(c)、(e)、(f) 、(i)も除外です。分散増加の理由からも、(i)は除外できます。残るのは(b)と(g)だけで、これらが定常な系列です。

一見したところ、系列(g)は強い循環性のため、非定常に見えるかもしれません。しかし、これらの循環は一定の周期ではありません。山猫は増え過ぎて餌が足りなくなると繁殖を止めて減少、十分少なくなると食料源が再生して再び増加、と繰り返す結果がこれらの循環です。長期には、これら循環のタイミングは予測できません。ですから、この系列は定常です。

差分化

9.1で、Google株価はパネル(a)では非定常でしたが、パネル(b)の日次変化では定常だったことに気付きましたか? ここから、非定常な時系列を定常にする方法の1つが、連続する観測値の差分を計算することだと分かります。これを、 差分化と言います。

対数を取るなどの変換は、時系列分散の安定化を助けることができます。差分化は、時系列の水準変化を除去してトレンドと季節性を消し去る(もしくは、減じる)ことで、時系列平均の安定化を助けることができます。

データの時間プロットと並んで、ACFプロットも非定常な時系列を特定するのに役立ちます。定常な時系列のACFは比較的速やかにゼロに落ちるのに対し、非定常なデータのACFはゆっくりとしか減少しません。また、非定常なデータでは、\(r_1\)が大きな正の値になることが多いです。

Google株価終値(2015年) (左) とGoogle株価日次変化(2015年) (右)それぞれのACF

図 9.2: Google株価終値(2015年) (左) とGoogle株価日次変化(2015年) (右)それぞれのACF

google_2015 %>%
  mutate(diff_close = difference(Close)) %>%
  features(diff_close, ljung_box, lag = 10)
#> # A tibble: 1 × 3
#>   Symbol lb_stat lb_pvalue
#>   <chr>    <dbl>     <dbl>
#> 1 GOOG      7.91     0.637

差分化したGoogle株価のACFは、ホワイトノイズ系列のものと同じように見えます。95%臨界値の外側にある自己相関は1つだけで、(\(h=10\)とした)Ljung-Box検定での\(Q^*\)統計量のp値は0.637です。ここから、Google株価の日次変化は、本質的に前日とは無相関な確率変数と考えられます。

ランダムウォーク・モデル

差分系列は、元の系列の連続する観測値間の変化であり、次のように書けます。 \[ y'_t = y_t - y_{t-1} \] 差分系列は\(T-1\)個だけの値を持つことになります。最初の観測値の差分\(y_1'\)は計算できないからです。

差分系列がホワイトノイズの場合、元の系列のモデルは次のように書けます。 \[ y_t - y_{t-1} = \varepsilon_t \] ただし、\(\varepsilon_t\)はホワイトノイズを表します。 これを再構成すると、「ランダムウォーク」モデルになります。 \[ y_t = y_{t-1} + \varepsilon_t \] ランダムウォーク・モデルは非定常なデータ、特に金融や経済データ、に広く使われています。ランダムウォークで典型的なのは、

  • 一見、長期間にわたる上昇か下降のトレンドがあり、
  • 突然、予期せぬ方向の変化が起こる。

ランダムウォーク・モデルでは、将来の動きは予測不可能で上昇も下降も等しくあり得るので、予測は最後の観測値と等しくなります。こうして、ランダムウォーク・モデルは、最初に5.2節で紹介したナイーブ予測の土台となっています。

密接に関連するモデルでは、ゼロでない差分の平均を持つことができます。以下のようなモデルです。 \[ y_t - y_{t-1} = c + \varepsilon_t\quad\text{もしくは}\quad {y_t = c + y_{t-1} + \varepsilon_t}\: \] \(c\)値は連続する観測値間差分の平均です。\(c\)が正だと、\(y_t\)の値は平均的には増加します。ですから、\(y_t\)は上方にドリフトしがちになります。一方、\(c\)が負だと、\(y_t\)は下方にドリフトしがちになります。

これが、5.2節で議論したドリフト法の背後にあるモデルです。

2次差分化

ときにはデータを差分化しても定常に見えず、定常な系列を得るには再度差分化する必要があるかもしれません。 \[\begin{align*} y''_{t} &= y'_{t} - y'_{t - 1} \\ &= (y_t - y_{t-1}) - (y_{t-1}-y_{t-2})\\ &= y_t - 2y_{t-1} +y_{t-2} \end{align*}\] この場合、\(y_t''\)\(T-2\)個の値を持つことになります。元のデータの「変化の変化」をモデル化しようとしていることになります。実際には、2次よりも高次の差分化の必要はまずありません。

季節差分化

季節差分は、観測値と、同じ季節で1つ前の観測値、との差分です。ですから、以下のようになります。 \[ y'_t = y_t - y_{t-m} \] ただし、\(m\)は季節周期です。ラグ\(m\)の観測値を控除するので、「ラグ\(m\)差分」とも言います。

季節差分データがホワイトノイズに見えるなら、元のデータの適切なモデルは、以下のようになります。 \[ y_t = y_{t-m}+\varepsilon_t \] このモデルからの予測は同季節の最後の観測値と等しくなります。つまり、このモデルは、5.2節で紹介した季節ナイーブ予測を与えてくれます。

9.3の一番下のパネルは、オーストラリアで販売されているA10(抗糖尿病薬)の月次売上高の対数の季節差分を示しています。変換と差分化によって、系列は比較的定常に見えます。

A10 (抗糖尿病薬) 売上高データの対数と季節差分。対数を取ることで分散を安定化させる一方、季節差分を取ることで季節性とトレンドを除去している

図 9.3: A10 (抗糖尿病薬) 売上高データの対数と季節差分。対数を取ることで分散を安定化させる一方、季節差分を取ることで季節性とトレンドを除去している

季節差分と普通の差分を区別するため、普通の差分のことを、ラグ1との差分という意味で、「一つ目差分」と言うことがあります。

定常なデータを得るのに、季節差分と一つ目差分の両方を取ることが必要になることがときにあります。図9.4の一番上のパネルは、オーストラリアでのコルチコステロイド薬の売上高(オーストラリア・ドル)をプロットしています。2つ目のパネルでまずデータの対数を取って変換し、3つ目のパネルでさらに季節差分を計算しています。でもまだ、データはいくらか非定常なようです。そこで、一番下のパネルでもう一段一つ目差分を計算しています。

PBS %>%
  filter(ATC2 == "H02") %>%
  summarise(Cost = sum(Cost)/1e6) %>%
  transmute(
    "売上高 (百万ドル)" = Cost,
    "売上高の対数" = log(Cost),
    "売上高の対数の季節差分" = difference(log(Cost), 12),
    "売上高の対数の二階差分" =
                     difference(difference(log(Cost), 12), 1)
  ) %>%
  pivot_longer(-Month, names_to="Type", values_to="Sales") %>%
  mutate(
    Type = factor(Type, levels = c(
      "売上高 (百万ドル)",
      "売上高の対数",
      "売上高の対数の季節差分",
      "売上高の対数の二階差分"))
  ) %>%
  ggplot(aes(x = Month, y = Sales)) +
  geom_line() +
  facet_grid(vars(Type), scales = "free_y") +
  labs(title = "コルチコステロイド薬の売上高", y = NULL)
一番上のパネル: コルチコステロイド薬の売上高(オーストラリア・ドル)。他のパネルは、変換と差分化後の同じデータを示している

図 9.4: 一番上のパネル: コルチコステロイド薬の売上高(オーストラリア・ドル)。他のパネルは、変換と差分化後の同じデータを示している

どれだけ差分化するかの選択は、ある程度主観的に行っています。図9.3の季節差分データは、図9.4の季節差分データと比べて、動きはそれほど違いません。後者のケースでは、季節差分データで止めて、もう一段の差分化は行わないこともできました。前者のケースでは、まだ十分定常ではないとして、もう一段差分化することもできました。差分化の公式な検定をいくつか後で議論しますが、モデル化のプロセスでは常にいくつかの選択が必要で、違った分析者は違った選択をすることがあり得ます。

\(y'_t = y_t - y_{t-m}\)を季節差分系列とすると、二階差分系列は以下のようになります。 \[\begin{align*} y''_t &= y'_t - y'_{t-1} \\ &= (y_t - y_{t-m}) - (y_{t-1} - y_{t-m-1}) \\ &= y_t -y_{t-1} - y_{t-m} + y_{t-m-1}\: \end{align*}\] 季節差分と一つ目差分の両方を適用する際は、どちらを最初に行っても変わりはありません。つまり、結果は同じになります。しかし、データに強い季節パターンがあるなら、季節差分化を最初に行うことをお薦めします。それで系列が定常になり、それ以上一つ目差分を取る必要がないことがあるからです。もし最初に一つ目差分を取ると、季節性が確実に残ってしまいます。

必要以上に差分を取ると、実際には存在しない偽の強弱や自己回帰を時系列に引き起こすことに注意が必要です。ですから、定常な系列を得るのに必要最小限の差分を取るようにしてください。

差分化する際は、解釈可能な差分にすることが重要です。一つ目差分は、観測値と次の観測値の間の変化と解釈できます。季節差分は、ある年と翌年の間の変化と解釈できます。その他のラグは、解釈可能な意味がありそうにないので、避けるべきです。

単位根検定

より客観的に差分化が必要か決める方法の1つは、単位根検定を使うことです。差分化が必要か決めるために設計された、定常性の統計的仮説検定です。

多くの単位根検定が利用可能ですが、異なる想定に基づいているため、回答は異なるかもしれません。私たちの分析では、Kwiatkowski-Phillips-Schmidt-Shin (KPSS) 検定 (Kwiatkowski et al., 1992) を使います。この検定では、帰無仮説をデータが定常であると置いて、帰無仮説が偽である証拠を探します。従って、小さなp値(例えば、0.05より小さい)は差分化が必要なことを示唆します。検定は、unitroot_kpss()関数を使って計算できます。

例えば、Google株価データに適用してみましょう。

google_2015 %>%
  features(Close, unitroot_kpss)
#> # A tibble: 1 × 3
#>   Symbol kpss_stat kpss_pvalue
#>   <chr>      <dbl>       <dbl>
#> 1 GOOG        3.56        0.01

p値は、0.01よりも小さいと0.01と出力され、0.1よりも大きいと0.1と出力されます。このケースでは、検定統計量(3.56)は1%の臨界値より大きく、そのためp値は0.01よりも小さく、帰無仮説は棄却されます。つまり、データは定常でない、と示しています。ですから、データを差分化して、再度検定してみます。

google_2015 %>%
  mutate(diff_close = difference(Close)) %>%
  features(diff_close, unitroot_kpss)
#> # A tibble: 1 × 3
#>   Symbol kpss_stat kpss_pvalue
#>   <chr>      <dbl>       <dbl>
#> 1 GOOG      0.0989         0.1

今度は、検定統計量は小さく、定常なデータに期待する範囲内に十分収まっており、そのためp値は0.1より大きくなっています。この差分データは定常に見えると結論できます。

unitroot_ndiffs()特徴量を使うと、一つ目差分を取る適切な回数を求めてKPSS検定を繰り返すこのプロセスが実行されます。

google_2015 %>%
  features(Close, unitroot_ndiffs)
#> # A tibble: 1 × 2
#>   Symbol ndiffs
#>   <chr>   <int>
#> 1 GOOG        1

先のKPSS検定で見たのと同じく、google_2015データを定常にするのに1回の差分が必要と出ました。

季節差分が必要か決める似たような特徴量がunitroot_nsdiffs()で、季節差分が必要な適切な回数を決めるため、4.3節で紹介した季節性の強さの指標を使っています。\(F_S<0.64\)なら季節差分はなし、それ以外なら1回の季節差分を提案します。

オーストラリアの月次総小売売上高にunitroot_nsdiffs()を適用してみます。

aus_total_retail <- aus_retail %>%
  summarise(Turnover = sum(Turnover))
aus_total_retail %>%
  mutate(log_turnover = log(Turnover)) %>%
  features(log_turnover, unitroot_nsdiffs)
#> # A tibble: 1 × 1
#>   nsdiffs
#>     <int>
#> 1       1

aus_total_retail %>%
  mutate(log_turnover = difference(log(Turnover), 12)) %>%
  features(log_turnover, unitroot_ndiffs)
#> # A tibble: 1 × 1
#>   ndiffs
#>    <int>
#> 1      1

unitroot_nsdiffs()が1(1回の季節差分が必要ということ)を返すので、次に、季節差分を取ったデータにunitroot_ndiffs()関数を適用します。これらの関数は、1回の季節差分と1回の一つ目差分の両方を取るよう提案しています。

参考文献

Kwiatkowski, D., Phillips, P. C. B., Schmidt, P., & Shin, Y. (1992). Testing the null hypothesis of stationarity against the alternative of a unit root: How sure are we that economic time series have a unit root? Journal of Econometrics, 54(1-3), 159–178. [DOI]

  1. より厳密には、\(\{y_t\}\)定常な時系列だと、全ての\(s\)\((y_t,\dots,y_{t+s})\)の分布は\(t\)に依存しない、です。↩︎