【物流業界内の格差は大きいのか?】ジニ指数で他業界と比較してみた
物流業界には意外と大企業の割合が多いことが【物流業は儲かるのか?】売上高と営業利益率を他業界と比較してみたでわかりましたが、業界の寡占度はどのくらいなのでしょうか?
例えば、米国のIT業界ではGAFAMなどによる寡占がかなり進んでいますが、日本の外食業界は群雄割拠なので寡占度は低いことが予想できます。
寡占度が高いということは、会社間の格差が大きいということもできます。
このような格差を比較するのにジニ指数がよく用いられますが、前回の記事【ジニ指数をExcelとPythonで計算する】テスト結果を例にわかりやすく解説では 、このジニ指数をExcelとPythonで計算する方法を解説しました。
今回は売上高のジニ指数を業界ごとにPythonで計算してみました。
物流業界の売上高の格差は他の業界と比べてどうなのでしょうか?
分析データ
Investing.comで上場企業の過去4年分の売上高/粗利益/営業利益/当期利益が取得できます。
また業界も52に分類されているので、業界ごとの売上高の分布がわかります。
これらのデータはInvestpyというライブラリーを使えばPythonで自動取得できるので、取得後、1年分だけのデータを残して下記のようなデータフレームに整理しました。
物流業界のローレンツ曲線
まずはこの中から物流業界のデータだけを抜き出して、ローレンツ曲線を描いてみます。
このデータフレームでは物流業界のIDを51としているので、下記のようなコードで描くことができます。
import matplotlib.pyplot as plt
import numpy as np
rev_list = df[df['ID_Industry'] == '51']['Total Revenue1'].values
rev_list = np.sort(rev_list)
x = np.linspace(0, 1, len(rev_list)+1)
x = x.tolist()
rel = rev_list / np.sum(rev_list)
rel_cum = rel.cumsum()
rel_cum = rel_cum.tolist()
rel_cum = [0] + rel_cum
plt.plot(x, rel_cum)
plt.xlabel("Company")
plt.ylabel("Cumulative Revenue")
曲線の曲がり度合いはそこそこ大きいことがわかります。
大体、上位20%の大企業で、業界全体の売上高の約80%を占めていることもわかります。
物流業界のジニ指数
では曲線の曲がり度合いを表すジニ指数を求めてみましょう。
ジニ指数の計算方法については、こちらを参照して下さい。
【ジニ指数をExcelとPythonで計算する】テスト結果を例にわかりやすく解説
先程計算したローレンツ曲線のx座標のリスト(x)とy座標のリスト(rel_cum)を使って、下記のように計算できます。
from scipy import integrate
gini = 2 * (0.5 -integrate.trapz(rel_cum, x))
gini
-------------------------
0.7316396733397128
このように物流業界の売上高のジニ指数は0.73になりました。
これは他の業界と比較してどうなのでしょうか?
業界別のジニ指数
52ある業界ごとのジニ指数を求めるには、今やった計算をfor文ですべての業界について繰り返せばよいでしょう。
まずはすべての業界IDを文字列で格納したリストidsを作りましょう。
df_industry = df['ID_Industry'].unique()
ids0 = df_industry['ID_Industry'].tolist()
ids = []
for id in ids0:
a = str(id)
ids.append(a)
そして、このリストに入っている業界IDをfor文で1つずつ入れ替えながら各業界のジニ指数を計算して、df_giniに結果を格納します。
またその際に、各業界の会社数もcnt列に格納しました。
df_gini = pd.DataFrame(columns=['gini', 'cnt'])
i = 0
for id in ids:
rev_list = df[df['ID_Industry'] == id]['Total Revenue1'].values
rev_list = np.sort(rev_list)
x = np.linspace(0, 1, len(rev_list)+1)
x = x.tolist()
rel = rev_list / np.sum(rev_list)
rel_cum = rel.cumsum()
rel_cum = rel_cum.tolist()
rel_cum = [0] + rel_cum
df_gini.loc[i, 'gini'] = 2 * (0.5 -integrate.trapz(rel_cum, x))
df_gini.loc[i, 'cnt'] = len(rev_list)
i = i + 1
df_gini
これだとどの業界の数字だかわからないので、業界IDも加えましょう。
df_gini = df_gini.reset_index()
df_gini = df_gini.rename({'index': 'ID_Industry'}, axis='columns')
df_gini['ID_Industry'] = df_gini['ID_Industry'].astype(str)
df_gini.columns = ['ID_Industry', 'gini', 'cnt']
df_gini
これでもまだわかりにくいので、業界名と順位も追加しておきましょう。
df_gini = pd.merge(df_gini, df, on = 'ID_Industry', how = 'left')
df_gini = df_gini[['ID_Industry', 'Industry', 'gini', 'cnt']].drop_duplicates().reset_index().drop('index', axis=1)
df_gini['gini_rank'] = df_gini['gini'].rank(ascending = False).astype(int)
df_gini = df_gini.sort_values('gini_rank', ascending = True)
df_gini
物流業界は全52業界中、中間くらいの22位でした。
ジニ指数が大きい業界のローレンツ曲線
一番ジニ指数の大きな業界は“家電&コンピュータ”でした。
全部で30の会社がありますが、上位10社を見てみましょう。
df[df['ID_Industry'] == '3'][['Company', 'Total Revenue1']].sort_values('Total Revenue1', ascending = False).head(10)
トップのソニーとパナソニックの売上高はあまり差がありませんが、3位以下はかなりの差があることがわかります。
1位と10位とでは100倍近くの差があります。
ローレンツ曲線を描いてみると、次のようにかなりシャープな切れのある曲線になります。
ジニ指数が小さい業界のローレンツ曲線
一方でジニ指数が小さく会社数もそこそこある業界は“住居&商業向けREIT”です。
上位10社の売上高は次の通りです。
df[df['ID_Industry'] == '12'][['Company', 'Total Revenue1']].sort_values('Total Revenue1', ascending = False).head(10)
1位と10位は10倍も差がありません。
ドングリの背比べです。
ローレンツ曲線は、次のようにy=xに近い曲線になります。
利益率のジニ指数が計算できない
同様に営業利益率のジニ指数を計算してみたところ下記のようになりました。
赤線で囲った部分を見て下さい。
ジニ指数は0~1になるはずなのに、1より大きかったり0より小さい数もあります。
例えば“外食&娯楽サービス”のジニ指数は-3.4になっています。
ローレンツ曲線を見てみましょう。
このようにマイナス領域に大きく食い込んでいます。
多くの会社で営業利益がマイナス、つまり赤字になっているためです。
ジニ指数は下図において、底辺1、高さ1の三角形の面積0.5に対する青影部分の面積の比で求められるため、ローレンツ曲線が上図のようになってしまうと計算できないのです。
「マイナスのデータがあるとジニ指数は使えないのか?」
というとそういうわけでもなく、そのような場合にも対応できる拡張ジニ指数の求め方も知られています。
次回はそれをPythonで試してみます。