スキップしてメイン コンテンツに移動

都道府県別の婚姻数・婚姻率を評価、そして、相関分析 総務省統計局データをPythonで加工 e-Stat with Python(5)


 e-Statで統計データを調べてみると、新しい発見がたくさんあって、とても興味深いと思います。。次は、出生数・出生率と関係がありそうな婚姻数・婚姻率を都道府県別に整理してみます。

 婚姻数・婚姻率のStatsDataIDは’0003411835’でございます。Data構造は出生数・出生率と同じように、まず、都道府県別の出生数がRowData(@tab=10270)で並び、そのあとに都道府県別の出生率がRowData(@tab=10280)として続きます。e-Stat特有のDataStructureかもしれません。

 今回、都道府県別の地図表示に関するコードは前回までのコードと類似しているので省略します。

 都道府県別の婚姻数を図化すると次のようになります。東京都だけがBlue系の色彩でGreen系もYellow系もほぼ存在せず、大部分の道府県が赤色系暖色で塗られています。婚姻数でみると、人口がダントツに多い東京都がどうしても抜きんでる結果になります。

 ではでは、人口千人当たりの婚姻率で評価してみます。

 おっと、予想に反して東京都の婚姻率は高いです。その他で見ると、愛知県、大阪府、福岡県など大都市圏が多めですが、沖縄県もかなり高そうな色合いです。首都圏や京都や広島なども高めで、ひときわ低いのは秋田県でしょうか?

 ちょっと興味を魅かれたので、出生率と婚姻率の相関関係を分析することにしました。

 あらためて、出生率と婚姻率のデータをe-Statからいただきます。
 きちんと書いていませんでしたが、取得しているデータは2021年度のデータになります。
##################
# e-Stat共通設定 #
##################

# e-StatAPIのDataBaseが格納されているURL
API_URL = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData"

# 対象期間
cdTime = "2021000000"

######################################################
# e-StatAPIから出生率(e-StatDataID=0003411597)をGet #
######################################################

# e-StatDataID(対象DataBaseに固有のID
statsDataId = "0003411597"

# Processing Pandas data and change the column name
column_rename = {
    '@tab': 'DataType',
    '@area': '都道府県コード',
    '@time': '対象年',
    '@unit': '単位',
    '$': '出生率'
}

tree = "['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE']"

df = fn_get_estat_data(APP_ID, API_URL, statsDataId, cdTime, column_rename, tree)

df.head()

##########################################
# 都道府県コードを都道府県の名称に置き換え
##########################################

#Dataの構造が格納されているMetaInfoを取得
API_URL = "http://api.e-stat.go.jp/rest/3.0/app/json/getMetaInfo?"

params = {
    "appId": APP_ID,
    "statsDataId": statsDataId,
    "limit": 2,
    "lang": "J"  # 日本語を指定
}

response = requests.get(API_URL, params=params)
data = response.json()
data

# META_INFOの中から都道府県コードと都道府県名を対比している箇所を取得
values = data['GET_META_INFO']['METADATA_INF']['CLASS_INF']['CLASS_OBJ']
#pprint.pprint(values)

for dictionary in values:
    if dictionary['@id'] == 'area':
        pref_list = dictionary['CLASS']

prefectures_list = {}
for pref_code in pref_list:
    prefectures_list[pref_code['@code']] = pref_code['@name']

# 先ほど作成した辞書を使用して、都道府県コードに基づき、
# 都道府県名の列を追加するための関数を定義
def replace_pref_name(pref_code):
    return prefectures_list.get(pref_code, None)

# 都道府県コード列を都道府県名列に置き換え
df["都道府県"] = df["都道府県コード"].apply(replace_pref_name)

df_birth_rate = df[df['DataType']=='10050']

#print(df_birth_rate)

######################################################
# e-StatAPIから婚姻率(e-StatDataID=0003411835)をGet #
######################################################

# e-StatAPIのDataBaseが格納されているURL
API_URL = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData"

# e-StatDataID(対象DataBaseに固有のID)
statsDataId = "0003411835"

# 対象期間
#cdTime = "2021000000"

# Processing Pandas data and change the column name
column_rename = {
    '@tab': 'DataType',
    '@area': '都道府県コード',
    '@time': '対象年',
    '@unit': '単位',
    '$': '婚姻率'
}

tree = "['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE']"

df = fn_get_estat_data(APP_ID, API_URL, statsDataId, cdTime, column_rename, tree)

#df.head()

##########################################
# 都道府県コードを都道府県の名称に置き換え
##########################################

#Dataの構造が格納されているMetaInfoを取得
API_URL = "http://api.e-stat.go.jp/rest/3.0/app/json/getMetaInfo?"

params = {
    "appId": APP_ID,
    "statsDataId": statsDataId,
    "limit": 2,
    "lang": "J"  # 日本語を指定
}

response = requests.get(API_URL, params=params)
data = response.json()
data

# META_INFOの中から都道府県コードと都道府県名を対比している箇所を取得
values = data['GET_META_INFO']['METADATA_INF']['CLASS_INF']['CLASS_OBJ']

for dictionary in values:
    if dictionary['@id'] == 'area':
        pref_list = dictionary['CLASS']

prefectures_list = {}
for pref_code in pref_list:
    prefectures_list[pref_code['@code']] = pref_code['@name']

# 先ほど作成した辞書を使用して、都道府県コードに基づき、
# 都道府県名の列を追加するための関数を定義
def replace_pref_name(pref_code):
    return prefectures_list.get(pref_code, None)

# 都道府県コード列を都道府県名列に置き換え
df["都道府県"] = df["都道府県コード"].apply(replace_pref_name)

df_marriage_rate = df[df['DataType']=='10280']

#print(df_marriage_rate)

#出生率のDataを新しいDataFrame'df_data'にコピー
df_data = df_birth_rate[['都道府県', '出生率']].copy()

#婚姻率のDataをDataFrame'df_data'に入力
for index,row in df_marriage_rate.iterrows():
    df_data.loc[df_data['都道府県'] == row["都道府県"], "婚姻率"] = row["婚姻率"]

print(df_data)

 もう少しスリムなコードにできると思うのですが、そこは目をつぶってください。

 出生率と婚姻率をそれぞれDataFrameとして取得して、必要なデータだけdf_dataというDataFrameにTransferしています。print(df_data)の出力は以下のようになります。

    都道府県   出生率  婚姻率
49    全国   6.6  4.1
50   北海道   5.6  3.8
51   青森県   5.4  3.1
52   岩手県   5.4  3.1
53   宮城県   6.1  3.8
54   秋田県   4.6  2.8
55   山形県   5.6  3.2
56   福島県   5.9  3.5
57   茨城県   5.9  3.6
58   栃木県   6.1  3.8
59   群馬県   6.0  3.6
60   埼玉県   6.4  4.0
61   千葉県   6.3  4.0
62   東京都   7.1  5.2
63  神奈川県   6.5  4.3
64   新潟県   5.8  3.3
65   富山県   6.0  3.5
66   石川県   6.5  3.8
67   福井県   7.0  3.8
68   山梨県   6.3  3.8
69   長野県   6.3  3.7
70   岐阜県   6.2  3.5
71   静岡県   6.1  3.8
72   愛知県   7.4  4.6
73   三重県   6.4  3.8
74   滋賀県   7.4  4.2
75   京都府   6.3  3.8
76   大阪府   7.0  4.6
77   兵庫県   6.7  3.9
78   奈良県   6.0  3.4
79  和歌山県   6.1  3.6
80   鳥取県   6.8  3.6
81   島根県   6.7  3.6
82   岡山県   7.1  4.0
83   広島県   6.8  4.1
84   山口県   6.1  3.6
85   徳島県   6.1  3.5
86   香川県   6.7  3.9
87   愛媛県   6.1  3.5
88   高知県   6.0  3.4
89   福岡県   7.4  4.4
90   佐賀県   7.3  3.7
91   長崎県   6.9  3.7
92   熊本県   7.4  3.8
93   大分県   6.6  3.7
94   宮崎県   7.2  3.7
95  鹿児島県   7.4  3.7
96   沖縄県  10.0  4.8

 Indexの番号は気にしないでください。次は以下のコードで出生率や婚姻率の数値をStringからfloatに変換し、さらに、出生率と婚姻率の相関係数を計算しておきます。相関係数の計算結果はのちほどご紹介します。

# データを結合
#df_merged_data = pd.merge(df_birth_rate, df_marriage_rate, on='都道府県',  how='inner')
df_data["出生率"] = df_data["出生率"].astype(float)
df_data["婚姻率"] = df_data["婚姻率"].astype(float)

# 相関係数を計算
correlation = df_data['出生率'].corr(df_data['婚姻率'])

#print(correlation)

 次のコードで一次回帰分析をして、その評価結果を図化します。

# Plot the scatter graph
plt.figure(figsize=(8,6))
plt.scatter(df_data['婚姻率'], df_data['出生率'], label=f'データ(相関係数:{correlation:.2f})')
plt.xlabel('婚姻率')
plt.ylabel('出生率')
plt.title('出生率と婚姻率の散布図')

# Create the first order correlation model
X = df_data['婚姻率']
y = df_data['出生率']
X = sm.add_constant(X) #定数項を追加
model = sm.OLS(y, X).fit()

# Calcurate R2(Desiccion factor)
r_sq = model.rsquared

# Show the plot of the linear regression
regression_equation = f"出生率 = {model.params['const']:.2f} + {model.params['婚姻率']:.2f} * 婚姻率"
plt.plot(df_data['婚姻率'], model.predict(X),
    color='red', label='回帰直線(' + regression_equation + ')')

plt.legend()
plt.show()

 出力されるグラフは以下の通りです。

 婚姻率の大きな2点以外はかなりいい相関を示しているような気がします。出生率が10程度は沖縄県、婚姻率が5を超えているのは東京都です。この2都県を分析していくと、特殊性を見出すことができるかもしれません。そして、もしこれを読み解くことができれば、日本の少子高齢化を解決するヒントを得ることができるかもしれません。


コメント