STL分解の仕組みを理解してパラメータを適切に設定する【python】
1. 概要
本記事では、時系列データをトレンド、季節性、残差の3要素に分解する手法であるSTL分解[1](Seasonal Trend decomposition using Loess)について解説します。STL分解は、複雑な時系列データを理解しやすい要素に分解することで、データの特徴を把握するのに役立ちます。
本記事の目的は以下の2点です。
- STL分解の仕組みとSTLで使われるLoessを理解する
- STL分解のパラメータの意味を知り、適切に設定できるようになる(statsmodels)
2. Loess
Loess(Locally Estimated Scatterd Smoothing)は局所回帰の一手法で、STL分解において季節性やトレンド等の平滑化に使用されます。以下にLoessの手順を説明します。
2.1 基本的な平滑化手順
注目する点を1点ずつずらしながら、以下手順を行います。
- 注目する点の近傍点に対して、「近傍重み」(2.3参照)を計算する
- 使用する近傍点の数はパラメータ「ウィンドウサイズ」で事前に指定
- 重み付き最小二乗法による回帰を行う
- 回帰に用いる多項式の次数はパラメータで事前に指定(一般的には1次または2次を使用)
- 注目している点の回帰結果を平滑化値とする
- 手順1~3を全ての点に対して実行
2.2 外れ値への対応
基本的な平滑化では、外れ値が回帰線に大きな影響を与える可能性があります。そこで、以下の追加手順を行います。
- 全ての点に対して、平滑化値と元の値との残差を求める
- 残差から「ロバスト重み」(2.4参照)を計算する
- 近傍重みとロバスト重みの両方を使用して、手順2~4を再実行
- 手順5~7を指定回数繰り返す
ここで2種類の重みは以下の特徴を持っています。
- 近傍重み: 注目する点に近い点ほど大きい重みが与えられる
- ロバスト重み: 外れ値に小さい重みが与えられる
以下で、各重みの計算方法を説明します。
2.3 近傍重みの計算方法
ここで、
式(2)より、点
つまり、近傍重みは以下の特徴を持つことがわかります。
- 注目する点に近い点ほど大きな重みを与える
- ウィンドウサイズ
が大きいほど、滑らかな回帰線となるq
2.4 ロバスト重みの計算方法
点
ここで、
点
式(4)より、残差
つまり、ロバスト重みは以下の特徴を持つことがわかります。
- 外れ値には小さい重みを与える
3. STL分解のアルゴリズム
3.1 inner loopとouter loop
STL分解は、inner loopとouter loopという2種類のループ処理を組み合わせることで、時系列データの分解を行います。
- inner loop: 原系列に対して、トレンド・季節性・残差への分解を繰り返す
- outer loop: inner loopで計算された残差を用いて、ロバスト重みを更新
outer loopの処理の中にinner loopが含まれる構造となっており、それぞれのループの反復回数はパラメータで指定します。例えばinner loopを2回、outer loopを5回とすると、5回のouter loopの中で2回ずつinner loopが実行されます。このようにinner loopとouter loopを複数回繰り返すことで、分解の精度を高めていきます。
inner loopとouter loopのフローチャート
3.2 STL分解の手順
原系列を
以下では(k+1)回目の分解の手順を説明し、
3.2.1 inner loop
1. トレンドの除去
原系列から前回(k回目)の分解で計算されたトレンド成分を除去します。初回の分解(
2. 周期成分の平滑化
手順1でトレンドを除去したデータから、季節性の周期の長さごとに点を抽出し、Loess平滑化を適用します。季節性の周期の長さと平滑化のウィンドウサイズはパラメータで指定します。平滑化された周期成分を
3. 平滑化周期成分にローパスフィルタ適用
手順2で計算した平滑化周期成分
4. 周期成分からトレンドを除去
手順2で計算した平滑化周期成分
5. 季節性の除去
原系列から手順4で計算した季節性
6. トレンド平滑化
手順5の結果に対してLoess平滑化を適用し、トレンド
7. 手順1~6を指定回数繰り返し
パラメータで指定された回数だけ、手順1〜6 を繰り返します。
3.2.2 outer loop
1. 残差を計算
inner loopによって原系列が季節性とトレンドに分解されたので、残差を計算します。
2. ロバスト重みを計算
手順1で計算した残差
3. inner loopの実行
更新されたロバスト重みを用いて、inner loopのを実行します。
3.3 周期成分のLoess平滑化
inner loopの手順2「周期成分の平滑化」では、以下手順で平滑化を行います。
- 事前に設定したパラメータ「季節性の周期の長さ」ごとに、原系列から点を抽出
- 抽出したデータに対して、Loess平滑化
例えば、日次データから曜日成分を分解する場合、曜日ごとに(7ずつ)点を抽出し、Loess平滑化を行います。
4. STL分解のパラメータ
Pythonの統計モデルライブラリStatsmodelsでは、statsmodels.tsa.seaasonal.STL
[2]クラスを用いてSTL分解を実行できます。
statsmodels.tsa.seaasonal.STL
クラスのパラメータ
4.1 -
period
季節性の周期の長さ。例えば、月次データから年次成分を抽出したい場合は、12を指定します。 -
seasonal
季節性をLoess平滑化する際のウィンドウサイズ。 -
trend
トレンドをLoess平滑化する際のウィンドウサイズ。 -
low_pass
ローパスフィルタをLoess平滑化する際のウィンドウサイズ。 -
seasonal_deg
季節性をLoess平滑化する際の次数。 -
trend_deg
トレンドをLoess平滑化する際の次数。 -
low_pass_deg
ローパスフィルタで抽出した低周波成分をLoess平滑化する際の次数。 -
robust
ロバスト重みを使用するかどうかを指定するフラグ。 -
seasonal_jump
季節性をLoess平滑化する際のスキップ値。seasonal_jump=1
とすると全ての点に対して平滑化値を計算し、2とすると1つ飛ばしで平滑化値を計算します。飛ばされた点は、前後の点から線形補間されます。大きな値を設定すると、平滑化値を計算する点が減るため、処理時間が短縮されます。 -
trend_jump
トレンドをLoess平滑化する際のスキップ値。 -
low_pass_jump
ローパスフィルタで抽出した低周波成分をLoess平滑化する際のスキップ値。
fit
[3]メソッドのパラメータ
4.2 -
inner_iter
inner loopの反復回数。 -
outer_iter
outer loopの反復回数。
5. まとめ
本記事では、STL分解の仕組みとパラメータについて解説しました。ライブラリを使うことで簡単に試せるので、ぜひ使ってみてください。
-
Robert B. Cleveland, William S. Cleveland, Jeam E. McRae, and Irma Terpenning. 'STL: A Seasonal-Trend Decomposition Procedure Based on LOESS', Journal of Official Statistics, vol6, No.1, pp.3-73, (1990) ↩︎
Discussion