Mímisbrunnr知恵の泉

← 時系列分析 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:ETSモデルと状態空間表現(SSOE の状態空間) | 数理:確率過程(マルコフ連鎖・ポアソン過程)(統計)・関連:ARMA・ARIMAモデル

要点(BLUF)

1. 状態空間モデルの一般形

中心アイデアは「観測は、見えない状態にノイズが乗ったもの」。これを2本の式で表します。

yt=Ztαt+εt,εtN(0,Ht)(観測方程式)αt=Ttαt1+Rtηt,ηtN(0,Qt)(状態方程式)\begin{aligned} y_t &= Z_t\,\alpha_t + \varepsilon_t, & \varepsilon_t &\sim N(0, H_t) &&\text{(観測方程式)}\\ \alpha_t &= T_t\,\alpha_{t-1} + R_t\,\eta_t, & \eta_t &\sim N(0, Q_t) &&\text{(状態方程式)} \end{aligned}

各記号の役割は次の通りです(αt\alpha_tmm 次元の状態ベクトル、yty_tpp 次元の観測)。

記号名前役割
αt\alpha_t状態ベクトル直接は見えない「真の」量(水準・傾き・季節など)
ZtZ_t観測(デザイン)行列状態を観測へ写す。どの状態成分が観測に現れるか
HtH_t観測ノイズ共分散測定の不確実性(観測方程式の εt\varepsilon_t の分散)
TtT_t遷移行列状態の時間発展の規則(前の状態→今の状態)
RtR_t状態ノイズ選択行列どの状態成分にショック ηt\eta_t が入るか
QtQ_t状態ノイズ共分散状態自体の揺らぎ(状態方程式の ηt\eta_t の分散)

εt\varepsilon_tηt\eta_t は互いに独立な正規ノイズ。添字 tt は行列が時変でもよいことを示しますが、本章のモデルは時不変Z,T,R,Q,HZ,T,R,Q,H が定数)です。

ローカルレベルモデル:最小の状態空間

一番簡単な例は、状態がスカラーの水準 μt\mu_t だけのローカルレベルモデルです。Z=1, T=1, R=1Z=1,\ T=1,\ R=1 とおくと、

yt=μt+εt,εtN(0,σε2)(=H)μt=μt1+ηt,ηtN(0,ση2)(=Q)\begin{aligned} y_t &= \mu_t + \varepsilon_t, & \varepsilon_t &\sim N(0, \sigma_\varepsilon^2)\quad(=H)\\ \mu_t &= \mu_{t-1} + \eta_t, & \eta_t &\sim N(0, \sigma_\eta^2)\quad(=Q) \end{aligned}

水準 μt\mu_tランダムウォークランダムウォークと単位根)で漂い、観測 yty_t はそれに測定ノイズが乗ったもの。Q/HQ/H(状態ノイズ÷観測ノイズ=信号対雑音比)が大きいほど水準は素早く動き、小さいほど滑らかになります(次ノート ローカルレベルとローカルトレンドモデル で深掘り)。

2. なぜ「統一フレーム」なのか

状態空間の威力は、多くのモデルが行列の中身を変えるだけでこの形に書けることです。

つまり状態空間は「個別モデルの上位言語」。一度この形に翻訳すれば、推定(カルマンフィルタ)・予測・平滑化・欠測処理が全部同じアルゴリズムで回ります(第4章の残りで順に扱います)。

flowchart LR
    eta["状態ノイズ η_t ~ N(0,Q)"] --> A["状態 α_t = T α_{t-1} + R η_t"]
    A --> Anext["次時点の状態 α_{t+1} へ"]
    A --> Y["観測 y_t = Z α_t + ε_t"]
    eps["観測ノイズ ε_t ~ N(0,H)"] --> Y

SSOE(単一誤差源)との違い

ETSモデルと状態空間表現 の ETS も状態空間でしたが、誤差項が εt\varepsilon_t ただ1つで、それが観測にも状態更新にも同じく入りました(single source of error, SSOE)。本章の状態空間は観測ノイズ εt\varepsilon_t と状態ノイズ ηt\eta_t が別物(複数誤差源)。

どちらも「状態空間で予測の不確実性を出す」点は共通ですが、定式化が別系統です。

コード①:隠れ状態と観測を生成して「見える/見えない」を可視化

真の隠れ水準 μt\mu_t(ランダムウォーク)と、それに観測ノイズを乗せた yty_t を生成します。私たちが手にできるのは灰色の yty_t だけで、赤の真の水準 μt\mu_t は本来見えません。この「隠れた構造を観測から復元する」のが次ノートの課題だ、と視覚的に掴むのが狙いです。

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib  # 日本語ラベル用

# 真の構造:隠れた水準 alpha がランダムウォーク、観測はそれにノイズが乗る
# alpha_t = alpha_{t-1} + eta_t,  eta_t ~ N(0, Q)   (状態方程式:Q=状態ノイズ分散)
# y_t     = alpha_t       + eps_t,  eps_t ~ N(0, H)   (観測方程式:H=観測ノイズ分散)
np.random.seed(0)
n = 120
Q_true, H_true = 0.25, 4.0          # 状態ノイズ < 観測ノイズ(水準はゆっくり動く)
alpha = np.zeros(n); alpha[0] = 10.0
for t in range(1, n):
    alpha[t] = alpha[t-1] + np.random.normal(0, np.sqrt(Q_true))
y = alpha + np.random.normal(0, np.sqrt(H_true), n)

print(f"状態ノイズ分散 Q = {Q_true},  観測ノイズ分散 H = {H_true}")
print(f"信号対雑音比 Q/H = {Q_true/H_true:.3f}(小さいほど水準は滑らか)")
print(f"隠れ水準 alpha の範囲 = [{alpha.min():.2f}, {alpha.max():.2f}]")
print(f"観測 y の標準偏差     = {y.std():.2f}(水準の動き+観測ノイズ)")

fig, ax = plt.subplots(figsize=(9, 4.5))
ax.plot(y, color="0.6", lw=1, marker="o", ms=3, label="観測 y_t(これだけ見える)")
ax.plot(alpha, color="C3", lw=2, label="隠れ水準 alpha_t(真の状態・本来は見えない)")
ax.set_xlabel("時点 t"); ax.set_ylabel("値"); ax.legend()
ax.set_title("ローカルレベルモデル:観測の裏に隠れた水準")
plt.tight_layout(); plt.show()

出力:

状態ノイズ分散 Q = 0.25,  観測ノイズ分散 H = 4.0
信号対雑音比 Q/H = 0.062(小さいほど水準は滑らか)
隠れ水準 alpha の範囲 = [8.11, 17.50]
観測 y の標準偏差     = 3.05(水準の動き+観測ノイズ)

出力の意味:状態ノイズ Q=0.25Q=0.25 に対し観測ノイズ H=4.0H=4.0 と、観測の方がずっとノイジー(信号対雑音比 Q/H=0.062Q/H=0.062)。だから図の灰色の観測 yty_t はギザギザに散らばり、赤の真の水準 μt\mu_t8.118.1117.5017.50滑らかに漂います。観測 yty_t の標準偏差 3.053.05 には「水準が動いた分」と「観測ノイズ」の両方が混ざっています。この赤線(隠れ状態)を、灰色の点(観測)だけから推定したい——それが カルマンフィルタ の仕事です。カルマンフィルタは観測のギザギザを適度に均し、真の滑らかな水準を追いかけます。

3. 数式の直観

⚠️ よくある誤解

関連ノート