GDPと構成要素#
import japanize_matplotlib
import numpy as np
import pandas as pd
import py4macro
# 警告メッセージを非表示
import warnings
warnings.filterwarnings("ignore")
はじめに#
人の心の中を知ることはできない。友人,同僚,パートナー,親族もそうである。また何十年も連れ添った夫婦でさえも完全にお互いの心の中を分かっているとは言い難いだろう。しかし話し言葉やその内容,行動から心の中を推測することは可能である。実際,我々は日常そうしており,人間関係を豊かにする為には必須でる。経済も同じである。経済の動きの裏にある「真のメカニズム」は完全に把握されていない。アダム・スミスの時代に比べると,「熟練夫婦」に匹敵するほど知見は蓄積されたかも知れないが,今でも「真のメカニズム」が100%解明されたとは言い難い。経済学者にとってできることは,経済の「言動」であるデータを観察し「真のメカニズム」について想像を巡らすことである。人の言動に注意を払わずに人の心の中を想像するのは「妄想」となり,データを無視して経済を考えるのは「空想」となってしまう危険性がある。
人の心の中 \(\Longleftrightarrow\) 経済の真のメカニズム
人の言動 \(\Longleftrightarrow\) 経済データ
この章はマクロ・データの特徴を理解することを目的とする。統計量やプロットを駆使して異なるマクロ・データの特性を炙り出し,経済の「言動」に注目しようということである。特に,以下では国内総生産(GDP)とその構成要素に着目し議論を進める。
使うデータはpy4macro
に含まれる日本の四半期データである。1980年から1993年のデータと1994年から2021年までの2つのデータ・セットを組み合わせて作成した。データを読み込むには次のようにする。
py4macro.data('jpn-q')
ここでjpn
はJapan,q
はquerterlyを表している。変数の定義を表示するにはdescription=True
の引数を追加する。
py4macro.data('jpn-q', description=True)
| `gdp`: 国内総生産(GDP)
| `consumption`: 消費
| `investment`: 投資
| `government`: 政府支出
| `exports`: 輸出
| `imports`: 輸入
| `capital`: 資本ストック
| `employed`: 就業者数
| `unemployed`: 失業者数
| `unemployment_rate`: 失業率
| `hours`: 労働者一人当たり月平均労働時間
| `total_hours`: 月平均総労働時間(`employed`X`hours`)
| `inflation`: インフレ率
| `price`: 消費者物価指数
| `deflator`: GDPデフレーター
|
| * 四半期データ
|
| <出典>
| GDPとその構成要素
| * 1994年Q1~2021年Q4
| * 実額・四半期・実質季節調整系列(年換算)
| * 2015暦年(平成27年)連鎖価格
| * 単位:10億円
| * 国民経済計算(GDP統計)
| * 1980年Q1~1993年Q4
| * 実額・四半期・実質季節調整系列(年換算)
| * 平成27年基準支出側GDP系列簡易遡及(参考系列であり上のデータと接続可能)
| * 単位:10億円
| * 国民経済計算(GDP統計)
|
| 実質資本ストック
| * 1994年Q1~2019年Q4
| * 平成25年基準
| * 単位:10億円
| * 国民経済計算(GDP統計)
| * 1980年Q1~1993年Q4
| * 平成25年基準遡及系列
| * 単位:10億円
| * 国民経済計算(GDP統計)
|
| 就業者数,失業者数,失業率
| * 総務省「労働力調査」
| * 単位:万人,%
|
| 労働者一人当たり月平均労働時間
| * 厚生労働省「毎月勤労統計調査」
| * 30 人以上(一般・パート)、月間実労働時間(総実労働時間)
| * 2020年の平均を100に基準化
|
| インフレ率
| * 景気動向指数(速報,改訂値,月次,原数値の前年同月比)から四半期平均として計算
|
| 消費者物価指数
| * 2020年基準
| * 「中分類指数(全国)<時系列表>【月次】」の四半期平均として計算
| * 簡便的に移動平均を使い季節調整を施している
|
| GDPデフレーター
| * 1994年Q1~2019年Q4
| * 2015年(平成27年)基準
| * 季節調整系列
| * 1980年Q1~1993年Q4
| * 2015年(平成27年)基準遡及系列
| * 季節調整系列
このデータ・セットにはGDPとその構成要素以外も含まれているが,それらは次章で使うことになる。
まずデータを読み込んで最初の5行を表示してみよう。
df = py4macro.data('jpn-q')
df.head()
gdp | consumption | investment | government | exports | imports | capital | employed | unemployed | unemployment_rate | hours | total_hours | inflation | price | deflator | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1980-03-31 | 269747.5 | 153290.7 | 65029.2 | 73039.5 | 18383.8 | 24278.8 | 834219.7 | 5506.000000 | 107.666667 | 1.900000 | 124.7 | 686598.200000 | 5.766667 | 71.015699 | 91.2 |
1980-06-30 | 268521.8 | 153551.9 | 65316.6 | 72164.5 | 18631.4 | 25454.5 | 843000.2 | 5525.666667 | 110.000000 | 1.966667 | 124.8 | 689603.200000 | 8.166667 | 72.907806 | 93.4 |
1980-09-30 | 274183.1 | 155580.0 | 65765.9 | 72663.8 | 18449.3 | 23885.7 | 854753.4 | 5561.333333 | 116.000000 | 2.033333 | 124.0 | 689605.333333 | 8.200000 | 73.898630 | 94.4 |
1980-12-31 | 279601.8 | 156162.4 | 66017.5 | 74761.1 | 19705.4 | 23716.5 | 868241.2 | 5551.333333 | 123.333333 | 2.166667 | 123.9 | 687810.200000 | 8.100000 | 74.771830 | 95.4 |
1981-03-31 | 281995.7 | 156757.7 | 66259.0 | 76127.6 | 20289.5 | 24174.1 | 879629.9 | 5568.666667 | 124.333333 | 2.200000 | 123.7 | 688844.066667 | 6.833333 | 75.694271 | 95.6 |
列には変数が並んでいるのが確認できる。行はインデックスではなくラベルとなっており,年・四半期を示している。例えば,1980-3-31
は1980年第1四半期であり,その最終日がラベルとして使われている。.info()
を使って確認してみる。
df.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 168 entries, 1980-03-31 to 2021-12-31
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 gdp 168 non-null float64
1 consumption 168 non-null float64
2 investment 168 non-null float64
3 government 168 non-null float64
4 exports 168 non-null float64
5 imports 168 non-null float64
6 capital 168 non-null float64
7 employed 168 non-null float64
8 unemployed 168 non-null float64
9 unemployment_rate 168 non-null float64
10 hours 168 non-null float64
11 total_hours 168 non-null float64
12 inflation 168 non-null float64
13 price 168 non-null float64
14 deflator 168 non-null float64
dtypes: float64(15)
memory usage: 21.0 KB
表示の上から2行目にDatetimeIndex
とあるが,行ラベルのことを表しており,時系列データ用となっている。具体的な説明は割愛するが,時系列データが扱いやすくなりプロットする際にも便利である。
GDPとその変化#
まずGDPを図示しよう。
df['gdp'].plot(title='GDP')
pass
長期的には上昇トレンドであることが分かる。これが経済成長である。一方で,よく観察するとギザギザに動いていることも確認できる。景気変動である。小さい上下の動きもあれば,より大きな動きもある。例えば,2008年のリーマン・ショック,そして2020年のコロナ禍の影響でGDPは大きく下落している。
(問4)なぜ景気変動は起こるのか?
これがマクロ経済学のもう一つのBig Questionである。この章以降は問4を中心にマクロ経済を考察することになる。
上の図には2022年第1四半期以降のデータは含まれていない。参考に最新のデータを含む図を下にに表示する。
Show code cell source
from IPython.display import IFrame
IFrame(src='https://fred.stlouisfed.org/graph/graph-landing.php?g=BOLN&width=420&height=320',
width=450, height=330)
この図は米国セントルイス連邦準備銀行が管理するFederal Reserve Economic Data (FRED)と呼ばれるデータ・ベースからライブでダウンロードして表示している。
py4macro
を使った上の図もしくはFREDの図にあるGDPは水準を表しているため,GDPの成長率を直接読み取り異なる時期の成長率を比べることは難しい。しかし,それを可能にするのが対数化したGDPのプロットである。まず,なぜそうなのかを簡単に説明しよう。
変数x
の成長率\(g_x\)は次の式で定義される。
ここで\(g_x\)の値は,例えば0.02
(2%
)のような値となる。この式の両辺に対数を取り,近似を使うと次のように書き直すことができる。
x
の成長率である\(g_x\)は,x
の対数の差分ということになる。即ち,縦軸にx
の対数,横軸に時間をおけば,プロットの傾きはx
の成長率と等しいことになる。
では実際にプロットしよう。
df['gdp_log'] = np.log(df['gdp'])
df['gdp_log'].plot(title='GDP(対数)')
pass
プロットの傾きは四半期ごとのGDPの成長率であり,成長率が変化しているのがわかる。また,2008年のリーマン・ショックとコロナ禍により成長率が大きく下落していることが確認できる。景気循環により成長率が小刻みに,また時には大きく変化している。
次に,長期的な視点で図を眺めてみよう。1980年から1990年までの間に直線のトレンドを描くことができる。その傾きが平均成長率である。同様に,1990年から2020年までの直線トレンドを描くこともできるが,傾きが緩やかになっていることに気づくのではないだろうか。1991年頃のバブル崩壊の影響により,その後のGDPの伸びが鈍化していることがわかる。「失われた10年」,「失われた20年」と言われていたが,今では「失われた30年」と言われる所以である。
次に(99)を使い四半期成長率を計算してみよう。
df['gdp_growth_quarter'] = 100*df['gdp_log'].diff() # 1
# 2
ax_ = df['gdp_growth_quarter'].plot(title='GDP四半期成長率(%)')
ax_.grid() # 3
pass
コードの説明 🐍
.diff()
は差分を計算するメソッドであり,引数の数(デフォルトは1
)は何期前の値と差分を計算するかを指定する。Pandas
のメソッドplot
は図を表示し,同時に図の「軸(axis)」を返すが,それを変数ax_
に割り当てている。軸の変数
ax_
には様々なメソッドが用意されており,その1つがグリッド線を表示する.grid()
である。
新聞などで「前年同期比成長率」という表現をみたことがあると思うが,diff()
の引数を4
にすることにより,前年同期比の成長率を計算することができる。それを図示してみよう。
df['gdp_growth_annual'] = 100*df['gdp_log'].diff(4)
ax_ = df['gdp_growth_annual'].plot(title='GDP前年同期比成長率(%)')
ax_.grid()
pass
上の図と比べると縦軸の幅の違いに気づくだろう。最高値と最小値を計算してみよう。
df['gdp_growth_annual'].max(), df['gdp_growth_annual'].min()
(7.591566394121507, -10.61353111987522)
1980年代後半ののバブル景気には約7.6
%増加しているが,コロナ禍では約10
%以上下落している。
次の点を知っておくのも有用だろう。
次の式を使うと四半期成長率を年率換算することもできる。
\[ g_{\text{年率換算成長率}}=\left(1+g_{\text{四半期成長率}}\right)^4-1 \]\(g_{\text{四半期成長率}}\)が4期続くことを想定した成長率である。
年次データを使うとGDPの値は均されるので変化率は低めに出る。
GDPの構成要素#
次式は所得恒等式である。
GDP=消費+投資+政府支出+純貿易(輸出ー輸入)
GDPに対してそれぞれ構成要素は何%を占め,どのように推移したかを図示する為に,まず変数を計算する。
# 消費の割合
con_gdp_ratio = 100 * df['consumption'] / df['gdp']
# 投資の割合
inv_gdp_ratio = 100 * df['investment'] / df['gdp']
# 政府支出の割合
gov_gdp_ratio = 100 * df['government'] / df['gdp']
# 純輸出の割合
net_exp_gdp_ratio = 100 * ( df['exports']-df['imports'] ) / df['gdp']
それぞれの平均をfor
ループで計算し表示してみよう。
ratio_list = [con_gdp_ratio,inv_gdp_ratio,
gov_gdp_ratio,net_exp_gdp_ratio]
label_list = ['Consumption','Investment','Gov Exp','Net Exports']
for r, l in zip(ratio_list, label_list):
avr = r.mean()
print(l, f'\t{avr:.1f}')
Consumption 55.6
Investment 21.8
Gov Exp 25.3
Net Exports -1.1
消費はGDPの60
%近くあり,GDPの約1/4が政府支出となっている。消費とは対照的に,投資は約20
%であり消費の約3分の1である。(小数点第一位までしか表示していないため合計は100にならない。)
次に推移を確認する。同じようにfor
ループを使うと簡単に表示できる。
for r, l in zip(ratio_list,label_list):
r.plot(label=l, legend=True)
コードの説明
zip()
について説明する。zip()
はループによく使われる便利な関数である。以下の単純なfor
ループfor r in ratio_list: r.plot()
にはループ用の変数が
r
の1種類しかない。これでも図示することは可能である。しかし凡例を追加するためにはlabel_list
もfor
ループの中で同時に使う必要がある。そのような場合に便利な関数がzip()
である。引数にratio_list
とlabel_list
を入れると,同時に順番に要素にアクセスできる。それぞれの要素を割り当てる変数としてr
とl
を使っている。r
とl
の間に,
を入れることにより,それぞれ別のリストの要素を捉えることができる。この
for
ループは以下と等しい。con_gdp_ratio.plot(label='Consumption', legend=True) inv_gdp_ratio.plot(label='Investment', legend=True) gov_gdp_ratio.plot(label='Gov Exp', legend=True) net_exp_gdp_ratio.plot(label='Net Exports', legend=True)
もちろんこれでも良いが,コードを書く際は極力同じような行を繰り返すのではなくループを使ってまとめる方が良い。第一の理由は,簡単なエラーの可能性を軽減することができることだ。リピートして書く場合,1行をコピペしその後に1行ずつ修正をするパターンが多いが,最初の1行目が間違っている場合,全ての行を修正する必要が発生する。その際に修正し忘れることがある。第二の理由は,コードの修正も簡単になるためである。例えば,
linewidth=2
を設定したいとしよう。for
ループの場合は一箇所に加えるだけで済むことになる。
景気の動向によって上下することがわかる。例えば,リマン・ショック後には投資が大きく下落し少しずつしか上昇しない。一方,景気悪化に反応し政府支出の割合は上昇している。またバブル景気(1986年から1991年まで)ではその逆が起こっており,順位が逆転する程である。コロナ禍の影響もプロットにハッキリと現れている。
トレンドと変動#
説明#
上の分析から明らかなことは,マクロ変数は変動するということであり,正しくそれが景気循環を表している。ここでは景気循環について,もう一歩踏み込んで考えてみる。
マクロ変数はトレンドと変動(サイクル)に分解することができる。例えば,\(Y\)をGDPとすると次式のように2つの項で表すことができる。
\(Y_t^{\text{trend}}\)は長期的な傾向を表し,GDPであれば経済成長を捉えている。また,トレンドが右上がりでないものありえる。例えば,失業率の場合,自然失業率が一定であればトレンドはないということになる。一方,\(Y_t^{\text{cycle}}\)は短期的な景気循環を捉えている。内閣府は景気循環を「山」と「谷」の2つに分けて景気基準日付を発表している。トレンドを上回っている期間を「山」,下回っている期間を「谷」と考えて良いだろう。図示すると次のようになる。
Show code cell source
def trend_cycle():
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
# フォントのサイズ
font_largest=30
font_large=20
# GDPのプロット
xlow = 0
xhigh = 3*np.pi
x = np.arange(xlow, xhigh, 0.1)
def yfunc(x):
return np.cos(x+np.pi/2)+0.1*x
fig, ax = plt.subplots(figsize=(10,5))
ax.plot(x, yfunc(x), linewidth=7, label='GDP')
# トレンド線のプロット
xx = np.linspace(xlow-1., xhigh+1)
def trend_line(x):
return ( yfunc(3*np.pi)-yfunc(0) )/(3*np.pi) * (x-0)+yfunc(0)
ax.plot(xx, trend_line(xx), lw=4, color='orange', label='トレンド')
# 縦点線のプロット
ylow = -1.68
tani0 = mlines.Line2D([np.pi/2, np.pi/2], [ylow, yfunc(np.pi/2)], linestyle='--')
yama = mlines.Line2D([np.pi*3/2, np.pi*3/2], [ylow+0.4, yfunc(np.pi*3/2)], linestyle='--')
tani1 = mlines.Line2D([np.pi*5/2, np.pi*5/2], [ylow, yfunc(np.pi*5/2)], linestyle='--')
ax.add_line(tani0)
ax.add_line(yama)
ax.add_line(tani1)
# 矢印のプロット(拡張と後退)
for dx in [np.pi/2, -np.pi/2]:
ax.arrow(x=np.pi, y=-1.2, dx=dx, dy=0,
width=0.01, head_width=0.1,head_length=0.2,
length_includes_head=True,color='k')
for dx in [np.pi/2, -np.pi/2]:
ax.arrow(x=2*np.pi, y=-1.2, dx=dx, dy=0,
width=0.01, head_width=0.1,head_length=0.2,
length_includes_head=True,color='k')
# 矢印のプロット(全循環)
start_arrow_shift = 0.8
ax.arrow(x=np.pi*3/2-start_arrow_shift, y=-1.5,
dx=-(np.pi-start_arrow_shift), dy=0,
width=0.01, head_width=0.1,head_length=0.2,
length_includes_head=True,color='k')
ax.arrow(x=np.pi*3/2+start_arrow_shift, y=-1.5,
dx=np.pi-start_arrow_shift, dy=0,
width=0.01, head_width=0.1,head_length=0.2,
length_includes_head=True,color='k')
# 注釈の挿入
x0 = np.pi/2
x1 = np.pi*3/2
x2 = np.pi*5/2
xshift = 0.33
yshift = 0.2
ax.annotate('谷', xy=(x0-xshift, yfunc(x0)+yshift),size=font_largest)
ax.annotate('山', xy=(x1-xshift, yfunc(x1)+yshift), annotation_clip=False, size=font_largest)
ax.annotate('谷', xy=(x2-xshift, yfunc(x2)+yshift),size=font_largest)
# ax.annotate('好況', xy=(xlow-1.1,0.2), annotation_clip=False, size=font_large, color='green')
# ax.annotate('不況', xy=(xlow-1.1,-0.5), annotation_clip=False, size=font_large, color='red')
# ax.annotate('好況', xy=(xhigh+0.3,1.25), annotation_clip=False, size=font_large, color='green')
# ax.annotate('不況', xy=(xhigh+0.3,0.55), annotation_clip=False, size=font_large, color='red')
ax.annotate('拡張', xy=(np.pi-0.2,-1.05), size=font_large, color='green')
ax.annotate('後退', xy=(2*np.pi-0.5,-1.05), size=font_large, color='red')
ax.annotate('全循環', xy=(np.pi*3/2-0.65,-1.6), size=font_large)
# 横軸のラベル,凡例を追加,縦軸の表示範囲の設定
ax.set_xlabel('時間', size=font_large)
ax.legend(loc='upper left', fontsize=20)
ax.set_ylim(ymax=2.3)
# 縦軸・横軸のラベルと目盛の削除
ax.set_yticklabels([])
ax.set_xticklabels([])
ax.set_xticks([])
ax.set_yticks([])
# 枠を削除
for s in ['top', 'right', 'left','bottom']:
ax.spines[s].set_visible(False)
trend_cycle()
この図のトレンドは右上がりとなっているが,一定もしくは右下がりになる場合もありえる。この図から,拡張・後退はGDPの変化を捉えていることが分かる。また,このプロットはNumPy
のコサイン関数を使って描画しているので,「谷」と「山」が発生した時期を簡単に見分けることができる。しかし,上のGDPデータのプロットを見直すと,「谷」と「山」がいつだったかを決めるのは簡単な問題ではないと想像できるだろう。実際,内閣府は単にGDPのデータを眺めるだけではなく景気動向指数を含め様々なデータに基づき,「谷」と「山」の時期を確定している。
景気循環を考える上で重要な役割を果たすのがトレンドである。トレンドはどのように計算するのだろうか。実は,決まった計算方法があるわけではなく,いろいろな考え方がある。実際,内閣府と日本銀行は独自の方法でGDPトレンドを算出している。
-
「潜在GDP」がトレンドに対応しており,「GDPギャップ」はトレンドからの%乖離を表している。
-
「潜在成長率」はトレンドの成長率に対応しており,「需給ギャップ」がトレンドからの%乖離を表している。
いずれにしろ,どのようにトレンドを決めたとしても,景気循環が人々の厚生に大きな影響を及ぼすことには変わりはない。不況は失業や様々な社会問題(例えば,犯罪や自殺)につながる。好況でも問題が無いわけではない。例えば,高いインフレが発生し資産価値(例えば,貨幣)が暴落し通常の生活に支障が出ることもある。またバブル景気が示すように「山」は次の「谷」の芽を育む期間となりえる。
以下では,データを使い景気循環\(Y_t^{\text{cycle}}\)の特徴を調べるが,まず上の式(100)を対数化し次式に書き換える。
ここで小文字は大文字の変数を対数化した値である(例えば,\(y_t\equiv\log(Y_t)\))。\(y_t^{\text{cycle}}\)をより直感的に解釈するために式(101)の右辺を次のように近似しよう。
即ち,\(y_t^{\text{cycle}}\)は変数\(Y_t\)のトレンドからの乖離をパーセンテージで表している。
ここまでの説明から,景気循環を捉える項\(y_t^{\text{cycle}}\)は変数の値とトレンドとの残差によって決まることがわかる。換言すると,景気循環の特徴はトレンドをどのように考えるかに依存しており,トレンドの算出方法をどうするか決めるかが重要なポイントとなる。ここでは,内閣府や日本銀行の複雑な手法ではなく,マクロ経済学研究でスタンダードなツールとなっているHodrick–Prescottフィルターと呼ばれる手法を使うことにする。詳細についての説明は控え,単にpy4macro
に含まれる関数trend
を使ってトレンド抽出を行うことにする。使い方は次のコードで確認できる。
help(py4macro.trend)
Help on function trend in module py4macro.py4macro:
trend(s, lamb=1600)
|
| 引数:
| s: Seriesもしくは1列のDataFrameとし,行のラベルはDatetimeIndexとすること。
| lamb: 四半期用のデータでは通常の値(デフォルト:1600)
|
| 返り値:
| Hodrick-Prescott filterで計算したtrend(トレンド)のSeries
|
| 例: py4macro.trend(df.loc[:,'gdp'])
使い方は簡単で,トレンドを計算したい変数のSeries
もしくは1列のDataFrame
を引数に設定し実行するとトレンドが返される。ただ,HPフィルターは線形トレンドが仮定されているため,次の点に注意すること。
GDPや消費の様に長期的に増加している変数は対数化し,
trend()
関数の引数に使うこと。失業率やインフレ率の様に長期的には「一定」になる変数は,そのまま
trend()
関数の引数に使うこと。
まず次の変数の対数化した変数とそのトレンドを計算しdf
に追加しよう。
var_list = ['gdp',
'consumption',
'investment',
'government',
'exports',
'imports']
for v in var_list:
df[v+'_log'] = np.log( df.loc[:,v] ) #1
df[v+'_log_trend'] = py4macro.trend( df.loc[:,v+'_log'] ) #2
コードの説明
#1
:対数化した変数を新たな列として追加している。列ラベルをv+'_log'
としているのは元々の変数名の後に_logを追加するためである。例えば,1回目のループの新たな列ラベルは
gdp_logとなり,2回目のループでは
consumption_log`となる。#2
:対数化した変数のトレンドを新たな列として追加している。列ラベルをv+'_log_trend'
としているのは元々の変数名の後に_log_trend
を追加するためである。例えば,1回目のループの新たな列ラベルはgdp_log_trend
となり,2回目のループではconsumption_log_trend
となる。
df
の属性.columns
を使い,列ラベルを表示して確認してみよう。
df.columns
Index(['gdp', 'consumption', 'investment', 'government', 'exports', 'imports',
'capital', 'employed', 'unemployed', 'unemployment_rate', 'hours',
'total_hours', 'inflation', 'price', 'deflator', 'gdp_log',
'gdp_growth_quarter', 'gdp_growth_annual', 'gdp_log_trend',
'consumption_log', 'consumption_log_trend', 'investment_log',
'investment_log_trend', 'government_log', 'government_log_trend',
'exports_log', 'exports_log_trend', 'imports_log', 'imports_log_trend'],
dtype='object')
_log
と_log_trend
が追加された変数が新たに作られていることが確認できる。
GDP#
対数化したGDPの変数を作成しトレンドと重ねて図示してみる。
df[['gdp_log','gdp_log_trend']].plot()
pass
トレンドは直線ではなくスムーズな曲線となっている。上下に動く変数を平滑化したものがトレンドなので直線になるとは限らないのである。
次に景気循環の変数を作成するが,トレンドからの乖離を%で表すために次の関係を利用する。
df['gdp_cycle'] = 100 * ( df['gdp_log'] - df['gdp_log_trend'] )
0
に横線を引いてプロットしてみよう。
ax_ = df['gdp_cycle'].plot(marker='.', # 1
linestyle=':',
title='GDPのトレンドからの%乖離')
ax_.axhline(0, color='red') # 2
pass
コード説明
Pandas
のメソッドplot
は図を表示すると共に図の「軸(axis)」を返すが,それを変数ax
に割り当てている。marker
はデータのマーカーを指定する引数であり,'.'
は小さな点を指定している。linestyle
は線のスタイルを指定する引数であり,':'
は点線を指定している。
ax_
のメソッド.axhline()
を使うと横線を描くことができる。縦軸の値
0
は必須の引数color=red
は色を指定する引数(無くても良い)。
図の景気循環はトレンドからの乖離である。乖離の典型的な特徴として持続性がある。これは同じ方向の乖離が続く傾向があるという意味である。即ち,今期景気が良ければ(悪ければ)来期も景気が良い(悪い)可能性が高いということである。もちろん,いずれは乖離が狭まり「山」から「谷」,そして「山」へと循環して行く。持続性を示す数値として自己相関係数がある。
説明するために2つの変数\(Y\)と\(Z\)を考え次の係数を定義しよう。
分子の標本共分散が符号を決定する。
分母は\(R(Y,Z)\)の値が\(-1\leq R(Y,Z)\leq 1\)となるよう標準化している。
\(t\)期のGDPを\(x_t\)としよう。式(104)を使うと,\(Y\)と\(Z\)が次の場合に\(x_t\)の自己相関係数となる。
直感的に説明すると,自己相関とは今期の値が前期の値に依存する程度をいう。前期の影響が強ければ,自己相関係数の絶対値は大きくなる。
式(105)として式(104)を計算するが,Series
にはそれを計算するメソッド.autocorr()
が用意されている。
df['gdp_cycle'].autocorr()
0.680888809545929
正の値であり,今期に高(低)ければ来期も高い(低い)可能性が非常に大きいことが分かる。第二の特徴として,「山」と「谷」の形,幅(期間),高さ(深さ)はまちまちであり,不確実な要素の働きが大きい。言い換えると,景気循環の予測は非常に難しい。この点は確率変数として捉えることができるが,このアプローチは後のトピックで扱う。
GDPの構成要素#
トレンドからの乖離#
次にGDPの構成要素について考えるが,まずトレンドからの乖離の変数を作成する(単位:%)。
for v in var_list[1:]: # gdp以外の変数
df[v+'_cycle'] = 100 * ( df[v+'_log'] -df[v+'_log_trend'] )
図示する変数のリスを作成するために,列ラベルを確認しよう。
df.columns
Index(['gdp', 'consumption', 'investment', 'government', 'exports', 'imports',
'capital', 'employed', 'unemployed', 'unemployment_rate', 'hours',
'total_hours', 'inflation', 'price', 'deflator', 'gdp_log',
'gdp_growth_quarter', 'gdp_growth_annual', 'gdp_log_trend',
'consumption_log', 'consumption_log_trend', 'investment_log',
'investment_log_trend', 'government_log', 'government_log_trend',
'exports_log', 'exports_log_trend', 'imports_log', 'imports_log_trend',
'gdp_cycle', 'consumption_cycle', 'investment_cycle',
'government_cycle', 'exports_cycle', 'imports_cycle'],
dtype='object')
列ラベルに_cycle
がついている変数だけを選ぶためにcycle_list
を作成する。
cycle_list = df.columns[-6:] # 最後の6変数
df.loc[:,cycle_list].plot(subplots=True, figsize=(8,10))
pass
この図に基づいて3つの点について考える。
持続性を示す自己相関
GDPと順循環的(pro-cyclical)か反循環的(counter- cyclical)かどうか
変動の大きさの比較
自己相関#
for
ループを使って自己相関係数を計算しよう。
for v in cycle_list:
autocorr = df[v].autocorr() # (1)
print(f'{v:<19}{autocorr:>5.2f}') # (2)
gdp_cycle 0.68
consumption_cycle 0.46
investment_cycle 0.84
government_cycle 0.63
exports_cycle 0.74
imports_cycle 0.82
コードの説明
.autocorr()
は自己相関係数を計算するメソッド。f-string
を使っている。<19
はv
の文字列の長さを空白を足して19
にし左詰めにする。>5
はcorr
の文字列の長さを空白を足して5
にし右詰めにする。.2f
は小数点第二位までの表示を設定している。>5
と.2f
の順番を逆にするとエラーが発生する。
全て0.45
以上であり,強い持続性が確認できる。
GDPとの相関度#
GDPと他の変数との相関度を確認するために2変数の相関係数を考えよう。式(104)を使うと\(Y\)と\(Z\)は次のようになる。
式(106)として式(104)を計算するが,Series
にはそれを計算するメソッド.corr()
が用意されている。for
ループを使って計算しよう。
print('GDPの変動との相関係数\n------------------------')
for v in cycle_list:
corr = df[['gdp_cycle', v]].corr().iloc[0,1] # 1
print(f'{v:<19}{corr:>5.2f}') # 2
GDPの変動との相関係数
------------------------
gdp_cycle 1.00
consumption_cycle 0.77
investment_cycle 0.77
government_cycle -0.15
exports_cycle 0.75
imports_cycle 0.66
コードの説明
.corr()
は相関係数を計算するメソッドであり,2x2の行列を返す。iloc[0,1]
は相関係数の値を抽出している。iloc[1,0]
でも同じ結果となる。
f-string
を使っている。<19
はv
の文字列の長さを空白を足して19
にし左詰めにする。>5
はcorr
の文字列の長さを空白を足して5
にし右詰めにする。.2f
は小数点第二位までの表示を設定している。>5
と.2f
の順番を逆にするとエラーが発生する。
政府支出以外は全て相関係数は正の値であり,値も大きい。即ち,順循環的である(裏にあるメカニズムを考えてみよう)。下の図はGDPと投資の散布図であり,正の相関を確認できる。
df.plot('gdp_cycle', 'investment_cycle', kind='scatter')
pass
一方,政府支出の値は負であり,景気循環をコントロールしようとする政府の政策の現れと解釈できる。値が小さいのは,時間的なラグがあるためだと思われる。景気に関するデータを集計するには数ヶ月かかり,国会審議や支出の実行にも時間を取られることになる。時間的なラグを捉えるために,Series
のメソッド.shift()
を使って相関係数を再計算してみよう。
print(' GDPとの相関係数\n-----------------------')
for n in range(1,12):
df['gov_cycle_shift'] = df['government_cycle'].shift(-n) #1
corr = df[['gdp_cycle', 'gov_cycle_shift']].corr().iloc[0,1]
print(f'{n:>3}期先の政府支出: {corr:>6.3f}')
del df['gov_cycle_shift'] #2
GDPとの相関係数
-----------------------
1期先の政府支出: -0.304
2期先の政府支出: -0.380
3期先の政府支出: -0.365
4期先の政府支出: -0.274
5期先の政府支出: -0.212
6期先の政府支出: -0.099
7期先の政府支出: -0.037
8期先の政府支出: 0.055
9期先の政府支出: 0.092
10期先の政府支出: 0.118
11期先の政府支出: 0.119
コードの説明
#1
:.shift()
の引数は値を先に何期ずらすかを指定する。比べたいのは\(t\)期のGDPと\(t+n\)期の政府支出なので,後にずらす必要があるためマイナス符号を付けて.shift(-t)
としている。#2
:列gov_cycle_shift
は必要ないので削除する。
GDPの乖離は2四半期先の政府支出との相関係数が最大となっている。景気循環に対する政府の姿勢が確認できる一方,政府の対応には長いの時間が掛かることを示す結果となっている。
変動の大きさ#
次に変動の大きさを考えるために,GDPの標準偏差に対するそれぞれの構成要素の標準偏差の比率を計算する。
for v in cycle_list:
var = df[v].std() / df['gdp_cycle'].std()
print(f'{v:<19}{var:>5.2f}')
gdp_cycle 1.00
consumption_cycle 0.81
investment_cycle 3.19
government_cycle 0.90
exports_cycle 3.83
imports_cycle 3.30
投資,輸出,輸入の値はGDPの3倍以上であり,政府支出の値はGDPより低く,消費の変動は更に小さい。これは消費者の不確実性を嫌う姿勢が反映されていると解釈できる。GDPの構成要素を対GDP比率で検討した際,消費は投資よりも比率が大きかったことを思い出そう。変動に関しては,順位が逆転し投資が大きく上回っている。この点を図示して視覚的に確認してみよう。
df.loc[:,cycle_list[:3]].plot()
pass
これらの結果を説明するために,効用最大化に基づく消費者理論があり,利潤最大化に基づく企業行動に関するモデルが使われている。