自己回帰分布遅延 (ARDL) モデル

ARDL モデル

自己回帰分布遅延 (ARDL) モデルは、説明変数の遅延を追加することで自己回帰モデルを拡張したものです。ARDL モデルは技術的には AR-X モデルに分類されますが、重要な違いは、ARDL モデルが外生変数に重点を置き、内生変数と外生変数の両方から正しい遅延構造を選択する点です。ARDL モデルは、ベクトル自己回帰 (VAR) モデルとも密接に関連しており、単一の ARDL は実質的に VAR の1行に相当します。主な違いは、ARDL が外生変数が外生的であると仮定する点です。つまり、外生変数の予測子として内生変数を含める必要はないとされています。

ARDL モデルの完全な仕様は次のようになります。

\[Y_t = \underset{\text{定数と傾向}}{\underbrace{\delta_0 + \delta_1 t + \ldots + \delta_k t^k}} + \underset{\text{季節要因}}{\underbrace{\sum_{i=0}^{s-1} \gamma_i S_i}} + \underset{\text{自己回帰}}{\underbrace{\sum_{p=1}^P \phi_p Y_{t-p}}} + \underset{\text{分布遅延}}{\underbrace{\sum_{k=1}^M \sum_{j=0}^{Q_k} \beta_{k,j} X_{k, t-j}}} + \underset{\text{固定項}}{\underbrace{Z_t \Gamma}} + \epsilon_t\]

モデル内の項は次の通りです:

  • \(\delta_i\): 定数項および決定論的時間遡及変数。trendを使用して設定します。

  • \(S_i\) は季節ダミーで、seasonal=Trueの場合に含まれます。

  • \(X_{k,t-j}\) は外生変数です。遅延をどのように指定するかを決定するために複数の形式が使用可能です。含まれる遅延の長さは必ずしも同じである必要はありません。causal=True の場合、遅延は1から開始します。それ以外の場合は遅延が0から始まり、\(Y_t\)\(X_t\) の同時的な関係がモデルに含まれます。

  • \(Z_t\) は分布遅延の仕様に含まれない他の固定項です。実際には、これらの回帰変数は \(Y_t\) と外生変数ベクトル \(X_t\) の長期関係に寄与しない場合に含まれることがあります。

  • \(\{\epsilon_t\}\) はホワイトノイズ過程であると仮定されています。

[ ]:
import numpy as np
import pandas as pd
import seaborn as sns

sns.set_style("darkgrid")
sns.mpl.rc("figure", figsize=(16, 6))
sns.mpl.rc("font", size=14)

データ

このノートブックでは、デンマークのマネー・デマンドデータを使用しています。このデータは、S. JohansenとK. Juselius(1990)によって初めて使用されました。主要な変数は次の通りです:

  • lrm: M2を用いて測定された実質マネーの対数

  • lry: 実質所得の対数

  • ibo: 債券の金利

  • ide: 銀行預金の金利

標準的なモデルでは、lrm を従属変数として、残りの3つを外生的な要因として使用します。

Johansen, S. and Juselius, K. (1990), Maximum Likelihood Estimation and Inference on Cointegration – with Applications to the Demand for Money, Oxford Bulletin of Economics and Statistics, 52, 2, 169–210.

まず、データをロードし、その内容を確認します。

[ ]:
from statsmodels.datasets.danish_data import load
from statsmodels.tsa.api import ARDL
from statsmodels.tsa.ardl import ardl_select_order

data = load().data
data = data[["lrm", "lry", "ibo", "ide"]]
data.tail()

平均を引いたデータをプロットして、すべての系列が同じスケールで表示されるようにしています。lrm 系列は非定常のように見え、lry も同様です。他の2つの系列については、定常性が明確ではありません。

[ ]:
_ = (data - data.mean()).plot()

モデル選択

ardl_select_order を使用して、モデルの次数を自動的に選択できます。ここでは、従属変数の最大 3 期遅れおよび各独立変数の最大3期遅れを考慮したすべてのモデルの中で最小の AIC を使用します。trend="c" は、モデルに定数項を含めるべきことを示しています。

[ ]:
sel_res = ardl_select_order(
    data.lrm, 3, data[["lry", "ibo", "ide"]], 3, ic="aic", trend="c"
)
print(f"The optimal order is: {sel_res.model.ardl_order}")

最適な順序は、内生変数のラグの数に続いて、各外生回帰変数が返されます。sel_resmodel属性には、ARDLのモデル仕様が含まれており、これを使ってfitを呼び出すことができます。ここでは、L#がラグの長さを示すサマリーを見ていきます(例えば、L0はラグなし、つまり\(X_{k,t}\)L2は2つのラグ、つまり\(X_{k,t-2}\))。

[ ]:
res = sel_res.model.fit()
res.summary()

グローバル検索

選択基準は、より小さなモデルを選択する BIC に切り替えることができます。ここでは、glob=Trueオプションを使用して、最大遅延(ここでは 3 )までの任意の遅延の部分集合を考慮するグローバル検索を実行しています。このオプションにより、モデル選択が非連続的な遅延指定を選択できるようになります。

[ ]:
sel_res = ardl_select_order(
    data.lrm, 3, data[["lry", "ibo", "ide"]], 3, ic="bic", trend="c", glob=True
)
sel_res.model.ardl_order

ardl_orderは各変数の最大遅延ラグを示しますが、ar_lagsdl_lagsは含まれる具体的な遅延ラグを示します。AR成分は、すべての 3 つの遅延ラグが含まれているため、通常のものです。一方、DL 成分は、iboが遅延ラグ 0 と 3 のみを選択し、ideが遅延ラグ2のみを選択するため、通常のものではありません。

[ ]:
sel_res.model.ar_lags
[ ]:
sel_res.model.dl_lags

BIC に基づいて最良の性能を示すモデルは、bicプロパティに格納されています。遅延 0 および 3 のiboは一貫して選ばれ、遅延 2 または 3 のide、遅延 0のlryも選ばれています。選ばれた AR 遅延はより多様ですが、最良の仕様ではすべていくつかの遅延を選択しています。

[ ]:
for i, val in enumerate(sel_res.bic.head(10)):
    print(f"{i+1}: {val}")

直接パラメータ化

ARDLモデルは、ARDLクラスを使用して直接指定できます。最初の引数は内生変数(\(Y_t\))です。2番目の引数はARラグです。これは定数にすることもでき、その場合、ラグ 1, 2, …, \(P\) が含まれます。または、含める特定のラグのインデックスのリスト(例:[1, 4])を指定できます。3 番目は外生変数で、4 番目は含めるラグのリストです。これには以下のいずれかを指定できます。

  • int:ラグ 0, 1, …, Q を含める

  • exogDataFrame の場合は列名を、exog がNumPy配列の場合は数値の列位置を含む辞書(例:{0:1, 1: 2, 2:3})を指定します。この場合、NumPy配列が使用されると、以下の仕様と一致します。

  • 列名(DataFrame)または整数(NumPy配列)を持つ辞書で、特定のラグを含むリスト(例:{"lry":[0,2], "ibo":[1,2]})を指定します。

以下の仕様は、ardl_select_order で選択されたモデルと一致します。

[ ]:
res = ARDL(
    data.lrm, 2, data[["lry", "ibo", "ide"]], {"lry": 1, "ibo": 2, "ide": 3}, trend="c"
).fit()
res.summary()

NumPyデータ

以下では、NumPy 配列を使用する際に ARDL モデルの指定方法がどのように異なるかを示します。主な違いは、辞書のキーが整数になり、xの使用する列を示す点です。このモデルは、以前に適合させたモデルと同一であり、すべてのキーと値が正確に一致します(例:対数尤度)。

[ ]:
y = np.asarray(data.lrm)
x = np.asarray(data[["lry", "ibo", "ide"]])
res = ARDL(y, 2, x, {0: 1, 1: 2, 2: 3}, trend="c").fit()
res.summary()

因果モデル

causal=True フラグを使用すると、DLコンポーネントからラグ 0 が排除され、モデルに含まれるすべての変数が \(Y_t\) のモデリング時に \(t-1\) の時点で既知となります。

[ ]:
res = ARDL(
    data.lrm,
    2,
    data[["lry", "ibo", "ide"]],
    {"lry": 1, "ibo": 2, "ide": 3},
    trend="c",
    causal=True,
).fit()
res.summary()

制約なし誤差修正モデル(UECM)

制約なし誤差修正モデル(UECM)は、時間系列の長期的な成分に焦点を当てるために、ARDLモデルを再パラメータ化します。再パラメータ化されたモデルは以下のようになります。

\[\Delta Y_t = \underset{\text{定数項とトレンド}}{\underbrace{\delta_0 + \delta_1 t + \ldots + \delta_k t^k}} + \underset{\text{季節性}}{\underbrace{\sum_{i=0}^{s-1} \gamma_i S_i}} + \underset{\text{長期成分}}{\underbrace{\lambda_0 Y_{t-1} + \sum_{b=1}^M \lambda_i X_{b,t-1}}} + \underset{\text{自己回帰}}{\underbrace{\sum_{p=1}^P \phi_p \Delta Y_{t-p}}} + \underset{\text{分布ラグ}}{\underbrace{\sum_{k=1}^M \sum_{j=0}^{Q_k} \beta_{k,j} \Delta X_{k, t-j}}} + \underset{\text{固定項}}{\underbrace{Z_t \Gamma}} + \epsilon_t\]

ほとんどの成分は同じです。主な違いは以下の通りです:

  • レベルはラグ 1 にのみ入る

  • 他のすべての\(Y_t\)\(X_{k,t}\)のラグは差分を取る

その構造により、UECMモデルは不規則なラグ指定をサポートしません。そのため、ラグ指定は整数でなければなりません。ARラグの長さは整数またはNoneである必要があり、DLラグの指定は整数または整数の辞書で指定できます。その他のオプション(例えばtrendseasonalcausal)は同じです。

以下ではモデルを選択し、クラスメソッドfrom_ardlを使用してUECMを構築します。D.で接頭辞が付けられたパラメータ推定値は差分を示します。

[ ]:
from statsmodels.tsa.api import UECM

sel_res = ardl_select_order(
    data.lrm, 3, data[["lry", "ibo", "ide"]], 3, ic="aic", trend="c"
)

ecm = UECM.from_ardl(sel_res.model)
ecm_res = ecm.fit()
ecm_res.summary()

共和分関係

長期的な関係に焦点を当てているため、UECMモデルの適合結果には長期的な関係に焦点を当てた多数のプロパティが含まれています。これらはすべて「ci_」で始まり、共和分関係を示しています。ci_summary には、共和分関係の正規化された推定値と、それに関連する推定値が含まれています。

[ ]:
ecm_res.ci_summary()

ci_resids には、\(\Delta Y_t\) の変化を引き起こす誤差である長期的な残差が含まれています。

[ ]:
_ = ecm_res.ci_resids.plot(title="Cointegrating Error")

季節ダミー

ここでは、統計的に有意であると思われる季節要因を追加します。

[ ]:
ecm = UECM(data.lrm, 2, data[["lry", "ibo", "ide"]], 2, seasonal=True)
seasonal_ecm_res = ecm.fit()
seasonal_ecm_res.summary()

すべての決定論的項目は、ci_ プレフィックスの項目に含まれています。ここでは、要約の中で正規化された季節効果が示されています。

[ ]:
seasonal_ecm_res.ci_summary()

残差は見た目がややランダムな感じです。

[ ]:
_ = seasonal_ecm_res.ci_resids.plot(title="Cointegrating Error with Seasonality")

消費と成長の関係

ここでは、Greeneの『計量経済学の分析』からの例を取り上げ、消費と成長の長期的な関係に焦点を当てます。まず、原データをダウンロードすることから始めます。

Greene, W. H. (2000). Econometric analysis 4th edition. International edition, New Jersey: Prentice Hall, 201-215.

[ ]:
greene = pd.read_fwf("http://www.stern.nyu.edu/~wgreene/Text/Edition7/TableF5-2.txt")
greene.head()

次に、インデックスをpandasのDatetimeIndexに変換し、季節変動の項目を簡単に使用できるようにします。

[ ]:
index = pd.to_datetime(
    greene.Year.astype("int").astype("str")
    + "Q"
    + greene.qtr.astype("int").astype("str")
)
greene.index = index
greene.index.freq = greene.index.inferred_freq
greene.head()

私たちは g を実質 GDP の対数、c を実質消費の対数として定義しました。

[ ]:
greene["c"] = np.log(greene.realcons)
greene["g"] = np.log(greene.realgdp)

ラグ長の選択

選択されたモデルは、消費の 5 ラグと成長の 2 ラグ( 0 および 1 )を含んでいます。ここでは季節変動項も含めていますが、これらは有意ではありません。

[ ]:
sel_res = ardl_select_order(
    greene.c, 8, greene[["g"]], 8, trend="c", seasonal=True, ic="aic"
)
ardl = sel_res.model
ardl.ardl_order
[ ]:
res = ardl.fit(use_t=True)
res.summary()

from_ardl は、対応する UECM 仕様を取得するための簡単な方法です。ここでは、季節項を除いて再度選択を実行します。

[ ]:
sel_res = ardl_select_order(greene.c, 8, greene[["g"]], 8, trend="c", ic="aic")

uecm = UECM.from_ardl(sel_res.model)
uecm_res = uecm.fit()
uecm_res.summary()

消費が 1% 増加するごとに、GDP が 1.05% 増加する必要があることがわかります。言い換えれば、貯蓄率は約 5% と推定されます。

[ ]:
uecm_res.ci_summary()
[ ]:
_ = uecm_res.ci_resids.plot(title="Cointegrating Error")

UECMモデルの直接指定

UECMは、モデルの遅延次数を直接指定するために使用できます。

[ ]:
uecm = UECM(greene.c, 2, greene[["g"]], 1, trend="c")
uecm_res = uecm.fit()
uecm_res.summary()

遅延構造の変化は、推定された長期的な関係にはほとんど違いをもたらしません。

[ ]:
uecm_res.ci_summary()

範囲検定

UECMResults は、Pesaran, Shin, and Smith (2001) の範囲検定を公開します。この検定は、どの変数が I(1) であるかを識別せずに、変数のセット間にレベル関係があるかどうかをテストするためのものです。この検定は、2つのセットの臨界値と p 値を提供します。もし検定統計量が下限の臨界値を下回る場合、\(X\) 変数の順序や統合の状態にかかわらず、レベル関係は存在しないと思われます。上限の臨界値を上回る場合、\(X\) 変数の統合の順序にかかわらず、レベル関係が存在するように見えます。論文では、モデルまたは検定における決定的回帰変数の異なる組み合わせを含む5つのケースが扱われています。

\[\Delta Y_{t}=\delta_{0} + \delta_{1}t + Z_{t-1}\beta + \sum_{j=0}^{P}\Delta X_{t-j}\Gamma + \epsilon_{t}\]

ここで、\(Z_{t-1}\) には \(Y_{t-1}\)\(X_{t-1}\) が含まれます。

これらのケースは、モデルに含まれる決定的項目と、検定の一部としてテストされる項目を決定します。

  1. 決定的項目なし

  2. 定数項はモデルと検定の両方に含まれる

  3. 定数項はモデルに含まれるが、検定には含まれない

  4. 定数項と傾向項はモデルに含まれ、検定には傾向項のみが含まれる

  5. 定数項と傾向項はモデルに含まれ、検定にはどちらも含まれない

ここでは、デンマークの貨幣需要データセットに対して検定を実行します。ここでは、検定統計量が下限および上限の95%の臨界値の両方を上回っているのが確認できます。

Pesaran, M. H., Shin, Y., & Smith, R. J. (2001). Bounds testing approaches to the analysis of level relationships. Journal of applied econometrics, 16(3), 289-326.

[ ]:
ecm = UECM(data.lrm, 3, data[["lry", "ibo", "ide"]], 3, trend="c")
ecm_fit = ecm.fit()
bounds_test = ecm_fit.bounds_test(case=4)
bounds_test
[ ]:
bounds_test.crit_vals

ケース3もまた、レベル関係がないという帰無仮説を棄却します。

[ ]:
ecm = UECM(data.lrm, 3, data[["lry", "ibo", "ide"]], 3, trend="c")
ecm_fit = ecm.fit()
bounds_test = ecm_fit.bounds_test(case=3)
bounds_test

最終更新日: 2025年01月28日