- 問題
- 答え
- 解説
adj = data - r.seasonal として作成している系列は何を目的としたものですか?
Python コード:
import numpy as np, pandas as pd
from statsmodels.tsa.seasonal import STL
np.random.seed(42)
t = np.arange(48)
data = pd.Series(100 + 0.5*t + 15*np.sin(2*np.pi*t/12)
+ np.random.randn(48)*2,
index=pd.date_range('2022', periods=48, freq='MS'))
r = STL(data, period=12).fit()
adj = data - r.seasonal
df = pd.DataFrame({'原系列': data, '季節成分': r.seasonal, 'adj': adj})
print(df.iloc[[0, 3, 6, 9, 12]].round(2))
print(f"\n前月比の平均絶対変化 原系列:{data.diff().abs().mean():.2f}"
f" adj:{adj.diff().abs().mean():.2f}")
回答の選択肢:
(A) 季節性を除去し、基調的なトレンドや変化を見やすくした系列
(B) トレンドを除去し、季節パターンだけを取り出した系列
(C) ノイズを除去し、滑らかにした系列
(D) 季節成分を強調し、周期性を際立たせた系列
原系列 季節成分 adj 2022-01-01 100.99 -0.19 101.19 2022-04-01 119.55 16.40 103.14 2022-07-01 106.16 1.89 104.27 2022-10-01 90.59 -13.67 104.25 2023-01-01 106.48 0.14 106.34 前月比の平均絶対変化 原系列:5.27 adj:1.48
正解: (A)
adjは季節調整済み系列です。STL分解で推定した季節成分を原系列から差し引くことで、周期的な季節変動を取り除いています。出力を見ると、原系列は4月に119.55、10月に90.59と大きく上下していますが、adjは101→103→104→104→106と緩やかに上昇しており、季節変動に隠れていた基調的なトレンドが見えるようになっています。前月比の平均絶対変化も5.27から1.48へ大幅に縮小しており、月ごとの比較がしやすくなったことを示しています。
回答の選択肢:
(A) 季節性を除去し、基調的なトレンドや変化を見やすくした系列
(B) トレンドを除去し、季節パターンだけを取り出した系列
(C) ノイズを除去し、滑らかにした系列
(D) 季節成分を強調し、周期性を際立たせた系列
- コードの解説
-
このコードは、季節性とトレンドを持つ月次データに対してSTL分解を行い、季節調整済み系列を作成しています。
import numpy as np, pandas as pd from statsmodels.tsa.seasonal import STL np.random.seed(42) t = np.arange(48) data = pd.Series(100 + 0.5*t + 15*np.sin(2*np.pi*t/12) + np.random.randn(48)*2, index=pd.date_range('2022', periods=48, freq='MS')) r = STL(data, period=12).fit() adj = data - r.seasonal df = pd.DataFrame({'原系列': data, '季節成分': r.seasonal, 'adj': adj}) print(df.iloc[[0, 3, 6, 9, 12]].round(2)) print(f"\n前月比の平均絶対変化 原系列:{data.diff().abs().mean():.2f}" f" adj:{adj.diff().abs().mean():.2f}")詳しく説明します。
ライブラリのインポート
numpy:数値計算を行うためのライブラリ。ここでは時間軸の生成や乱数生成に使用しています。pandas:日付インデックス付きのSeriesと、結果の表形式での整理に使用しています。statsmodels.tsa.seasonal.STL:STL分解を実行するクラスです。
データの生成
100 + 0.5*t:ベースレベル100に、月あたり0.5の緩やかな上昇トレンドを加えています。15*np.sin(2*np.pi*t/12):振幅15、周期12の季節成分です。トレンドの傾き(0.5/月)に比べて季節変動がはるかに大きく、原系列を見ただけではトレンドが読み取りにくい設定です。pd.date_range('2022', periods=48, freq='MS'):2022年1月から4年分の月初日付をインデックスとしています。
季節調整の実行
STL(data, period=12).fit():周期12でSTL分解を行い、トレンド・季節・残差の3成分に分解します。adj = data - r.seasonal:原系列から季節成分を引き算します。残るのは「トレンド+残差」であり、これが季節調整済み系列です。
結果の確認
df.iloc[[0, 3, 6, 9, 12]]:1月、4月、7月、10月、翌年1月の5行を抜き出し、四季ごとの変化を見やすくしています。data.diff().abs().mean():前月比変化の絶対値の平均です。季節調整によって月次の変動がどれだけ小さくなったかを示しています。
- 選択肢の解説
-
(A) 季節性を除去し、基調的なトレンドや変化を見やすくした系列 → ○
正解です。原系列から季節成分を差し引いたadjには、トレンドと残差が残ります。季節変動という「毎年繰り返す既知の変動」を取り除くことで、それ以外の変化が見えやすくなります。(B) トレンドを除去し、季節パターンだけを取り出した系列 → ×
これはr.seasonalそのものの説明です。adjはその逆で、季節成分を取り除いた側の系列です。(C) ノイズを除去し、滑らかにした系列 → ×
ノイズ(残差)を除去した系列はr.trend、あるいはdata - r.residで得られます。adjには残差がそのまま含まれているため、滑らかにはなっていません。(D) 季節成分を強調し、周期性を際立たせた系列 → ×
季節成分を引いているので、周期性はむしろ消えています。出力のadj列が緩やかに単調増加していることからも、周期性が残っていないことがわかります。 - 季節調整とは
-
季節調整とは、時系列データから季節変動を取り除く処理です。季節変動とは、暦や気候などの要因によって毎年決まった時期に繰り返し現れる変動を指します。
たとえば小売業の売上には、以下のような季節変動が典型的に含まれます。
- 年末年始やボーナス時期の売上増
- 夏物・冬物など季節商品の需要変動
- 月の営業日数の違いによる変動
こうした変動は「毎年起きるとわかっている」ものであり、それ自体は分析上の関心事ではないことが多いです。関心があるのは「季節要因を除いた上で、売上は伸びているのか落ちているのか」という基調的な動きです。季節調整は、この基調的な動きを取り出すための処理であり、次の関係で表されます。
$$
\text{季節調整済み系列} = \text{原系列} – \text{季節成分} = \text{トレンド} + \text{残差}
$$注意すべきは、季節調整済み系列には残差(不規則変動)が残っている点です。トレンドだけを見たい場合は
r.trendを使いますが、実務では「季節要因以外の変動はすべて見たい」ことが多いため、残差を含んだ季節調整済み系列が標準的に使われます。 - なぜ季節調整が必要か
-
季節調整済み系列が実務で重視される最大の理由は、時期の異なるデータを比較可能にすることです。
前月比の比較
原系列で「4月の売上は3月より増えた」と言っても、それが季節要因(毎年4月は増える)によるものか、実力による増加なのかは判別できません。季節調整済み系列であれば、季節要因を除いた前月比を見ることができます。今回の出力で前月比の平均絶対変化が5.27から1.48へ縮小したのは、季節要因による見かけの変動が除かれたためです。
景気判断での利用
GDP、鉱工業生産指数、失業率などの経済統計では、季節調整済み系列が公表されます。政府や中央銀行の景気判断は、季節調整済みの前期比をもとに行われるのが一般的です。ニュースで「季節調整済み」という表現を目にするのはこのためです。前年同月比との違い
季節要因を除く方法として、前年同月比(今年4月と去年4月を比べる)もよく使われます。前年同月比は簡便ですが、次のような限界があります。- 直近の変化がわかりにくい(1年前との比較なので、ここ数ヶ月の動きを捉えにくい)
- 前年に特殊要因があると、その影響が翌年の数値に現れる
季節調整済み系列の前月比であれば、直近の動きを季節要因抜きで捉えることができます。両者は補完的に使われます。 - 加法モデルと乗法モデル
-
季節調整には、季節成分をどう捉えるかによって2つの考え方があります。
加法モデル
季節変動の大きさが、水準に関係なく一定であると仮定します。今回のコードはこの形です。$$
\text{原系列} = \text{トレンド} + \text{季節成分} + \text{残差}
$$$$
\text{季節調整済み} = \text{原系列} – \text{季節成分}
$$乗法モデル
季節変動の大きさが、水準に比例して拡大縮小すると仮定します。売上が2倍になれば、季節変動の振幅も2倍になるようなデータに適しています。$$
\text{原系列} = \text{トレンド} \times \text{季節成分} \times \text{残差}
$$$$
\text{季節調整済み} = \text{原系列} \div \text{季節成分}
$$STLは加法モデルのみを直接扱いますが、乗法的な季節性を持つデータには、対数変換を施してからSTLを適用し、季節調整後に指数変換で戻す方法がよく使われます。対数を取ると掛け算が足し算に変わるため、乗法モデルを加法モデルとして処理できます。
どちらのモデルが適切かは、季節変動の振幅が時間とともに大きくなっているかどうかを可視化して判断します。
- 実務での注意点
-
データの末端は推定が不安定
STLに限らず、季節調整の推定はデータの両端(特に直近)で不安定になります。将来のデータが追加されると、直近の季節調整値が改定されることがあります。経済統計で過去の季節調整値が事後的に修正されるのはこのためです。周期の指定を誤らない
periodには実際の季節周期を正しく指定する必要があります。月次データなら12、四半期データなら4、日次データで週周期を扱うなら7です。誤った周期を指定すると、季節成分が正しく推定されず、調整後の系列に周期性が残ります。祝日・うるう年などのカレンダー効果
月ごとの営業日数の違いや、祝日の位置、うるう年などは、単純な周期性では捉えきれない変動を生みます。本格的な季節調整(政府統計で使われるX-13ARIMA-SEATSなど)では、これらのカレンダー効果を回帰で補正してから季節成分を推定します。構造変化への対応
季節パターンが途中で変わるデータ(たとえば新商品の投入で需要の季節性が変わった場合)では、全期間で一定の季節パターンを仮定すると精度が落ちます。STLは季節成分の緩やかな変化を許容していますが、急激な変化には対応しきれません。その場合は期間を分けて調整することを検討します。季節調整値は「推定値」である
季節成分は観測できるものではなく、モデルによって推定されたものです。手法やパラメータを変えれば季節調整値も変わります。季節調整済み系列を扱う際は、どの手法で調整したのかを明記し、原系列も併せて確認する習慣が重要です。

