再帰的最小二乗法

再帰的最小二乗法は、通常の最小二乗法の拡張ウィンドウ版です。再帰的に計算された回帰係数に加えて、再帰的に計算された残差は、パラメータの不安定性を調査するための統計量の構築に使用されます。

RecursiveLSクラスは、再帰的残差の計算を可能にし、CUSUMおよびCUSUMの二乗統計量を計算します。これらの統計量を、パラメータの安定性という帰無仮説からの統計的に有意な偏差を示す参照線と一緒にプロットすることで、パラメータの安定性を視覚的に簡単に確認することができます。

最後に、RecursiveLSモデルは、パラメータベクトルに対して線形制約を課すことができ、式インターフェースを使用して構築することができます。

[1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import statsmodels.api as sm
from pandas_datareader.data import DataReader

np.set_printoptions(suppress=True)

例1: 銅

まず、銅データセットのパラメータの安定性を検討します (説明は下記)。

[2]:
print(sm.datasets.copper.DESCRLONG)

dta = sm.datasets.copper.load_pandas().data
dta.index = pd.date_range("1951-01-01", "1975-01-01", freq="AS")
endog = dta["WORLDCONSUMPTION"]

# To the regressors in the dataset, we add a column of ones for an intercept
exog = sm.add_constant(
    dta[["COPPERPRICE", "INCOMEINDEX", "ALUMPRICE", "INVENTORYINDEX"]]
)
このデータは、1951年から1975年までの世界の銅市場を記述したものです。Gillの例
では、2段階推定の結果変数として、25年間の世界の銅消費量が使用されています。
説明変数には、以下が含まれます:
- 世界の銅消費量(単位: 1000メートルトン)
- 調整済みの実質ドルベースの銅価格
- 代替品であるアルミニウムの価格
- 1970年を基準とした1人当たり実質所得の指数
- 製造業の在庫変動の年間測定値
- 時間のトレンド

次の警告が表示されます:
C:\Users\user\AppData\Local\Temp\ipykernel_15324\2153377698.py:4: FutureWarning: 'AS' is deprecated and will be removed in a future version, please use 'YS' instead.
  dta.index = pd.date_range("1951-01-01", "1975-01-01", freq="AS")
**警告の意味**: `AS`(年単位の開始日を指定する頻度)が廃止予定で、将来のバージョンで削除されるため、
代わりに`YS`(同等の機能を持つ頻度)を使用するよう推奨されています。

まず、モデルを構築してフィットさせ、要約を出力します。RLSモデルは回帰パラメータを再帰的に計算するため、データポイントの数と同じ数の推定値がありますが、要約テーブルにはサンプル全体で推定された回帰パラメータのみが表示されます。再帰の初期化による小さな影響を除けば、これらの推定値は OLS 推定値と同等です。

[3]:
mod = sm.RecursiveLS(endog, exog)
res = mod.fit()

print(res.summary())
                           Statespace Model Results
==============================================================================
Dep. Variable:       WORLDCONSUMPTION   No. Observations:                   25
Model:                    RecursiveLS   Log Likelihood                -154.720
Date:                Thu, 28 Nov 2024   R-squared:                       0.965
Time:                        23:11:12   AIC                            319.441
Sample:                    01-01-1951   BIC                            325.535
                         - 01-01-1975   HQIC                           321.131
Covariance Type:            nonrobust   Scale                       117717.127
==================================================================================
                     coef    std err          z      P>|z|      [0.025      0.975]
----------------------------------------------------------------------------------
const          -6562.3719   2378.939     -2.759      0.006   -1.12e+04   -1899.737
COPPERPRICE      -13.8132     15.041     -0.918      0.358     -43.292      15.666
INCOMEINDEX      1.21e+04    763.401     15.853      0.000    1.06e+04    1.36e+04
ALUMPRICE         70.4146     32.678      2.155      0.031       6.367     134.462
INVENTORYINDEX   311.7330   2130.084      0.146      0.884   -3863.155    4486.621
===================================================================================
Ljung-Box (L1) (Q):                   2.17   Jarque-Bera (JB):                 1.70
Prob(Q):                              0.14   Prob(JB):                         0.43
Heteroskedasticity (H):               3.38   Skew:                            -0.67
Prob(H) (two-sided):                  0.13   Kurtosis:                         2.53
===================================================================================

Warnings:
[1] Parameters and covariance matrix estimates are RLS estimates conditional on the entire sample.

再帰係数は recursive_coefficients 属性で使用できます。または、 plot_recursive_coefficient メソッドを使用してプロットを生成することもできます。

[4]:
print(res.recursive_coefficients.filtered[0])
res.plot_recursive_coefficient(range(mod.k_exog), alpha=None, figsize=(10, 6))
[     2.88890087      4.94795049   1558.41803044   1958.43326658
 -51474.9578655   -4168.94974192  -2252.61351128   -446.55908507
  -5288.39794736  -6942.31935786  -7846.0890355   -6643.15121393
  -6274.11015558  -7272.01696292  -6319.02648554  -5822.23929148
  -6256.30902754  -6737.4044603   -6477.42841448  -5995.90746904
  -6450.80677813  -6022.92166487  -5258.35152753  -5320.89136363
  -6562.37193573]
[4]:
../../../_images/examples_notebooks_generated_recursive_ls_7_1.png
../../../_images/examples_notebooks_generated_recursive_ls_7_2.png

CUSUM統計量はcusum属性で利用できますが、通常はplot_cusumメソッドを使用してパラメータの安定性を視覚的に確認する方が便利です。下のプロットでは、CUSUM統計量が5%の有意水準帯を超えていないため、5%の水準で安定したパラメータの帰無仮説を棄却できません。

[5]:
print(res.cusum)
fig = res.plot_cusum()
[ 0.69971508  0.65841244  1.24629674  2.05476032  2.39888918  3.1786198
  2.67244672  2.01783215  2.46131747  2.05268638  0.95054336 -1.04505546
 -2.55465286 -2.29908152 -1.45289492 -1.95353993 -1.3504662   0.15789829
  0.6328653  -1.48184586]
../../../_images/examples_notebooks_generated_recursive_ls_9_1.png

もう一つ関連する統計量は、二乗和のCUSUMです。これはcusum_squares属性で確認できますが、視覚的に確認する方が便利であり、そのためにplot_cusum_squaresメソッドが用意されています。以下のプロットでは、二乗和のCUSUM統計量は5%の有意水準バンドの外に出ていないため、5%の有意水準で安定したパラメータの帰無仮説を棄却できません。

[6]:
res.plot_cusum_squares()
[6]:
../../../_images/examples_notebooks_generated_recursive_ls_11_0.png
../../../_images/examples_notebooks_generated_recursive_ls_11_1.png

例2: 貨幣数量説

貨幣数量説は、「貨幣供給量の変化率の変化が与えられた場合、それは…物価上昇率の変化と等しい変化を引き起こす」と示唆しています(Lucas, 1980)。Lucasに従い、私たちは貨幣成長の両面指数加重移動平均とCPIインフレ率との関係を調べます。Lucasはこれらの変数間の関係が安定していることを発見しましたが、最近ではこの関係が不安定であるようです。例えば、SargentとSurico(2010)を参照してください。

[7]:
start = "1959-12-01"
end = "2015-01-01"
m2 = DataReader("M2SL", "fred", start=start, end=end)
cpi = DataReader("CPIAUCSL", "fred", start=start, end=end)
[8]:
def ewma(series, beta, n_window):
    nobs = len(series)
    scalar = (1 - beta) / (1 + beta)
    ma = []
    k = np.arange(n_window, 0, -1)
    weights = np.r_[beta ** k, 1, beta ** k[::-1]]
    for t in range(n_window, nobs - n_window):
        window = series.iloc[t - n_window : t + n_window + 1].values
        ma.append(scalar * np.sum(weights * window))
    return pd.Series(ma, name=series.name, index=series.iloc[n_window:-n_window].index)


m2_ewma = ewma(np.log(m2["M2SL"].resample("QS").mean()).diff().iloc[1:], 0.95, 10 * 4)
cpi_ewma = ewma(
    np.log(cpi["CPIAUCSL"].resample("QS").mean()).diff().iloc[1:], 0.95, 10 * 4
)

ルーカスの\(\beta = 0.95\)フィルター(両側に10年のウィンドウを使用)を使って移動平均を構築した後、以下に各シリーズをプロットします。サンプルの一部ではそれらが一緒に動いているように見えますが、1990年以降はそれらが分岐しているように見えます。

[9]:
fig, ax = plt.subplots(figsize=(13, 3))

ax.plot(m2_ewma, label="M2 Growth (EWMA)")
ax.plot(cpi_ewma, label="CPI Inflation (EWMA)")
ax.legend()
[9]:
<matplotlib.legend.Legend at 0x246e0a5ff10>
../../../_images/examples_notebooks_generated_recursive_ls_16_1.png
[10]:
endog = cpi_ewma
exog = sm.add_constant(m2_ewma)
exog.columns = ["const", "M2"]

mod = sm.RecursiveLS(endog, exog)
res = mod.fit()

print(res.summary())
                           Statespace Model Results
==============================================================================
Dep. Variable:               CPIAUCSL   No. Observations:                  141
Model:                    RecursiveLS   Log Likelihood                 692.328
Date:                Thu, 28 Nov 2024   R-squared:                       0.812
Time:                        23:11:20   AIC                          -1380.656
Sample:                    01-01-1970   BIC                          -1374.758
                         - 01-01-2005   HQIC                         -1378.259
Covariance Type:            nonrobust   Scale                            0.000
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const         -0.0034      0.001     -6.002      0.000      -0.004      -0.002
M2             0.9133      0.037     24.482      0.000       0.840       0.986
===================================================================================
Ljung-Box (L1) (Q):                 138.24   Jarque-Bera (JB):                18.28
Prob(Q):                              0.00   Prob(JB):                         0.00
Heteroskedasticity (H):               5.36   Skew:                            -0.81
Prob(H) (two-sided):                  0.00   Kurtosis:                         2.28
===================================================================================

Warnings:
[1] Parameters and covariance matrix estimates are RLS estimates conditional on the entire sample.
[11]:
res.plot_recursive_coefficient(1, alpha=None)
[11]:
../../../_images/examples_notebooks_generated_recursive_ls_18_0.png
../../../_images/examples_notebooks_generated_recursive_ls_18_1.png

CUSUM プロットは 5% レベルで大幅な偏差を示しており、パラメータ安定性の帰無仮説が棄却されたことを示しています。

[12]:
res.plot_cusum()
[12]:
../../../_images/examples_notebooks_generated_recursive_ls_20_0.png
../../../_images/examples_notebooks_generated_recursive_ls_20_1.png

同様に、二乗の CUSUM は 5% レベルで大幅な偏差を示しており、これもパラメータ安定性の帰無仮説が棄却されることを示唆しています。

[13]:
res.plot_cusum_squares()
[13]:
../../../_images/examples_notebooks_generated_recursive_ls_22_0.png
../../../_images/examples_notebooks_generated_recursive_ls_22_1.png

例3: 線形制約と式

線形制約

モデルを構築する際に、constraintsパラメータを使用することで、線形制約を実装することは難しくありません。

[14]:
endog = dta["WORLDCONSUMPTION"]
exog = sm.add_constant(
    dta[["COPPERPRICE", "INCOMEINDEX", "ALUMPRICE", "INVENTORYINDEX"]]
)

mod = sm.RecursiveLS(endog, exog, constraints="COPPERPRICE = ALUMPRICE")
res = mod.fit()
print(res.summary())
                           Statespace Model Results
==============================================================================
Dep. Variable:       WORLDCONSUMPTION   No. Observations:                   25
Model:                    RecursiveLS   Log Likelihood                -134.231
Date:                Thu, 28 Nov 2024   R-squared:                       0.989
Time:                        23:11:23   AIC                            276.462
Sample:                    01-01-1951   BIC                            281.338
                         - 01-01-1975   HQIC                           277.814
Covariance Type:            nonrobust   Scale                       137155.014
==================================================================================
                     coef    std err          z      P>|z|      [0.025      0.975]
----------------------------------------------------------------------------------
const          -4839.4836   2412.410     -2.006      0.045   -9567.721    -111.246
COPPERPRICE        5.9797     12.704      0.471      0.638     -18.921      30.880
INCOMEINDEX     1.115e+04    666.308     16.738      0.000    9847.000    1.25e+04
ALUMPRICE          5.9797     12.704      0.471      0.638     -18.921      30.880
INVENTORYINDEX   241.3452   2298.951      0.105      0.916   -4264.515    4747.206
===================================================================================
Ljung-Box (L1) (Q):                   6.27   Jarque-Bera (JB):                 1.78
Prob(Q):                              0.01   Prob(JB):                         0.41
Heteroskedasticity (H):               1.75   Skew:                            -0.63
Prob(H) (two-sided):                  0.48   Kurtosis:                         2.32
===================================================================================

Warnings:
[1] Parameters and covariance matrix estimates are RLS estimates conditional on the entire sample.

同じモデルをクラスメソッドfrom_formulaを使ってフィットさせることができます。

[15]:
mod = sm.RecursiveLS.from_formula(
    "WORLDCONSUMPTION ~ COPPERPRICE + INCOMEINDEX + ALUMPRICE + INVENTORYINDEX",
    dta,
    constraints="COPPERPRICE = ALUMPRICE",
)
res = mod.fit()
print(res.summary())
                           Statespace Model Results
==============================================================================
Dep. Variable:       WORLDCONSUMPTION   No. Observations:                   25
Model:                    RecursiveLS   Log Likelihood                -134.231
Date:                Thu, 28 Nov 2024   R-squared:                       0.989
Time:                        23:11:23   AIC                            276.462
Sample:                    01-01-1951   BIC                            281.338
                         - 01-01-1975   HQIC                           277.814
Covariance Type:            nonrobust   Scale                       137155.014
==================================================================================
                     coef    std err          z      P>|z|      [0.025      0.975]
----------------------------------------------------------------------------------
Intercept      -4839.4836   2412.410     -2.006      0.045   -9567.721    -111.246
COPPERPRICE        5.9797     12.704      0.471      0.638     -18.921      30.880
INCOMEINDEX     1.115e+04    666.308     16.738      0.000    9847.000    1.25e+04
ALUMPRICE          5.9797     12.704      0.471      0.638     -18.921      30.880
INVENTORYINDEX   241.3452   2298.951      0.105      0.916   -4264.515    4747.206
===================================================================================
Ljung-Box (L1) (Q):                   6.27   Jarque-Bera (JB):                 1.78
Prob(Q):                              0.01   Prob(JB):                         0.41
Heteroskedasticity (H):               1.75   Skew:                            -0.63
Prob(H) (two-sided):                  0.48   Kurtosis:                         2.32
===================================================================================

Warnings:
[1] Parameters and covariance matrix estimates are RLS estimates conditional on the entire sample.
C:\Users\user\projects\statsmodels-main\statsmodels\tsa\base\tsa_model.py:465: ValueWarning: No frequency information was provided, so inferred frequency YS-JAN will be used.
  self._init_dates(dates, freq)

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