PythonでReal Business Cycle Model その1
Sympyを用いた対数線形近似ならびにCanonical Formの構築

0. マクロ経済モデル系の記事をこれから書いていきます
おはこんばんにちは。ブログをリニューアルしたことに伴い、記事の整理が行いやすくなり、また開発したパッケージのサポートページへの連携などもできると考えたため、専門であるマクロ経済モデル系の記事を書いていきたいと思います。本記事を含むシリーズ第一弾では、分析の土台となる動学的一般均衡モデルのClass
をPython
で開発します。Real Business Cycleモデルを例に開発状況を記事にまとめました。初学者の方にも配慮した内容となるよう気を使っていますが、高難易度になっている部分はご容赦ください。
1. Real Business Cycle(RBC) モデル
RBCモデルは新古典派系動学的一般均衡モデル
さて、まずRBCモデルについての説明から行う必要がありますね。RBCモデルとは、マクロ経済学の中でも景気循環分析(Business Cycle Analysis)で用いられる新古典派系動学的一般均衡モデルで、景気変動の源泉を実物要因、特に財の生産技術に対する確率的なショックに求めている点が特徴です。日本語訳は実物景気循環モデルで、その名からわかるように価格は伸縮的で貨幣中立が成り立っており、名目変数が景気循環に影響しないモデルとなっています。
Kydland and Prescott(1982)がその嚆矢
RBCモデルは以下の論文で公開されました。
Kydland, F. and E. Prescott (1982), “Time to Build and Aggregate Fluctuations,” Econometrica 50, 1345-1371.
それまでの動学的一般均衡モデルとしては、ラムゼイモデルが有名でした。RBCモデルはこのラムゼイモデルで外生として扱われていた労働供給を内生化し、また生産関数に対する技術的なショックを導入しています。のちにKydlandとPrescottはこの業績からノーベル経済学賞を受賞しています。
現在ではNew Keynesian モデルが主流だが、議論の発射台として重用されている
少なくとも実務の世界ではRBCモデルを使用している機関は存在しないと思います。RBCが仮定している価格の伸縮性が現実的な仮定ではないからです。現在は価格の硬直性を導入したNew Keynesianモデルが広く使用されています1。では、RBCモデルは有用ではないのかというと、そういうわけではありません。New KeynesianモデルはRBCモデルに比べて、モデルが複雑になるため、モデルを拡張した際にその拡張が経済的にどのような意味を持っているかを解釈するのが大変です。そのため、モデル拡張の初期においてはプレーンなRBCモデルを用いて研究を行い、その特徴を調べ、その後実際のデータにフィッテイングする際にNew Keynesianモデルが使用されるケースがあります。よって、現在においてもRBCモデルは議論の発射台として有用です。
モデル概観
ここで、簡単にモデルを概観しておきましょう。経済主体として、無期限間2生きる代表的家計3と企業が存在します。家計は企業に労働と資本4を供給し、企業はそれらを用いて財を生産します。家計は企業から受け取る賃金と資本のレンタル料を、消費と貯蓄に振り分け、財の消費から効用を得ます。この経済には、資本と国債の2つの資産が存在し、家計はこれらを購入することで貯蓄を行うことができます。 ここまでの議論から、経済には以下4つの市場が存在します。
- 財市場
- 労働市場
- 資本市場
これらの市場は完全競争市場であると仮定します。家計は生涯効用の最大化を、企業は利潤最大化を達成するよう最適な行動を行うと仮定します。つまり、以下のような最適化問題に議論を帰着させることができます。
家計の最適化問題
家計の効用関数をCRRA型効用関数に特定化します。家計の効用最大化のための最適消費計画問題は以下のように定式化されます。
\[ \max_{c_t,~l_t,~k_t}\sum_{t=0}^{\infty}\beta^{t}[\frac{c_t^{1-\theta}}{1-\theta}-\Psi\frac{l_t^{1+\varphi}}{1+\varphi}] \\ \] \[ s.t.~~c_t + k_t = w_tl_t + r_tk_{t-1} + (1-\delta)k_{t-1} - \tau_t \\ \]
ここで、\(c_t,k_t,l_t,w_t,r_t^k, \tau_t\)はそれぞれ消費、資本、労働量、賃金、資本のレンタル料を表しています。また、\(\beta,\theta,\Psi,\varphi,\delta\)は構造パラメータで主観的割引率、消費の異時点間の代替弾力性の逆数、不効用のスケールパラメータ、労働供給の弾力性の逆数、資本減耗率を表しています。この問題は制約付き最適化問題ですので、ラグランジアンを用いることで一階の条件を導出することができます。一階の条件は以下になります。
\[ c_t^{-\theta} = \beta E_t[(1+r_{t+1}-\delta)c_{t+1}^{-\theta}] \tag{1} \\ \] \[ l_t^{\varphi} = c_t^{-\theta}w_t \tag{2} \\ \] (1)式は消費のオイラー方程式、(2)式は労働の最適化条件と呼ばれます。オイラー方程式は消費から得る効用の割引現在価値が異時点で無差別であることを保証する条件です。労働の最適化条件は家計の労働供給が負効用とその対価である賃金×効用が無差別となる点まで行われることを表します。これらに加え、以下の横断性条件を加えることで家計は消費計画問題を最適化します。
\[ \lim_{t\rightarrow\infty} \beta^{t}\lambda_tk_t=0 \\ \] 横断性条件が示していることは、無限大の将来において資本と国債の割引現在価値が0となることです。つまり、現時点においては遠い将来に資産を保有するような消費計画は行わないということです。そもそも資産形成は最終的に消費、ひいては効用の最大化のために行っているわけですので、保有するだけでは効用を得ることができない資産を保有し続けるということは最適化行動と矛盾します。
企業の最適化問題
企業は以下のコブ=ダグラス型生産関数により、財の生産を行います。
\[ y_t = z_tk_{t-1}^{\alpha}l_t^{1-\alpha} \tag{4} \] ここで、\(y_t,z_t\)はそれぞれ生産量、技術水準を表しており、\(\alpha\)は資本装備率です。\(z_t\)は一階の自己回帰過程に従い、外生変数によって確率的に変動します。
\[ z_t = \rho_zz_{t-1} + \epsilon_t^z \tag{5} \] ここで、\(\rho_z\)は自己回帰係数、\(\epsilon_t^z\)は外生(確率)ショックです。先述した通り、RBCはこの財の生産技術水準に対する確率的ショックを景気変動の源泉としています。 資本\(k_{t-1}\)の時点が\(t-1\)となっていることからもわかるように、\(t\)期の投資活動の結果実現した資本が実際に稼働するまでには1期必要と仮定します。企業は完全競争の労働市場、資本市場から生産要素を収集し、同じく完全競争の財市場で財を販売します。よって、企業の利潤最大化問題は以下のようになります。
\[ \max_{k_t,~l_t}~ y_t - r_t^kk_{t-1} - w_tl_t \\ \] \[ s.t.~~y_t = z_tk_{t-1}^{\alpha}l_t^{1-\alpha} \] 利潤最大化の一階の条件は以下の通り。
\[ r_t = z_t\alpha(\frac{l_t}{k_{t-1}})^{1-\alpha} \tag{6} \\ \] \[ w_t = z_t(1-\alpha)(\frac{k_{t-1}}{l_t})^{\alpha} \tag{7} \] 生産要素市場は完全競争市場であるので、限界生産性=要素価格が成立する点を需要することになります。また、利潤はゼロです。よって、以下のように完全分配が成り立ちます。
\[ y_t = r_tk_{t-1} + w_tl_t \]
財市場の均衡条件
\(t\)期に生産された財は消費されるか、投資されるかのいずれかです。よって、財市場の均衡条件は以下のようになります。
\[ y_t = c_t + i_t \tag{10} \] なお、ここで\(i_t\)は投資であり、資本遷移式を表す以下の方程式に(10)を代入することで資本の動学が定まります。
\[ k_t = (1-\delta)k_{t-1} - z_tk_t^\alpha l_t^{(1-\alpha)} + c_t \tag{11} \] モデルの概観は以上になります。このモデルをどうやって解くのかやパラメータをどう推定するのかは次回、次々回のPostで説明します。
2. RBC Modelを分析できるプログラミング言語
Matlab
(Octave
) + Dynare
がデファクトスタンダード
動学的確率的一般均衡モデルにはDynare
と呼ばれる専用のプログラミング言語が存在します。このDynare
は単体で動くのではなく、Matlab
(Octave
)上で動かす必要がありますが、インパルス応答関数等の数値シミュレーションに加え、状態空間モデルの推定や構造パラメータのMCMC推定など動学的一般均衡モデルの基本的な分析を行うには十分な機能を備えています。ただ、先進的な研究を行う場合、特に推定方法の高度化、Matlab
単体を使用して分析が行われることが多いと感じます。Dynare
は手を動かして既存のモデルを動かしたい人に向けたソフトウェアであるといってもよいかもしれません(もちろんDynare
でも論文は書けますし、実際に存在もします)。
Python
でRBC Modelを分析する意義
Matlab
+ Dynare
がデファクトスタンダードであるのに、Python
を使用する理由は以下3点です。
- モデル分析以外の部分の利便性が高い
- このブログでも紹介したように
Python
にはpandasdmx
やpandas_datareader
等APIを使用してマクロ経済データを直接取得できる便利な関数群があります。これまでの分析では、実際にWEBサイトへ行き、手でcsvファイルをダウンロードして、それをExcelで加工し分析用のデータを作成していました。
- このブログでも紹介したように
- より高度な分析のための外部ライブラリの統合が容易
- 動学的一般均衡モデルの実装に際して、状態空間モデルであったりMCMCに関する実装を一から行う気は毛頭ありません。
statsmodels
やPymc3
といった外部ライブラリを利用することを考えています。また、粒子フィルタなどさ らに発展的な技術についてもPythonの方が実装済みコードが存在しており、かつClass
という概念を用いればこれ らの特性が容易に継承可能である点からもPython
での実装がBestであると考えました。
- 動学的一般均衡モデルの実装に際して、状態空間モデルであったりMCMCに関する実装を一から行う気は毛頭ありません。
- みんな
Python
を使っているから- せっかくであれば、自分だけじゃなくいろんな人に使ってほしいので、利用者が多い
Python
を選びました。
- せっかくであれば、自分だけじゃなくいろんな人に使ってほしいので、利用者が多い
3. Python
での実装
このPostでやり遂げたいこと
各モデル方程式をSympy
で定義し、それを対数線形化、その後Canonical form
と呼ばれる行列形式に整理するまでをクラス化したいと思います。
Canonical form
とは
おそらく聞き慣れない単語であろうCanonical form
について説明しておきます。先ほど導出したRBCモデルの均衡条件式は非線形差分方程式システムとなっています。動学的確率的一般均衡モデルでは、これを定常値周りで対数線形近似して線形化するのが一般的です。線形化されたシステムを行列形式で表現すると以下のようになります。
\[
Bs_{t+1} = Cs_{t} + \Psi\epsilon_t
\]
ここで\(s_t\)は内生変数で\(\epsilon_t\)は外生変数、\(B,C,\Psi\)は係数行列です。このシステムをCanonical form
と呼びます。今回は均衡条件式をこちらの形式へ整形することがゴールです。
利用するモジュール群のインポート
以下を使用します。
import numpy as np
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
import sympy as sym
Sympyでの方程式の定義
先ほど導出した方程式をSympy
で定義します。
まず内生変数を宣言します。
sym.init_printing()
var = sym.var('l, c, k, l, z, r, LEAD_c, LEAD_k, LEAD_l, LEAD_r, LEAD_z, LEAD_R')
endog = sym.var('l, c, k, z')
LEADs = sym.var('LEAD_l, LEAD_c, LEAD_k, LEAD_z')
次にパラメータを宣言します。
params = sym.var('beta, theta, varphi, alpha, delta, phi, Psi')
方程式を定義します。
# Eliminate Price
LEAD_R = (LEAD_z*alpha*(LEAD_k/LEAD_l)**(alpha-1))
w = (1-alpha)*z*(k/l)**alpha
# Optimal Conditions & state transition
labor = l**varphi-w/(Psi*c**(theta))
euler = c**(-theta) -(LEAD_c**(-theta))*beta*(1+LEAD_R-delta)
capital = LEAD_k - (1-delta)*k - z*(k**alpha)*(l**(1-alpha)) + c
tech = LEAD_z - phi*z
optcon = sym.Matrix([labor, euler, capital, tech])
Sympy
の自動数式処理機能を用いた自動対数線形近似の実施
optcon
に保存されているのは非線形差分方程式システムとなっています。次に対数線形近似を行い、線形システムへ変換を行います。対数線形近似はそれ自体に特別な意味があるとは思えませんので、Sympy
のjacobian
を用いてヤコビ行列を計算し、自動処理します。
# Differentiation
jopt = optcon.jacobian(endog).subs([(LEAD,endog[i]) for i, LEAD in enumerate(LEADs)])
jopt_LEAD = optcon.jacobian(LEADs).subs([(LEAD,endog[i]) for i, LEAD in enumerate(LEADs)])
ここでは、内生変数\(s_t\)と\(s_{t+1}\)を分けて処理しています。
対数線形近似後の係数を得るためには、ヤコビ行列のそれぞれの要素に、対応する変数の定常均衡値を掛け合わせる必要があります。ヤコビ行列の各要素は\(\partial f(x_t)/\partial x_t\)ですが、対数線形近似=関数\(f(x_t)\)を定常値からの乖離\(x_t/x\)で(定常値周りで)一次近似することですので、定常値\(x\)を掛け合わせることで係数\(\partial f(x_t)/(\partial x_t/x)\)を求めることができます。
よって、定常値の計算が必要です。数値的に求めることもできますが、定常均衡はそれを求めること自体もモデルの特性を知る上で重要ですので、解析的に解いた数式をSympy expression
として定義します。
# Steady State Equation needed to be calculated by hand
kls = (((1/beta)+delta-1)/alpha)**(1/(alpha-1))
wstar = (1-alpha)*(kls)**alpha
clstar = kls**alpha - delta*kls
lstar = ((wstar/Psi)*(clstar**(-theta)))**(1/(varphi+theta))
kstar = kls*lstar
cstar = clstar*lstar
zstar = 1
Ystar = (kstar**alpha)*(lstar**(1-alpha))
ss_eq = sym.Matrix([lstar, cstar, kstar, zstar])
次に、この定常均衡方程式システムを構造パラメータを引数とするPython
関数へ変換します。MCMC
で構造パラメータの推定を行う際などは頻繁にパラメータを更新しますので、関数化しておくことは便利です。また、構造パラメータと定常値を引数として対数線形システムの係数行列を評価する関数もPython
関数へ変換しておきます。
# Translating Sympy expressions into Python functions for steady state and coefficient matrix
fss = sym.lambdify([params],ss_eq)
fcoef = sym.lambdify([params,endog],jopt)
fcoef_LEAD = sym.lambdify([params,endog],jopt_LEAD)
これで解析的には準備が整いました。では、構造パラメータに数値を代入して、係数を計算してみます。
# Evaluate steady state and each derivative in terms of % deviations from ss
vparams = np.array([0.99, 1.5 ,2 , 0.3, 0.025, 0.8, 1])
ss = fss(vparams)
B = np.matrix(fcoef_LEAD(vparams,ss)*ss, dtype='float')
C = np.matrix(fcoef(vparams,ss)*ss, dtype='float')
A = np.dot(np.linalg.inv(np.matrix(C)),B)
print(A)
## [[-1.02747592e-02 3.21263317e-01 -5.48161413e-03 -4.68593779e-01]
## [ 3.19823603e-02 -1.00000000e+00 -1.49198793e-03 4.01094076e-02]
## [ 4.95211793e-02 -1.54839039e+00 -9.81949430e-01 3.57889915e+00]
## [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -1.25000000e+00]]
4. まとめ
今回はReal Business Cycleモデルをpython
で解くために前段階となるモデルのparseとCanonical form
への整形を行いました。次回は実際にこのモデルの合理的期待均衡解を解き、インパルスレスポンス応答を数値的に計算するところまで進みます。お楽しみに!!
このほか、金融市場の情報の非対称性や労働市場での失業の発生などさまざまな不完全性を取り込んでいる場合が多いです。↩︎
代表的家計とはその名の通り無数存在する家計を代表する家計です。一世帯ずつモデル化していると埒が明かないので、このような単純化を行っているわけです。「平均的な消費者」とも言えるかもしれません。↩︎
無限期間生きる家計は現実的でない仮定ですが、単一の家計が無限期間生きるということではなく、ある家計が自身のみではなく、代々脈々と無数に続く子孫までの消費計画を自身の問題として捉えて行動していると考える方が適切だと個人的に思っています。利他性100%の世代重複モデルとも解釈できます。↩︎
家計が資本を供給することに違和感を持たれる人がいらっしゃるかもしれません。資本とは生産に必要な設備などですが、ここではその元となる原資である資金を社債等を通じて企業へ供給をしていると考えてもらった方がいいと思います。つまり、このモデルでは資本財価格は消費財価格と同じであると仮定していることになります。↩︎