統計検定、統計学入門 (基礎統計学Ⅰ) | 東京大学教養学部統計学教室 |本 | 通販 | Amazon に、
ジニ係数という、所得分配の不平等さを測る指標 が登場します。python でこのジニ係数の計算方法や、不平等差を測るための統計指標について調べてみましたので、結果を記載します。
不平等指標について
Wikipedia に記載されている不平等指標
python だと、ライブラリのパッケージ名に、inequality
がつきます。
日本語だとあまり見つからなかったですが、英語版の Wikipedia にinequality metrics
として以下のような指標が言及されています。
-
Gini index ジニ係数
以下、ジニ係数 - Wikipedia の引用です。社会における所得分配の不平等さを測る指標
-
20:20 Ratio
母集団の上位20%と、下位20%を比較して、そこにどれだけの格差があるのか示します。 -
Palma ratio パルマ比率
パルマ比率。上位10%の所得合計÷下位40%の所得合計 で、低いほど格差が小さい指標になります。 -
Hoover index 集中指標
地域的集中度の指標 です。 以下のpdfに説明が記載されています。
研究シリーズ第32号 -
Coefficient of variation 変動係数 収入の分散の平方根を平均収入で割ったもの。統計で語られるそれは、収入に括ったものではないですが、経済指標としては、収入に括った値のようです。
-
Wage share 労働分配率
企業において生産された付加価値全体のうちの、どれだけが労働者に還元されているかを示す割合。「人件費/付加価値」で算出された%で表されます。 -
Theil index タイル指数
所得格差を示す指標。説明は、以下のpdfに記載されています。
IPSJ-JNL5211001.pdf
その他の不平等指標
Wikipedia には記載がありませんが、その他の不平等指標として、以下があるようです。
-
Atkinson Index ダルトン・アトキンソン尺度
所得格差を表す指標の一つで、所得が完全に平等に分配される状態にした時に社会が諦めねばならない総所得の割合 を示します。 -
Kakwani index カクワニ係数
貧困を示す指標 ? ジニ係数と同じような値に思われました。
一般的に使用されている不平等指標
統計検定では、過去ジニ係数と、ローレンツ曲線についての出題があり、 一般的にも、それらがよく使われているようで、その他の指標についてはあまりWeb上の情報はないように見えました。
統計局ホームページ/統計Today No.53 に以下のように記載されています。
全国消費実態調査の結果や「経済財政白書」を見ると、ほぼ一貫して不平等の指標としてジニ係数が用いられています。政府統計では従来から平均値を単一指標として示すことが多く、不平等の指標についてもジニ係数を単一指標として示すことが多いです。不平等の指標としては、ピグー=ダルトン原理を満たすものとして、ジニ係数以外にもアトキンソン指標、一般化エントロピー、タイル指標など分割公理に対応した指標もありますが、国際的な比較の観点からもジニ係数が用いられているものと考えられています。
不平等指標の計算ができるライブラリについて
以下、見つかりました。
* pysal/pysal: PySAL: Python Spatial Analysis Library
-
oliviaguest/gini: Calculate the Gini coefficient of a numpy array.
numpy で、自前実装したgini 関数が github で公開されています。 pysal で、gini 係数を計算するよりも計算速度が早いようです。
pysal で不平等指標の計算をする
-
インストール
python3 -m pip install pysal
-
ジニ係数
空間ジニ係数 と ジニ係数を計算できます。
import pysal
import numpy as np
# pysalのデータセットに含まれる、メキシコの 32のメキシコの州、1940-2010年 10年ごと の時系列データを取得する
f=pysal.open(pysal.examples.get_path("mexico.csv"))
vnames=["pcgdp%d"%dec for dec in range(1940,2010,10)]
y=np.transpose(np.array([f.by_col[v] for v in vnames]))
regimes=np.array(f.by_col('hanson98'))
# 乱数を固定
np.random.seed(12345)
w = pysal.block_weights(regimes)
# 空間ジニ係数を求める
gs = pysal.inequality.gini.Gini_Spatial(y[:,0],w)
print("空間ジニ係数", gs.__dict__)
# ジニ係数を求める
gs = pysal.inequality.gini.Gini(y[:,0])
print("ジニ係数", gs.__dict__)
空間ジニ係数 {'g': 0.35372371173452849, 'wcg': 4353856.0, 'wg': 884130.0, 'dtotal': 5237986.0, 'den': 14808128.0, 'wcg_share': 0.29401798795904521, 'wcgp': array([ 4126228., 4000994., 4203292., 4197086., 4277902., 4252922.,
4039574., 4089000., 4290410., 4120558., 4195242., 4209028.,
4038750., 4201308., 4243490., 4183814., 4168974., 4028010.,
4363162., 4110582., 4181112., 4335680., 4240808., 4154998.,
4210238., 4139444., 4137668., 4282600., 4230824., 4076498.,
4183592., 4206110., 4029216., 4236384., 4110596., 4038182.,
4015358., 4080044., 4232460., 4027460., 4151414., 4028410.,
4206624., 4183384., 4194806., 4188668., 4242914., 4281378.,
4094012., 4190744., 4245344., 4202794., 4141048., 4111328.,
4126792., 4332588., 4328924., 4264912., 4172752., 4145232.,
4156490., 4028624., 4070424., 4048800., 4180720., 4185870.,
4140368., 4325158., 4172828., 4283022., 4032032., 4064170.,
4129126., 4490908., 4067802., 4329386., 4037278., 4301716.,
4177344., 4296376., 4108508., 4094022., 4084408., 4228526.,
4058830., 4236482., 4228552., 4198926., 4108536., 4024064.,
4152000., 4146158., 4045994., 4139672., 4199608., 4124702.,
4175594., 4356900., 4311728.]), 'p_sim': 0.040000000000000001, 'e_wcg': 4170356.7474747472, 's_wcg': 95869.167798782844, 'z_wcg': 1.9140590946861487, 'p_z_sim': 0.0278063026961195}
ジニ係数 {'g': 0.35372371173452849}
Gini_Spatial は、空間ジニ係数に関する値を、持ちつつ、gs.g
で ジニ係数が取得できます。
Gini は、ジニ係数のみを返し、gs.g
で ジニ係数が取得できます。
- Theil指数
pysal.inequality.theil.Theil
、pysal.inequality.theil.TheilD
、pysal.inequality.theil.TheilDSim
が用意されています。
TheilD
、TheilDSim
については、理解が追いついておらず、ここでは、Theil
についてのみ記載します。
import pysal
f=pysal.open(pysal.examples.get_path("mexico.csv"))
vnames=["pcgdp%d"%dec for dec in range(1940,2010,10)]
y=np.transpose(np.array([f.by_col[v] for v in vnames]))
theil_y=pysal.inequality.theil.Theil(y)
print(theil_y.T)
[ 0.20894344 0.15222451 0.10472941 0.10194725 0.09560113 0.10511256
0.10660832]
IneqPy で不平等指標の計算をする
-
インストール
python3 -m pip install git+https://github.com/mmngreco/IneqPy
-
ジニ係数を計算する
ineqpy.gini
でジニ係数の計算が可能です。
import pandas as pd
import numpy as np
import ineqpy
from io import StringIO
data = StringIO("""index renta factor
0 -13004.12 1.0031
89900 141656.97 1.4145
179800 1400.38 4.4122
269700 415080.96 1.3295
359600 69165.22 1.3282
449500 9673.83 19.4605
539400 55057.72 1.2923
629300 -466.73 1.005
719200 3431.86 2.2861
809100 423.24 1.1552
899000 0 1.0048
988900 -344.41 1.0028
1078800 56254.09 1.2752
1168700 60543.33 2.0159
1258600 2041.7 2.7381
1348500 581.38 7.9426
1438400 55646.05 1.2818
1528300 0 1.0281
1618200 69650.24 1.2315
1708100 -2770.88 1.0035
1798000 4088.63 1.1256
1887900 0 1.0251
1977800 10662.63 28.0409
2067700 3281.95 1.167
""")
df = pd.read_table(data, index_col=0)
# dataframe のカラム名を指定する
print(ineqpy.gini(data=df, income='renta', weights='factor'))
# 配列を指定する
print(ineqpy.gini(income=df.renta.values, weights=df.factor.values))
0.767391363659
0.767391363659
ineqpy の gini 関数は、何故かweights
を必須で指定する必要があります。
README.md
に Weighted Gini
と記載があるので、調整したジニ係数 で pysal
で計算できる値とは違うのかと思われます。
- ダルトン・アトキンソン尺度
ineqpy.atkinson
で、ダルトン・アトキンソン尺度 の計算を行うことができます。
import pandas as pd
import numpy as np
import ineqpy
from io import StringIO
data = StringIO("""index renta factor
0 -13004.12 1.0031
89900 141656.97 1.4145
179800 1400.38 4.4122
269700 415080.96 1.3295
359600 69165.22 1.3282
449500 9673.83 19.4605
539400 55057.72 1.2923
629300 -466.73 1.005
719200 3431.86 2.2861
809100 423.24 1.1552
899000 0 1.0048
988900 -344.41 1.0028
1078800 56254.09 1.2752
1168700 60543.33 2.0159
1258600 2041.7 2.7381
1348500 581.38 7.9426
1438400 55646.05 1.2818
1528300 0 1.0281
1618200 69650.24 1.2315
1708100 -2770.88 1.0035
1798000 4088.63 1.1256
1887900 0 1.0251
1977800 10662.63 28.0409
2067700 3281.95 1.167
""")
df = pd.read_table(data, index_col=0)
# ダルトン・アトキンソン尺度 を計算
print(ineqpy.atkinson(data=df, income='renta', weights='factor'))
0.42284127012
- ローレンツ曲線
ineqpy.lorenz
でローレンツ曲線を返すdataframeを取得できます。
import pandas as pd
import numpy as np
import ineqpy
from io import StringIO
data = StringIO("""index renta factor
0 -13004.12 1.0031
89900 141656.97 1.4145
179800 1400.38 4.4122
269700 415080.96 1.3295
359600 69165.22 1.3282
449500 9673.83 19.4605
539400 55057.72 1.2923
629300 -466.73 1.005
719200 3431.86 2.2861
809100 423.24 1.1552
899000 0 1.0048
988900 -344.41 1.0028
1078800 56254.09 1.2752
1168700 60543.33 2.0159
1258600 2041.7 2.7381
1348500 581.38 7.9426
1438400 55646.05 1.2818
1528300 0 1.0281
1618200 69650.24 1.2315
1708100 -2770.88 1.0035
1798000 4088.63 1.1256
1887900 0 1.0251
1977800 10662.63 28.0409
2067700 3281.95 1.167
""")
df = pd.read_table(data, index_col=0)
# ローレンツ曲線を示すデータフレームを取得
result = ineqpy.lorenz(data=df, income='renta', weights='factor')
%matplotlib inline
# x軸、y軸を指定してplot する
result.plot(x='x', y='y')
<matplotlib.axes._subplots.AxesSubplot at 0x10fc60b00>
ローレンツ曲線と思われるグラフが描画できています。
元データがいまいちなんのデータなのかわからないので、あまり面白みはないかもしれません。
numpy でgini 係数を計算する
oliviaguest/gini: Calculate the Gini coefficient of a numpy array. に記載のメソッドを拝借します。
import numpy as np
def gini(array):
"""Calculate the Gini coefficient of a numpy array."""
# based on bottom eq: http://www.statsdirect.com/help/content/image/stat0206_wmf.gif
# from: http://www.statsdirect.com/help/default.htm#nonparametric_methods/gini.htm
array = array.flatten() #all values are treated equally, arrays must be 1d
if np.amin(array) < 0:
array -= np.amin(array) #values cannot be negative
array += 0.0000001 #values cannot be 0
array = np.sort(array) #values must be sorted
index = np.arange(1,array.shape[0]+1) #index per array element
n = array.shape[0]#number of array elements
return ((np.sum((2 * index - n - 1) * array)) / (n * np.sum(array))) #Gini coefficient
import pysal
import numpy as np
# pysalのデータセットに含まれる、メキシコの 32のメキシコの州、1940-2010年 10年ごと の時系列データを取得する
f=pysal.open(pysal.examples.get_path("mexico.csv"))
vnames=["pcgdp%d"%dec for dec in range(1940,2010,10)]
y=np.transpose(np.array([f.by_col[v] for v in vnames]))
regimes=np.array(f.by_col('hanson98'))
# ジニ係数を求める
print("ジニ係数", gini(y[:,0]))
ジニ係数 0.35372371173
pysal.inequality.gini.Gini
と同様の結果が取得できます。
参考
参考にした記事のリンクになります。
以上です。
コメント