4.3 STL特徴量

3章で議論したSTL分解が、さらにいくつかの特徴量の基礎となります。

時系列分解は時系列データのトレンドと季節性の強さを測るのに利用できます。分解は以下のように書くことができることを思い出しましょう。 \[ y_t = T_t + S_{t} + R_t \] ここで、\(T_t\)は平滑化されたトレンド成分、\(S_{t}\)は季節成分、そして、\(R_t\)は残余成分です。トレンドの強いデータでは、季節調整値は残余成分よりもずっと大きな分散になっているはずです。ですから、Var\((R_t)\)/Var\((T_t+R_t)\)は比較的小さくなるはずです。しかし、トレンドが弱いか、ないデータでは、それら2つの分散はおおよそ同じはずです。故に、トレンドの強さを以下のように定義します。 \[ F_T = \max\left(0, 1 - \frac{\text{Var}(R_t)}{\text{Var}(T_t+R_t)}\right) \] こうすることで、トレンドの強さを0から1の値で測ることができます。残差の分散が季節調整値の分散より大きい場合が時にあるので、\(F_T\)の取り得る最小値をゼロにしています。

季節性の強さも同様に定義できます。ただし、季節調整値と比べるのではなく、トレンド除去後のデータと比べる点が異なります。 \[ F_S = \max\left(0, 1 - \frac{\text{Var}(R_t)}{\text{Var}(S_{t}+R_t)}\right) \] 季節性の強さ\(F_S\)がゼロに近い系列は季節性をほとんど示さないのに対し、強い季節性のある系列ではVar\((R_t)\)がVar\((S_{t}+R_t)\)よりずっと小さいので\(F_S\)は1に近くなります。

これらの特徴量は、例えば、多くの時系列データ中から最もトレンドの強い系列、あるいは、最も季節性の強い系列を探し出す必要がある時に有益です。これらを含むSTLに基づく特徴量はfeat_stl()関数を使って計算できます。

tourism %>%
  features(Trips, feat_stl)
#> # A tibble: 304 × 12
#>    Region   State    Purpose trend_strength seasonal_strengt… seasonal_peak_y…
#>    <chr>    <chr>    <chr>            <dbl>             <dbl>            <dbl>
#>  1 Adelaide South A… Busine…          0.464             0.407                3
#>  2 Adelaide South A… Holiday          0.554             0.619                1
#>  3 Adelaide South A… Other            0.746             0.202                2
#>  4 Adelaide South A… Visiti…          0.435             0.452                1
#>  5 Adelaid… South A… Busine…          0.464             0.179                3
#>  6 Adelaid… South A… Holiday          0.528             0.296                2
#>  7 Adelaid… South A… Other            0.593             0.404                2
#>  8 Adelaid… South A… Visiti…          0.488             0.254                0
#>  9 Alice S… Norther… Busine…          0.534             0.251                0
#> 10 Alice S… Norther… Holiday          0.381             0.832                3
#> # … with 294 more rows, and 6 more variables: seasonal_trough_year <dbl>,
#> #   spikiness <dbl>, linearity <dbl>, curvature <dbl>, stl_e_acf1 <dbl>,
#> #   stl_e_acf10 <dbl>

これらの特徴量をプロットすれば、どのタイプの系列がトレンドが強く、どのタイプが季節性が強いのか特定できます。

tourism %>%
  features(Trips, feat_stl) %>%
  ggplot(aes(x = trend_strength, y = seasonal_strength_year,
             col = Purpose)) +
  geom_point() +
  facet_wrap(vars(State))
全ての旅行系列での、季節性の強さ vs トレンドの強さ

図 4.1: 全ての旅行系列での、季節性の強さ vs トレンドの強さ

明らかにHoliday(休暇)系列が最も季節性が強いのは、驚くに当たりません。最も強いトレンドは、Western Australia州とVictoria州に見られます。次のコードのようにすれば、最も季節性の強い系列を簡単に特定し、その系列の時間プロットを描くこともできます。

tourism %>%
  features(Trips, feat_stl) %>%
  filter(
    seasonal_strength_year == max(seasonal_strength_year)
  ) %>%
  left_join(tourism, by = c("State", "Region", "Purpose")) %>%
  ggplot(aes(x = Quarter, y = Trips)) +
  geom_line() +
  facet_grid(vars(State, Region, Purpose))
オーストラリア旅行データ中で最も季節性の強い系列

図 4.2: オーストラリア旅行データ中で最も季節性の強い系列

最も季節性の強い系列は、オーストラリアで最も人気のあるスキー地域へのHoliday(休暇)旅行でした。

feat_stl()関数は、これまでに議論したもの以外に、さらにいくつかの特徴量を出力します。

  • seasonal_peak_yearは、山のタイミングを示します。つまり、どの月、あるいは、どの四半期が最大の季節成分を有しているかを示します。よって、季節性の性質について、何事かを教えてくれます。オーストラリア旅行データでは、3(第3四半期が山)ならその地域へは冬に人々が訪れ、1(第1四半期が山)ならその地域は夏の方が人気がある、と教えてくれるのです。
  • seasonal_trough_yearは、谷のタイミングを示します。つまり、どの月、あるいは、どの四半期が最小の季節成分を有しているかを示します。
  • spikinessは、STL分解による残余成分\(R_t\)中のスパイク(突起)の発生頻度を測ります。\(R_t\)の1個抜き分散を個数分計算したその分散になります。
  • linearityは、STL分解によるトレンド成分の線形性を測ります。トレンド成分に線型回帰を適用して得た係数に基づいています。
  • curvatureは、STL分解によるトレンド成分の曲率を測ります。トレンド成分に直交2次多項式回帰を適用して得た係数に基づいています。
  • stl_e_acf1は、残差系列のラグ1の自己相関係数です。
  • stl_e_acf10は、残差系列のラグ1からラグ10までの自己相関係数10個の平方和です。