上級マクロ経済学

第13回 非定常過程と予測

Author

荻巣嘉高

1 確定トレンド

確定トレンド

次のようなy_tを考えよう。 y_t = \phi_0 + \delta t + u_t ただし、E(u_t)=0かつiidであるとしよう。

期待値を取ると、 E(y_t) = \phi_0 + \delta t

  • 時間が経つにつれてE(y_t)が増加。
  • このようなy_t確定トレンドを持つと言われる。

確定トレンドによるバイアス

真のデータの関係が y_t = \phi_0 + \phi_1 y_{t-1} + \delta t + u_t であるとする。

それにも関わらず、次の回帰式で分析を行うとする。 y_t = \phi_0 + \phi_1 y_{t-1} + u_t

  • \phi_1がバイアスを持つ。
  • トレンドを除去して分析する必要がある。

2 確率トレンド

ランダムウォーク

次のようなy_tを考えよう。

y_t = y_{t-1} + u_t ただし、u_t

  • E(u_t)=0
  • Var(u_t)=E(u_t^2)=\sigma^2

のホワイトノイズだとする。

  • この過程に従うy_tランダムウォークであるといわれる。

ランダムウォークの分解

初期値をY_0としよう。

\begin{aligned} y_1 &= y_{0} + u_1 \\ y_2 &= y_{0} + u_2 + u_{1} \\ y_3 &= y_{0} + u_3 + u_{2} + u_{1} \\ &\hspace{12pt} \vdots \\ y_t &= y_0 + \sum_{j = 1}^{t} u_j \end{aligned}

  • ランダムウォークは過去のランダムショックの積み重ね。
  • 過去のショックが減衰せずに残る。

ランダムウォークの性質

E(y_t) = y_0

\begin{aligned} Var(y_t) &= Var(y_0) + \sum_{j=1}^{t} Var(u_j) \\ &= y_0 + \sum_{j=1}^{t} \sigma^2 \\ &= y_0 + t \sigma^2 \end{aligned}

  • 時間を通じて分散が限りなく大きくなる。

ARモデルと確率トレンド

次のようになy_tを考えよう。 y_t = \phi_0 + y_{t-1} + u_t

  • このようなy_t確率トレンドを持つとか、単位根過程であるとか言われる。
    • ARモデルにおいて\phi_1=1であるケースだと考えられる。
  • ランダムウォークと同様の性質があるので、分散が時間を通じて大きくなり続ける。
  • このようなy_tは非定常であると言われる。

3 ディトレンド

ディトレンド

  • トレンドがあると、回帰係数にバイアスが生じる。
  • トレンドを除去することをディトレンドと呼ぶ。
  • たいてい、階差をとるとトレンドが消える。
    • 階差とは、1期前の値との差のこと。 一階の階差: \Delta y_t \equiv y_t - y_{t-1}
  • これをもとに、y_tが一階階差をとると定常過程になる場合、1次の和分過程に従うといい、I(1)と表現する。
  • y_tが階差を取らなくても定常過程になるならば、I(0)と表現する。

確定トレンドの階差

\begin{aligned} \Delta y_t &= \phi_0 + \phi_1 y_{t-1} + \delta t + u_t \\ &\hspace{12pt} - \left( \phi_0 + \phi_1 y_{t-2} + \delta (t-1) + u_{t-1} \right) \\ &= \delta + \phi_1 (y_{t-1} - y_{t-2} ) + u_t - u_{t-1} \\ &= \delta + \phi_1 \Delta y_{t-1} + u_t - u_{t-1} \end{aligned}

  • u_t - u_{t-1} \equiv \epsilon_tとすれば、通常のAR(1)。
  • トレンド成分は消失。

確率トレンドの階差

\begin{aligned} y_t &= \phi_0 + y_{t-1} + u_t \\ y_t - y_{t-1} &= \phi_0 + u_t \\ \Delta y_t &= \phi_0 + u_t \end{aligned}

  • \Delta y_tは定常になる。
    • E(\Delta y_t) = \phi_0 + E(u_t) = \phi_0
    • Var(\Delta y_t) = Var(u_t) = \sigma^2
    • Cov(u_i, u_{i-j}) = 0

単位根検定

AR(1)モデル y_t = \phi_0 + \phi_1 y_{t-1} + u_t を階差変換した次のAR(1)モデルを考えよう。 \Delta y_t = \phi_0 + \rho y_{t-1} + u_t だたし、\rho= \phi_0 - 1

このとき、H_0: ~ \rho = 0を検定するテストを、ディッキー・フラー検定と呼ぶ。

  • \rhoの推定値\hat{\rho}が通常は正規分布ではなく、ディッキー・フラー分布と呼ばれる特殊な分布に従うことが知られている。
  • また、AR(1)ではなく、ラグ項がより多いAR(p)モデルで単位根を検定するものを拡張ディッキー・フラー検定と呼ぶ
  • 本講義では取り扱わないが、計量分析をちゃんとをやる人は教科書などで勉強することを強くお勧めする。

4 マクロ経済の予測

将来を予測したい

  • マクロ経済を予測するとき、ARモデルを用いて予測することはfirst stepといえる。
    • 構造が単純
    • 解釈しやすい
    • それなりの予測力

モデル

y_tが定常であるとする。 y_t = \phi_0 + \phi_1 y_{t-1} + u_t でモデルがうまく特定できたとしよう。 ただし、u_t\sim \mathcal{N}(0,1)かつiidとする。

  • t期までのy_tは既に観測されているとしよう。
  • そのもとで、y_{t+1}を求めるとしよう。

パラメータが既知のケース

\phi_0\phi_1\sigma^2が既知だとしよう。 y_{t+1} = \phi_0 + \phi_1 y_t + u_{t+1} これを、\left\{ y_{j} \right\}_{j=0}^{t}が既知であるという条件付き期待値を取れば、 E (y_{t+1}\mid \left\{ y_{j} \right\}_{j=0}^{t}) = \phi_0 + \phi_1 y_t ただし、E(u_{t+1}\mid \left\{ y_{j} \right\}_{j=0}^{t})=0であることを用いている。

  • これが次期の期待されるy_{t+1}ということになる。 \hat{y}_{t+1} = \phi_0 + \phi_1 y_t としよう。

予測誤差

実現値y_{t+1}と予測値\hat{y}_{t+1}の差は、 y_{t+1} - \hat{y}_{t+1} = u_{t+1} なので、予測誤差の分散は \sigma_y^2 = E\left( (y_{t+1} - \hat{y}_{t+1})^2 \right) = E(u_{t+1}^2) = \sigma^2 となる。

区間予測

\hat{y}_{t+1}はどれくらいばらつきをもっているかを、区間として表示する。

\frac{y_{t+1} - \hat{y}_{t+1}}{\sigma_y} \sim \mathcal{N}(0,1) になるはず。 これを用いれば、区間予測ができる。

  • 例えば、90%信頼区間を求めるならば、

\hat{y}_{t+1} + 1.64 \sigma_y \le y_{t+1} \le \hat{y}_{t+1} - 1.64 \sigma_y つまり、 \hat{y}_{t+1} \pm 1.64 \sigma_y 区間が90%の信頼度の予測区間になるということ。

h期先の予測

  • t+2期以上先についても順に繰り返し代入をすれば解析的に予測値と予測区間を算出できる。
  • 天下り的に書けば、h期先の\hat{y}_{t+h}とその予測誤差は、 \hat{y}_{t+h} = \phi_0 \sum_{j = 0}^{h-1} \phi_1^j + \phi_1^h y_{t} \sigma_y = \sigma^2 \sum_{j = 0}^{h-1} \phi_1^{2j}

h期先の90%予測区間は \hat{y}_{t+h} \pm 1.64 \sigma_y

AR(p)の予測

\hat{y}_{t+1} = \phi_0 + \phi_1 y_{t} + \phi_{2} y_{t-1} + \cdots + \phi_{j} y_{t-j+1} \sigma_y^2 = \sigma^2 ゆえに、90%予測区間は \hat{y}_{t+1} \pm 1.64 \sigma_y^2

AR(p)の予測の困難

2点の問題:

  • 実際にはパラメータ\phi_0\phi_1\sigma^2が未知。
    • AR(1)で推計した\hat{\phi}_0\hat{\phi}_1\hat{\sigma}^2を用いる。
  • AR(p)モデルに拡張した場合、繰り返し代入をしていって\sigma_yを求めるのはかなり煩雑。
    • 逐次予測を用いることが多い。

逐次予測: 将来のy_{t+h}を予測\hat{y}_{t+h}に逐次置き換えて計算を行なっていく。

逐次予測の点推定値

  • y_{t-j+1}からy_{t}までを初期値とする。

\hat{y}_{t+1} = \phi_0 + \phi_1 y_t + \phi_2 y_{t-1} + \cdots + \phi_{j} y_{t-j+1}

\hat{y}_{t+2} = \phi_0 + \phi_1 \hat{y}_{t+1} + \phi_2 y_{t} + \cdots + \phi_{j} y_{t-j+2}

\hat{y}_{t+3} = \phi_0 + \phi_1 \hat{y}_{t+2} + \phi_2 \hat{y}_{t+1} + \cdots + \phi_{j} y_{t-j+3}

\vdots

\hat{y}_{t+h} = \phi_0 + \phi_1 \hat{y}_{t+h-1} + \phi_2 \hat{y}_{t+h-2} + \cdots + \phi_{j} y_{t-j+h}

と繰り返して求める。

  • 予測区間はどう構築する?

逐次予測の予測区間

N回だけのシミュレーションを行う。

  • i回目のシミュレーションを(i)で表す。

\mathcal{N}(0,\sigma^2)からランダムにh個の生成。

  • 順に、u_{t+1}^{(i)}, \cdots u_{t+h}^{(i)}としよう。

\hat{y}_{t+1}^{(i)} = \phi_0 + \phi_1 y_t + \cdots + \phi_{j} y_{t-j+1} + u_{t+1}^{(i)}

\hat{y}_{t+2}^{(i)} = \phi_0 + \phi_1 \hat{y}_{t+1}^{(i)} + \cdots + \phi_{j} y_{t-j+2} + u_{t+2}^{(i)}

\hat{y}_{t+3}^{(i)} = \phi_0 + \phi_1 \hat{y}_{t+2}^{(i)} + \cdots + \phi_{j} y_{t-j+3} + u_{t+3}^{(i)}

\vdots

\hat{y}_{t+h}^{(i)} = \phi_0 + \phi_1 \hat{y}_{t+h-1}^{(i)} + \cdots + \phi_{j} y_{t-j+h} + u_{t+h}^{(i)}

区間の構築

h期後の90%予測区間は、 (y_{t+h}^{(1)}, y_{t+h}^{(2)}, \cdots, y_{t+h}^{(N)}) を小さい順に並び替えて、5%のところから95%のところを取り出して構築。

  • 例えばN=100なら、小さい順に並び替えて5個目の値と95個目の値を取ってくる。

シミュレーションによる区間予測の実装

  • コロナショックは予測外。 大きなショックが検出できる。
Code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.tsa.api as ts

df = pd.read_excel("gdp_gap.xlsx", sheet_name="Data") # データの読み込み

df["time"] = pd.to_datetime(df["年"].astype(str) + "-" + df["月"].astype(str)) # 時間列の作成

df0 = df[df["time"] < "2016-01-01"] # 2015年中までのデータが既知、2016年以降のデータが未知だとして予測する。

res = ts.AutoReg(df0["GDP_gap"], lags=3).fit(cov_type="HAC", cov_kwds={"maxlags":4}) # AR(3)で、4期ラグのHAC標準誤差を用いる

## 推計パラメータ
phi0 = res.params[0]
phi1 = res.params[1]
phi2 = res.params[2]
phi3 = res.params[3]

sigmahat = (np.mean(res.resid**2))**(1/2) # 誤差の推定値


## GDPギャップデータをappendで扱えるリストに変換
y = df0["GDP_gap"].values.tolist()

N = 100 # シミュレーションの数
h = 34 # maxの予測先
np.random.seed(1234) # シードの固定

# 点推定量
yhat_point = y.copy() # 点推定の結果を入れるリストとして、yのコピーを作成
for j in range(h):
    yhat = phi0 + phi1*y[-1] + phi2*y[-2] + phi3*y[-3] # yhatを計算
    yhat_point.append(yhat) # 一番後ろに足す。


## 区間予測のためのシミュレーションを行う
sim_res = [] # シミュレーション結果を入れるリストを作成
for i in range(N):
    yhat_int = y.copy() # 結果を入れるリストとして、yのコピーを作成
    u = np.random.normal(size=h,loc=0, scale=sigmahat) # 平均ゼロ、標準偏差sigmahatの正規分布からランダムに100個の変数をピック
    for j in range(h):
        yhat = phi0 + phi1*y[-1] + phi2*y[-2] + phi3*y[-3] + u[j] # 確率変動を含むyhatを計算する
        yhat_int.append(yhat)

    sim_res.append(yhat_int) #シミュレーションした系列を保存


## シミュレーション結果から区間を構築する。
## sim_res[i][j]成分がi回目のトライアルのj期目の値。

sim_res = np.array(sim_res) # j列を取り出しやすいように、ndarrayにして処理

lb = [] # 5%水準の値を保存するリスト
ub = [] # 95%水準の値を保存するリスト

ind_b = int(np.round(N*0.05,0)) # 5%水準のインデックス
ind_u = int(np.round(N*0.95,0)) # 95%水準のインデックス

for j in range(len(y)+h):
    vals = sim_res[:,j] # j期目の値のシミュレーション結果を取り出す
    lb.append(np.sort(vals)[ind_b]) # j期の下限をリストに加える
    ub.append(np.sort(vals)[ind_u]) # j期の上限をリストに加える

## プロットする
plt.rcParams["font.size"]=10
plt.plot(df["time"],np.zeros(len(df)), color="gray", alpha=0.3)
plt.plot(df["time"], df["GDP_gap"], label="data", alpha=0.5) # データのプロット
plt.plot(df["time"].iloc[len(y)-1:len(y)+h], yhat_point[len(y)-1:len(y)+h],ls="--", label="estimate", color="black") # 予測値のプロット
plt.fill_between(df["time"].iloc[len(y)-1:len(y)+h], y1=ub[len(y)-1:len(y)+h], y2=lb[len(y)-1:len(y)+h], color="blue", alpha=0.2, label="90 confidence interval")
plt.legend()
plt.show()

2025-09-13T13:10:49.740248 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/

まとめ

  • トレンドを持ちそうなデータは差分を取ると変換できることがほとんど。
    • ARモデルで分析を行うならば定常性には注意が必要。
    • 単位根検定は少し特殊かつ統計のちゃんとした知識のもと学ぶ必要がある。
  • 予測は逐次でシミュレーションを行うのが最も実用性が高い。
    • コードを自分でレプリケートすると、何が行われているのか理解が進むかも。
    • 予測区間を外れるような変動は、モデルが想定している状態から経済が大きく外れたということを示している。
    • これらのショックには当然(経済学的な)意味があるはず。そこの解釈をするのが経済学でやるべきこと。