成長会計#

in English or the language of your choice.

import japanize_matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import py4macro

# 警告メッセージを非表示
import warnings
warnings.filterwarnings("ignore")

はじめに#

この章では次の問を考える。

(問2)なぜ国々の経済成長率は大きく異なるのか?

この問を成長会計と呼ばれる手法を使って考察する。この手法も発展会計と同様に,一人当たりGDPの変化率(即ち、経済成長率)を全要素生産性と蓄積生産要素に分解し、それぞれの寄与度を考察することにより問2の「なぜ」を考える。

成長率について#

\(t\)時点の生産関数を

\[ y_t=A_tk_t^a\left(h_tH_t\right)^{1-a} \]

としよう。\(t\)時点と\(t+1\)時点の生産関数を使うと

\[ \frac{y_{t+1}}{y_t}=\frac{A_{t+1}}{A_t} \left(\frac{k_{t+1}}{k_t}\right)^a \left(\frac{h_{t+1}H_{t+1}}{h_tH_t}\right)^{1-a} \]

となる。ここで

\[ 1+g_x\equiv\frac{x_{t+1}}{x_t} \]

とすると,\(g_x\)\(x\)の成長率(例えば、0.02)である。これにより、

\[ 1+g_y=(1+g_A)(1+g_k)^a\left[(1+g_h)(1+g_H)\right]^{1-a} \]

となり、対数化すると

\[ \log(1+g_y)=\log(1+g_A)+a\log(1+g_k)+(1-a)\left[\log(1+g_h)+\log(1+g_H)\right] \]

となる。また成長率が十分に小さい場合(例えば、0.02)、次式で近似することが可能となる。

(10)#\[ \log(1+g_x)\approx g_x \]
np.log(1+0.02)
0.01980262729617973

即ち、

(11)#\[ g_y=g_A+ag_k+(1-a)(g_h+g_H) \]

となる。

この式に基づき,成長会計,即ち,どの要素がどれだけ一人当たりGDPの成長率に貢献しているかを計算することになる。

次に変数の平均成長率の計算方法を説明する。ある変数\(x\)が毎年\(g_x\)の率(例えば,0.02)で\(n\)年間成長したとしよう。初期の\(x=x_0\)に対する\(n\)年後の比率を考えると,次式が成立する。

(12)#\[ \frac{x_{n}}{x_{0}}= \frac{x_1}{x_{0}}\cdot \frac{x_2}{x_{1}}\cdot \frac{x_3}{x_{2}}\cdot \cdots \frac{x_{n-2}}{x_{n-3}}\cdot \frac{x_{n-1}}{x_{n-2}}\cdot \frac{x_n}{x_{n-1}} =(1+g_x)^{n} \]

\(g_x\)は一定なので\(g_x\)は年間平均成長率と等しい。このことを踏まえ(12)の両辺を\(1/n\)乗すると次式となる。

\[ \left(\frac{x_n}{x_0}\right)^{\frac{1}{n}}=1+g_x \]

即ち,\(1+g_x\)\(\dfrac{x_n}{x_0}\)の幾何平均であり,平均成長率\(g_x\)はこの式を使い計算できる。

(13)#\[ g_x= \left( \dfrac{x_{n}}{x_{0}} \right)^{\frac{1}{n}}-1 \]

この場合,算術平均ではなく幾何平均を使うことに注意しよう。また毎期毎期の成長率が違っても同じ結果(13)が成立することも覚えておこう。

更に,年間平均成長率を計算する場合,(12)の両辺を対数化し式(10)の近似を使うこともできる。

\[\begin{split} \begin{align*} \ln\left(\frac{x_n}{x_0}\right) &=\ln\left(1+g_x\right)^n \\ &\Downarrow \end{align*} \end{split}\]
(14)#\[ g_x\approx\frac{1}{n}\ln\left(\frac{x_n}{x_0}\right) \]

\(g_x\)が十分に小さい場合は,(13)(14)のどちらを使っても大きな差は出ない。重要な点は,どちらかの一つの方法を計算の対象全てに一貫して使うことであり,以下では(11)(14)を使って計算する。

例:\(x_0=10\)\(x_n=30\)\(n=50\)

x0 = 10
xn = 30
n  = 50

houhou1 = (xn/x0)**(1/n)-1
houhou2 = ( np.log(xn)-np.log(x0) )/n

print(f'方法1:{houhou1:}\n方法2:{houhou2}')
方法1:0.022215413278477092
方法2:0.02197224577336219

平均成長率の計算#

まずPenn World Tableを読み込み,国のリストを作成しよう

df = py4macro.data('pwt')
country_list = df.loc[:,'country'].unique()

データに含まれる次の変数を使う。

  • rgdpna:実質GDP

    • 経済成長を考える上で適している

  • emp:雇用者数

  • rkna:物的資本サービス

  • hc:人的資本の指標

    • 教育年数と教育の収益から計算されている

以下で計算する変数とは次のように対応している。

  • 一人当たりGDP:\(y_i\equiv\dfrac{Y_i}{L_i}=\) rgdpna/emp

  • 一人当たり資本:\(k_i\equiv\dfrac{K_i}{L_i}=\) rkna/emp

  • 労働者一人当たり人的資本サービス:\(h_iH_i=\) avhxhc

  • 資本の所得シャア:\(\alpha=1/3\)(仮定)

  • 蓄積生産要素:\(k_i^{\alpha}\left(h_iH_i\right)^{1-\alpha}\)

  • 全要素生産性:\(A_i=\dfrac{y_i}{k_i^{\alpha}\left(h_iH_i\right)^{1-\alpha}}\)

それぞれの変数を計算しよう。

# 資本の所得シャア
a=1/3.0

# 一人当たりGDP
df['gdppc'] = df['rgdpna'] / df['emp']

# 資本割合

df['kpc'] = df['rkna'] / df['emp']

# 蓄積生産要素
df['factors'] = df['kpc']**a * ( df['avh']*df['hc'] )**(1-a)

# 全要素生産性
df['tfp'] = df['gdppc'] / df['factors']

これらの変数を使い,1999年から2019年の20年間のrgdp_pck_pcavhhcの平均成長率を計算するが,まずそのための準備として関数を作成する。次のcalculate_growth関数は,country(国)のvar(変数)の平均成長率を返す。

def calculate_growth(country, var):
    """
    引数:
        country: 国名(文字列; 例えば,'Japan')
        var: 変数名(文字列; 例えば,`gdppc`)
    戻り値:
        `country`における`var`の平均成長率(浮動小数点型)
    """

    start = 1999        #1
    end = 2019          #2
    t = end-start       #3

    cond1 = ( df.loc[:,'country']==country ) #4
    cond2 = ( df.loc[:,'year']==start )      #5
    cond3 = ( df.loc[:,'year']==end )        #6

    cond_start = ( cond1 & cond2 )           #7
    cond_end = ( cond1 & cond3 )             #8

    df_start = df.loc[cond_start,:]   #9
    df_end = df.loc[cond_end,:]       #10

    g = (1/t)*np.log( df_end[var].iloc[0]/df_start[var].iloc[0] ) #11
    
    return 100*g   #12

例として,日本の一人当たりGDPの平均成長率を計算してみよう。

calculate_growth('Japan','gdppc')
0.6242925604611884

次に,calculate_growth関数を使いいっきに全ての国の4つの変数の平均成長率を計算する。forループが二重(入れ子)になっている。

var_list = ['gdppc','kpc','avh','hc']   #1

growth_dict = {}            #2

for v in var_list:          #3
    
    growth_list = []        #4
    
    for c in country_list:  #5
        
        g = calculate_growth(c, v)  #6
        
        growth_list.append(g)       #7
            
    growth_dict[v] = growth_list    #8

df_growth = pd.DataFrame({'country':country_list,         #9
                          'gdppc':growth_dict['gdppc'],   #10
                          'kpc':growth_dict['kpc'],
                          'avh':growth_dict['avh'],
                          'hc':growth_dict['hc']})

df_growthの最初の5行を表示してみよう。

df_growth.head()
country gdppc kpc avh hc
0 Aruba -0.138284 3.101398 NaN NaN
1 Angola 1.929675 -0.188248 NaN 0.732205
2 Anguilla NaN NaN NaN NaN
3 Albania 3.525447 NaN NaN 0.386450
4 United Arab Emirates -2.090208 NaN NaN 0.335412

Note

DataFrameにはグループ計算用のメソッドgroupbyが備わっており,それを使うとより短いコードでdf_growthを作成することができる。

def calc_growth(x):
    return (1/(len(x)-1))*np.log( x.iloc[-1] / x.iloc[0] )

cond1 = ( 1999 <= df['year'] )
cond2 = ( 2019 >= df['year'] )
cond = cond1 & cond2
df_growth = 100 * df.loc[cond,:].groupby('country')[['gdppc','kpc','avh','hc']].agg(calc_growth)

ここを参考にしよう。

gdppcの成長率のヒストグラムをプロットするが,ここではDataFrameのメソッドplot()を使う。まず使用する列を選んでメソッドplot()の引数にkind='hist'を指定するだけである。bins=20は階級(棒)の数を指定する引数(デフォルトは10)と理解すれば良いだろう。

df_growth['gdppc'].plot(kind='hist',bins=15)
pass
_images/d1eb953b253cf2c64158b66eb48961478b128b98aeb3cb5505095cddc5f2737c.png

多くの国はプラスの経済成長を遂げているが,マイナイス成長の経済も存在する。平均成長率がマイナスの国数を計算してみよう。

cond = ( df_growth.loc[:,'gdppc']<0 )
len(df_growth.loc[cond,:])
29

最も平均成長率が低い経済の国名を探してみよう。

df_growth_sorted = df_growth.sort_values('gdppc')
df_growth_sorted.head()
country gdppc kpc avh hc
176 Venezuela (Bolivarian Republic of) -4.749982 -0.583572 NaN 1.560305
179 Yemen -4.072836 NaN NaN 2.328553
130 Oman -3.330238 -0.217700 NaN NaN
4 United Arab Emirates -2.090208 NaN NaN 0.335412
158 Syrian Arab Republic -1.849972 NaN NaN 1.051994

ここで使ったメソッドsort_values()は,引数の列を基準に昇順に並べ替える。引数にascending=Falseを使うと,降順に並び替えることができる。

Hide code cell source
print( '上のヒストグラムで最も成長率が低い国は'
      f'{df_growth_sorted.iloc[0,0]}である。')
上のヒストグラムで最も成長率が低い国はVenezuela (Bolivarian Republic of)である。

df_growth_sortedから分かるように,他の変数には欠損値が含まれているのでNaNがある行は全て削除する。

df_growth = df_growth.dropna()

残った国数を確認してみよう。

len(df_growth)
60

蓄積生産要素の成長率#

次に,下の式を使って蓄積生産要素の成長率を計算しよう。

\[ g_{\text{factors}}=ag_k+(1-a)(g_h+g_H) \]

結果をdf_growthに追加するが,その際、\(a=\dfrac{1}{3}\)と仮定する。

df_growth.loc[:,'factors'] = (1/3)*df_growth['kpc']+(1-1/3)*( df_growth['avh']+df_growth['hc'] )

factorsの成長率のヒストグラムを図示する。

df_growth['factors'].plot(kind='hist',bins=15)
pass
_images/e1dcd13fb7fa8c3b42ab19ce6cbc7049e97091d0eaf7f0ef2ea2fb1aa7ffa905.png

マイナスの成長率の国数を調べてみよう。

cond = ( df_growth.loc[:,'factors']<0 )
len(df_growth.loc[cond,:])
0

全要素生産性#

全要素生産性は残差として計算される。

\[ g_A=g_y-g_{\text{factors}} \]
df_growth['tfp'] = df_growth['gdppc'] - df_growth['factors']

tfpの成長率のヒストグラムを図示してみよう。

df_growth['tfp'].plot(kind='hist',bins=15)
pass
_images/de4d09b96a1822850b55c64b7bd78a0264010a1ce5ca85d7e29d57daa6ffa525.png

蓄積生産要素と比べると全要素生産性の成長率はよりマイナスに広がっている。TFP成長率がマイナスの国の数を確認してみよう。

cond = ( df_growth.loc[:,'tfp']<0 )
len(df_growth.loc[cond,:])
13

蓄積要素生産性のマイナス成長率の国数と比べると10倍である。

全要素生産性と蓄積生産要素の貢献度#

全要素生産性と蓄積生産要素のどちらが成長率に貢献しているのだろうか。まず図を使って比較してみよう。

df_growth[['tfp','factors']].plot(kind='hist',bins=20,alpha=0.5)
pass
_images/13b1bda1f046fbb4d592eb4bf1cc208e8298544b0d1169fec8d90f26b0776a76.png

図から次のことがわかる。蓄積生産要素の成長率は正の値になる傾向がある。即ち,殆どの経済で蓄積生産要素による経済成長が起こっているということである。一方,全要素生産性の成長率はマイナスへの広がりがあり,成長を妨げる要因になっているようである。

次に,一人当たりGDPの成長率に対する全要素生産性の貢献度を数量化するが,2つの方法を考えよう。

方法1#

全要素生産性の貢献度を次の式で計算する。

\[ 100\times\frac{g_{A}}{g_y} \]
df_growth['tfp_contribution'] = 100 * df_growth['tfp']/df_growth['gdppc']

全要素生産性の貢献度が50%以上の国はデータセット全体の何%を占めるかを計算しよう。

cond = ( df_growth.loc[:,'tfp_contribution']>=50 )
100 * len(df_growth.loc[cond,:]) / len(df_growth)
45.0

45.0%の国で全要素生産性がより大きな貢献をしている。

方法2#

2つ目の方法として発展会計で使った方法を考える。

\[ g_{yi} = g_{Ai} + g_{\text{factors},i} \]

従って、分散を計算すると

\[ \text{Var}\left(g_{yi}\right)= \text{Var}\left(g_{Ai}\right)+ \text{Var}\left(g_{\text{factors},i}\right) +2\text{Cov}\left(g_{Ai},g_{\text{factors},i}\right) \]

となり、次式を定義することができる。

\[\begin{split} \begin{align*} \text{全要素生産性の寄与度}&= \dfrac{ \text{Var}\left(g_{Ai}\right)+ \text{Cov}\left(g_{Ai},g_{\text{factors},i}\right) }{ \text{Var}\left(g_{yi}\right) } \\ \text{生産要素の寄与度}&= \dfrac{ \text{Var}\left(g_{\text{factors},i}\right)+ \text{Cov}\left(g_{Ai},g_{\text{factors},i}\right) }{ \text{Var}\left(g_{yi}\right) } \end{align*} \end{split}\]

これらの式に従って計算してみよう。

# それぞれの変数を設定
gdppc_growth   = df_growth['gdppc']
tfp_growth     = df_growth['tfp']
factors_growth = df_growth['factors']

# 分散・共分散の計算
gdppc_growth_var       = gdppc_growth.var()
tfp_growth_var         = tfp_growth.var()
factors_growth_var     = factors_growth.var()
tfp_factors_growth_cov = np.cov(tfp_growth, factors_growth)[0,1]

Hint

tfp_factors_growth_covは次のコードでも計算できる。

df_growth.loc[:,['tfp','factors']].cov().iloc[0,1]

全要素生産性の寄与度

(tfp_growth_var + tfp_factors_growth_cov) / gdppc_growth_var
0.5790633151326812

蓄積生産要素の寄与度

(factors_growth_var+ tfp_factors_growth_cov) / gdppc_growth_var
0.4209366848673189

蓄積生産要素と全要素生産性の寄与度は概ね6対4の割合でであることが確認できる。この結果は両変数の成長率のヒストグラムからも伺える。全要素生産性の方がより幅広く変化しているようである。いずれにしろ,蓄積生産要素と全要素生産性ともに一人当たりGDPの成長に大きく貢献していることが確認できる。

表の作成#

結果を表としてまとめてみる。右端の列は方法1の結果を使っている。

country_table = ['Japan', 'United Kingdom','United States', 'Norway',
                'Singapore','Peru','India','China']

cond = df_growth['country'].isin(country_table)

col = ['country','gdppc','factors','tfp','tfp_contribution']

df_growth.loc[cond,col].set_index('country') \
         .sort_values('gdppc', ascending=False) \
         .round(2) \
         .rename(columns={'gdppc':'一人当たりGDPの成長率',
                          'factors':'蓄積生産要素の成長率',
                          'tfp':'全要素生産性の成長率',
                          'tfp_contribution':'全要素生産性の寄与度(%)'})
一人当たりGDPの成長率 蓄積生産要素の成長率 全要素生産性の成長率 全要素生産性の寄与度(%)
country
China 6.07 4.24 1.83 30.08
India 5.17 3.05 2.12 40.96
Peru 2.42 1.45 0.97 40.16
Singapore 1.72 2.06 -0.34 -19.85
United States 1.34 0.64 0.70 52.08
United Kingdom 0.77 0.61 0.16 21.29
Japan 0.62 0.27 0.36 57.12
Norway 0.61 0.72 -0.12 -19.56

ここでの全要素生産性の寄与度は,一人当たりGDPの成長率のうち何%がTFPによるものかを示している。この表を見ると,日本の全要素生産性の寄与度は非常に大きい。このデータは1999~2019年のデータであり,それ以前ではどうだったのかを含めて,次節では年代を区切って日本の経済成長を考察してみることにする。

日本#

日本の年代別に成長率を考えてみよう。まず次の関数を作成するが,これはcalculate_growth関数を「日本仕様」に少しだけ修正したものとなっており,中身はほとんど同じである。大きな違いは引数にstartendを加えてことである。

def jp_calculate_growth(var, start, end):
    """
    引数:
        var: 変数名(文字列; 例えば,`gdppc`)
        start: 最初の年(整数型)
        end: 最後の年(整数型)
    戻り値:
        日本における`var`の平均成長率(浮動小数点型)
    """

    t = end-start

    cond1 = ( df.loc[:,'country']=='Japan' )
    cond2 = ( df.loc[:,'year']==start )
    cond3 = ( df.loc[:,'year']==end )

    cond_start = ( cond1 & cond2 )
    cond_end = ( cond1 & cond3 )

    df_start = df.loc[cond_start,:]
    df_end = df.loc[cond_end,:]

    g = (1/t)*np.log( df_end[var].iloc[0]/df_start[var].iloc[0] )
    
    return 100*g

jp_calculate_growth関数を使いstartからendまで4つ変数の平均成長率を計算する関数を作成する。

def jp_growth_decomposition(start, end):
    """引数:
        start(int): 開始年
        end(int): 最終年
        
       返り値:次の変数の成長率とTFPの寄与度からなるリスト
                一人当たりGDP
                一人当たり物的資本
                平均労働時間
                人的資本
                全要素生産性(TFP)"""

    var_list = ['gdppc','kpc','avh','hc']
        
    g_list = []
    
    # ========== var_listの変数の平均成長率を計算しg_listに追加する ==========
    for v in var_list:
        
        g = jp_calculate_growth(v, start, end)
        g_list.append(g)
        
    # ========== 蓄積生産要素の平均成長率を計算しg_listに追加する ==========
    factors = (1/3)*g_list[1]+(1-1/3)*( g_list[2]+g_list[3] )
    g_list.append(factors)
    
    # ========== 全要素生産性の平均成長率を計算しg_listに追加する ==========
    tfp = g_list[0]-factors
    g_list.append(tfp)

    # ========== 全要素生産性の寄与度を計算しg_listに追加する ==========
    tfp_contribution = 100*tfp/g_list[0]
    g_list.append(tfp_contribution)
    
    return g_list

この関数を使ってDataFrameを作成する。

dic = {}                                          # 1

yr_list = ['1950s','1960s','1970s',               # 2
           '1980s','1990s','2000s','2010s']

for yr in yr_list:                                # 3
    start = int(yr[:4])                           # 4
    end = start+9                                 # 5
    dic[yr] = jp_growth_decomposition(start,end)  # 6


idx = ['gdppc_growth','kpc_growth',               # 7
       'avh_growth','hc_growth','factors_growth',
       'tfp_growth','tfp_contribution']

df_jp = pd.DataFrame(dic, index=idx)              # 8
df_jp
1950s 1960s 1970s 1980s 1990s 2000s 2010s
gdppc_growth 5.655810 8.226415 3.756609 3.573876 0.900981 0.219960 0.307585
kpc_growth NaN 10.634742 8.042348 5.030082 3.975190 1.526388 0.116887
avh_growth 0.668095 -0.133169 -0.340568 -0.067613 -1.017606 -0.619595 -0.564995
hc_growth 1.257113 0.804446 0.708988 0.558892 0.515371 0.442203 0.302941
factors_growth NaN 3.992432 2.926396 2.004213 0.990240 0.390535 -0.135740
tfp_growth NaN 4.233982 0.830212 1.569663 -0.089259 -0.170575 0.443326
tfp_contribution NaN 51.468135 22.100051 43.920461 -9.906831 -77.547931 144.130973

値を確認するだけであればこのままでも良いが,棒グラフを作成するために列と行を入れ替えることにする。df_jpのメソッド.transpose()を使う。

df_jp = df_jp.transpose()
df_jp
gdppc_growth kpc_growth avh_growth hc_growth factors_growth tfp_growth tfp_contribution
1950s 5.655810 NaN 0.668095 1.257113 NaN NaN NaN
1960s 8.226415 10.634742 -0.133169 0.804446 3.992432 4.233982 51.468135
1970s 3.756609 8.042348 -0.340568 0.708988 2.926396 0.830212 22.100051
1980s 3.573876 5.030082 -0.067613 0.558892 2.004213 1.569663 43.920461
1990s 0.900981 3.975190 -1.017606 0.515371 0.990240 -0.089259 -9.906831
2000s 0.219960 1.526388 -0.619595 0.442203 0.390535 -0.170575 -77.547931
2010s 0.307585 0.116887 -0.564995 0.302941 -0.135740 0.443326 144.130973

1950年代に欠損値があるが,そのまま議論を進めよう。まず一人当たりGDP成長率gdp_pc_growthを棒グラフとして表示してみよう。表示したい列を選択し,引数にkind='bar'を選択するだけである。

df_jp['gdppc_growth'].plot(kind='bar')
pass
_images/057f1a63aa04b4dd224b3dbf9a9bb61def060e27f94558cac9922a6ba29ac8cc.png

1960年代をピークに成長率は下降線をたどっている。

次にヒストグラムに異なる変数を並べて表示してみる。この場合も、表示したい変数を先に選びkind='bar'を指定するだけである。

df_jp.iloc[:,[0,-3,-2]].plot(kind='bar')
pass
_images/ccc7ef320f9df979bf3308a1fc9c8c5d9616e220d4269ba5a8c4fbf39af717aa.png

以下では,全要素生産性と蓄積生産要素の成長率に焦点を当て議論を進めるためにdropna()を使って1950年代のデータは削除する。

df_jp = df_jp.dropna()

上の棒グラフで,引数stacked=Trueを設定すると棒を積み重ねて表示することができる。

df_jp.iloc[:,[-3,-2]].plot(kind='bar', stacked=True)
pass
_images/1ac794c6f1d7d15f0d4f314d7fa83f2c25638a4446da4c7e6e2cd10a1586338a.png

次のグラフでは,一人当たりGDPの線グラフと一緒に表示している。

ax_ = df_jp.iloc[:,0].plot(marker='o',color='k', legend=True)
df_jp.iloc[:,[-3,-2]].plot(kind='bar', stacked=True, legend=True, ax=ax_)
pass
_images/79889fd9cd98aaf84f74168d0bdfefd79512b1b5629eaf6f2bfc07d04597274e.png

1990年代に入ると,それ以前と比べて全要素生産性の成長率の下落が著しく,一人当たりGDPの成長率に大きく影響している。「失われた10年」の原因と主張する研究者もいる。