MSTLの仕組みを理解してパラメータを適切に設定する【Python】【statsmodels】
1. 概要
本記事の目的
本記事では、時系列データを「トレンド」「季節性」「残差」の3要素に分解するSTL[1](Seasonal Trend decomposition using Loess)を拡張し、複数の季節性を持つ時系列データを処理できるようにしたMSTL[2](Multiple STL)について解説します。
MSTLのアルゴリズムを理解し、適切なパラメータ設定を行えるようになることを目指します。
MSTLの概要
まず、MSTLの基礎となるSTLについて簡単に説明します。STLは時系列データを以下の3要素に分解する手法です。
-
トレンド(Trend)
時系列の長期的な傾向 -
季節性(Seasonal)
一定期間で繰り返す周期的な変動(例: 日、週、月、年)
「季節性の周期の長さ」は事前にパラメータで設定 -
残差(Remainder)
トレンドや季節性で説明できない、不規則な変動成分
STLのアルゴリズム・パラメータについては、以下記事を参照してください。
MSTLはSTLを拡張した手法で、時系列データをトレンド・複数の季節性・残差に分解できるようにした手法です。
本記事では、2章でMSTLのアルゴリズム、3章でstatsmodelsのMSTLのパラメータについて解説します。
2. MSTLのアルゴリズム
MSTLは前処理->成分分解->後処理の順に処理を行います。
前処理
1. パラメータ「季節性の周期の長さ」を決定
時系列データに含まれる可能性がある季節性を特定し、それぞれの周期を設定します。
例) 年次、週次の季節性がある日別データの場合
季節性の周期の長さは[365, 7]
となります。
2. 分解対象の季節性を周期の長さでフィルタリング
1で特定した季節性候補のうち、原系列の長さの半分以上の周期をもつ季節性を除外します。ランダムな変動と区別が難しいためです。
例)1年分(365日分)の日別データの場合
周期の長さが365/2=182.5以上の季節性は除外
3. パラメータ「季節性の周期の長さ」を昇順にソート
季節性の分解は、パラメータ「季節性の周期の長さ」の格納順で行われます。そのため、周期の長さの昇順(短い順)にソートしておきます。周期が長い季節性を先に分解すると、短い季節性が吸収される可能性があるためです。
4. 欠損値を補完
正確な分解のために、データの欠損値を補完します。
5. Box-Cox変換
データを正規分布に近づけるための手法で、時系列データを定常化します。特に、
box-cox変換の実装コード
import numpy as np
import matplotlib.pyplot as plt
y = np.linspace(0.1, 10, 100)
fig, ax = plt.subplots()
for lam in [-2, -1, 0, 1, 2]:
if lam == 0:
z = np.log(y)
else:
z = (y**lam - 1) / lam
ax.plot(y, z, label=f'λ = {lam}')
ax.set_xlabel('y')
ax.set_ylabel('z')
ax.legend()
plt.show()
成分分解
時系列が季節性を持つかどうかで、別の処理を行います。
季節性がある時系列
各季節性に対して、パラメータ「iterate」で指定した回数だけSTLを繰り返し、分解の精度を高めます。
以下では、原系列を
1. 各季節性に対して1.1~1.3を実行
以下では、
-
1.1 前ループで分解された季節性を加えた系列を生成する
全ての季節性が除かれた系列(deseas)に、前ループで分解された季節性 を加えます。S_{i}^{(j-1)}
$$
\begin{equation}
deseas + S_{i}^{(j-1)}
\end{equation}
$$ -
1.2. STLを実行
1.1で生成した系列に対してSTLを実行し、季節性 を分解します。S_{i}^{(j)}
- 1.3. 新しく分解された季節成分を1.1の系列から引きます
2. 手順1をパラメータ「iterate」で指定した回数繰り返し
パラメータで指定された回数だけ、手順1を繰り返し、季節性の精度を高めます。
3. 最後のSTLで抽出されたトレンドをMSTLのトレンドとする
季節性がない時系列
局所回帰に基づいたsupersmoother[3]という平滑化手法を原系列に適用することで、トレンドを抽出します。
後処理
原系列からトレンド、季節成分を除いたデータを残差とします。
3. MSTLのパラメータ
Pythonの統計モデルライブラリstatsmodelsでは、statsmodels.tsa.seaasonal.MSTL
[4]クラスを用いてMSTLを実行できます。
statsmodels.tsa.seaasonal.MSTL
クラスのパラメータ
-
periods
季節性の周期の長さ。季節性の数だけ設定します。例えば、日次データから週次成分を抽出したい場合は、7を指定します。 -
windows
季節性をLoess平滑化する際のウィンドウサイズ。季節性の数だけ設定します。STLではseasonal
で設定されていました。 -
lmbda
Box-Cox変換のパラメータ 。\lambda -
iterate
STLの反復回数。 -
stl_kwargs
内部で呼び出しているstatsmodels.tsa.seaasonal.STL
[5]へ渡すパラメータ。
-
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) ↩︎
-
Kasun Bandaraa, Rob J. Hyndmanb, and Christoph Bergmeir. 'MSTL: A Seasonal-Trend Decomposition Algorithm for Time Series with Multiple Seasonal Patterns', arXive preprint arXive:2107.13462, (2021) ↩︎
-
J. H. Friedman, 'A Variable Span Smoother', Stanford University Technical Report No.5(1984) ↩︎
Discussion