本ページは、自殺という重い主題を扱った受賞論文を、統計教育の題材として原論文の分析を淡々と正確に解説するものです。数値は地域(都道府県)単位の集計データに関するもので、個人を対象とした分析ではありません。悩みを抱えている場合は、こころの健康相談統一ダイヤル 0570-064-556 や、よりそいホットライン 0120-279-338 などの相談窓口があります。
この教材は、原論文が使ったデータそのものを使えていません。そこで代わりのデータで同じ問いを追いかけ、結論の向き(増える/減る、強い/弱い)が原論文と一致するかを確かめます。「同じ数値が出る」ことは目標にしていません。
| 原論文が使ったデータ | SSDSE-A・SSDSE-B・SSDSE-C・SSDSE-D・林野庁「都道府県別森林率・人工林率」・厚生労働省「平成 27 年賃金構造基本統計調査」・厚生労働省「平成 14 年度から令和元年度までの地域別最低賃金改定状況」・国土交通省国土地理院「面積調」・総務省統計局「都道府県, 世帯人員別一般世帯数と世帯の種類別世帯人員」・総務省 国勢調査「母子世帯, 父子世帯数–全国, 都道府県(平成 2 年〜27 年)」・厚生労働省「患者調査」・厚生労働省「人口動態統計特殊報告」 分析単位:都道府県 中核手法:相関分析 |
|---|---|
| この教材が使うデータ | CSV は読み込まない(原論文が報告した数値をそのまま図表化して読み解く) |
| 原論文(PDF) | 男女別の自殺に至る要因について 特別賞/河又 杏香(慶應義塾湘南藤沢高等部) |
原論文と同じ粒度のデータは、この教材にも同梱しています。これを読み込めば、原論文と同じ細かさで分析をやり直せます(下の「🐍 ブラウザで動かす」でコードを書き換えて試せます)。ただし原論文が使った項目がすべて収録されているとは限りません。足りない項目は、上の「できないこと」に書いた出典から取ってくる必要があります。
▶ ここに書いてある分析は、ページ下部の「🐍 ブラウザで動かす」でそのまま実行できます(インストール不要)。動かしているのは code/2021_H5_1_shorei.py(243 行)そのものです。
リーマン・ショック後の2009年をピークに減少を続けていた日本の自殺者数は、新型コロナウイルスの感染が拡大した2020年に11年ぶりに増加した(原論文 図1)。原論文の著者は、コロナ禍という特殊な状況ではなかった2015年の自殺率に着目し、そこに影響していた要因を多方面から調べることで、これからの自殺率の増減を考える手がかりを得ようとした。
まず「男女で自殺の要因は違うのではないか」という問いを立てる。その理由は、自殺率には大きな男女差があり、男性が女性の2倍以上である期間が多いからである。都道府県別の男性自殺率と女性自殺率の相関は r = 0.2032165 と弱く、散布図を描いても明確な傾向は読み取れなかった(原論文 図2)。そこで男女を分けて要因を探る方針をとる。
相関分析 無相関の検定(p値) 偏相関係数 散布図と回帰直線
目的変数は都道府県別の年齢調整死亡率・自殺(男・女、人口10万あたり)(厚生労働省「人口動態統計特殊報告」2015年)。説明側の指標は、SSDSE(教育用標準データセット)A/B/C/D 2021 と、林野庁・厚生労働省・国土交通省国土地理院・総務省などの官庁統計を組み合わせて作成する。分析対象は47都道府県。
| 使用した主な変数 | 出典 |
|---|---|
| 完全失業者数・就業者数(男女) | SSDSE-A-2021(2015年) |
| 降水日数・降水量・総人口・小中高の児童生徒数と教員数・一般病院数 | SSDSE-B-2021(2015年) |
| 牛乳・乳製品・大豆製品・魚介類・きのこ・緑黄色野菜・酒類などの支出額 | SSDSE-C-2021(2018〜2020年平均) |
| 介護・趣味娯楽・スポーツ・旅行行楽の行動者率、学業・仕事・睡眠・休養の時間 | SSDSE-D-2021(2016年) |
| 森林率・人工林率 | 林野庁「都道府県別森林率・人工林率」(2017年) |
| 平均月間賃金・最低賃金 | 厚生労働省「賃金構造基本統計調査」「地域別最低賃金改定状況」(2015年) |
| 面積 / 一般世帯数 / 母子・父子世帯数 | 国土地理院「面積調」/ 総務省統計局 / 国勢調査(2015年) |
| 入院受療率・外来受療率 | 厚生労働省「患者調査」(2014年) |
| 年齢調整死亡率・自殺(目的変数) | 厚生労働省「人口動態統計特殊報告」(2015年) |
| 指標 | 計算方法 |
|---|---|
| 人口密度[人/km²] | 総人口 ÷ 面積 |
| 教師一人あたり生徒数[人] | (小学校児童+中学校+高校の生徒数) ÷ (各校種の教員数の合計) |
| 完全失業率(男・女)[%] | 完全失業者数 ÷ (完全失業者数+就業者数) ×100 |
| カルシウム/ビタミンD/ビタミンAを含む食品[円] | 該当食品の支出額の平均(栄養素ごとに対象食品を集計) |
| 母子・父子世帯率[%] | 母子・父子世帯数 ÷ (一般世帯数×10) |
| 人口1000人あたりの病院数[軒] | 一般病院数 ÷ 総人口 ×1000 |
この研究の1点は47都道府県の集計値どうしの相関であり、個人(自殺した人)のデータではない。「病院が少ない県ほど女性自殺率が高い」という県レベルの相関を、そのまま「病院に行けない個人が自殺しやすい」と読み替えると生態学的誤謬(ecological fallacy)に陥る危険がある。原論文自身も限界として明記している。
5分類の各指標と、男女別の自殺率との相関(Pearson の r)を算出する。原論文は 相関係数 の絶対値が 0.2 を超えたものについて無相関の検定(p値)を行い、有意水準5%で有意だったものに * を付けた。下表は原論文 表6〜10 の報告値を1枚にまとめたものである。
| 要因分類 | 指標 | 男性自殺率との r | 女性自殺率との r |
|---|---|---|---|
| 自然環境 | 降水日数 | 0.1892666 | -0.2720383 |
| 降水量 | -0.1264948 | -0.3876141 * | |
| 森林・人工林率 | 0.2891686 | -0.1450716 | |
| 社会的 | 平均月収 | -0.3681953 * | 0.2598133 |
| 最低賃金 | -0.4985958 * | 0.2394296 | |
| 人口密度 | -0.3484553 * | 0.1531512 | |
| 教師一人あたり生徒数 | -0.3917334 * | 0.2162066 | |
| 完全失業率 | 0.0864754 | 0.032204 | |
| 食生活 | カルシウム | -0.124765 | 0.3667838 * |
| ビタミンD | -0.1002074 | 0.0520631 | |
| ビタミンA | -0.22498 | 0.2489419 | |
| 酒類 | -0.3887164 * | 0.0198852 | |
| 身辺事情 | 離婚率 | -0.0933102 | -0.0250456 |
| 父子・母子世帯率 | 0.2260748 | -0.2988605 * | |
| 入院患者率 | 0.1125827 | -0.332586 * | |
| 外来患者率 | -0.0273847 | -0.2530422 | |
| 生活行動 | 学業 | -0.2988691 * | -0.0770282 |
| 仕事 | 0.2714662 | -0.0867027 | |
| 介護関係 | 0.0093135 | -0.1951387 | |
| 趣味・娯楽の総数 | -0.5175879 * | 0.2080845 | |
| スポーツ | -0.560301 * | 0.1939965 | |
| 睡眠 | 0.6107483 * | -0.0696166 | |
| 休養・くつろぎ | 0.2736665 | -0.1304227 | |
| 旅行・行楽 | -0.4192268 * | 0.2343289 |
* … 無相関の検定で有意(p<0.05)。値はすべて原論文の報告値。
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import os import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 FIG_DIR = 'html/figures' os.makedirs(FIG_DIR, exist_ok=True) # すべての図に添える注記(本ページの図はすべて報告値の可視化) NOTE = '※原論文(河又杏香 2021)の報告値の可視化であり、本スクリプトで再計算した値ではない。' print('セットアップ完了。図の出力先:', FIG_DIR) |
セットアップ完了。図の出力先: html/figures
plt・pd・np と保存先 FIG_DIR、全図共通の注記 NOTE をここで定義する。html/figures に図が書き出される。34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | # ── 原論文 表6〜10:男女別・要因別の自殺率との相関係数(報告値の転記)── # 「男性有意」「女性有意」= 原論文で * が付されたもの(|r|>0.2 かつ p<0.05) rows = [ # (指標, 要因分類, 男性r, 女性r, 男性有意, 女性有意) ('降水日数', '自然環境', 0.1892666, -0.2720383, False, False), ('降水量', '自然環境', -0.1264948, -0.3876141, False, True), ('森林・人工林率', '自然環境', 0.2891686, -0.1450716, False, False), ('平均月収', '社会的', -0.3681953, 0.2598133, True, False), ('最低賃金', '社会的', -0.4985958, 0.2394296, True, False), ('人口密度', '社会的', -0.3484553, 0.1531512, True, False), ('教師一人あたり生徒数','社会的', -0.3917334, 0.2162066, True, False), ('完全失業率', '社会的', 0.08647537, 0.03220396, False, False), ('カルシウム', '食生活', -0.124765, 0.3667838, False, True), ('ビタミンD', '食生活', -0.1002074, 0.05206311,False, False), ('ビタミンA', '食生活', -0.22498, 0.2489419, False, False), ('酒類', '食生活', -0.3887164, 0.01988522,True, False), ('離婚率', '身辺事情', -0.09331021, -0.02504564,False, False), ('父子・母子世帯率', '身辺事情', 0.2260748, -0.2988605, False, True), ('入院患者率', '身辺事情', 0.1125827, -0.332586, False, True), ('外来患者率', '身辺事情', -0.0273847, -0.2530422, False, False), ('学業', '生活行動', -0.2988691, -0.07702816,True, False), ('仕事', '生活行動', 0.2714662, -0.08670267,False, False), ('介護関係', '生活行動', 0.009313488,-0.1951387, False, False), ('趣味・娯楽の総数', '生活行動', -0.5175879, 0.2080845, True, False), ('スポーツ', '生活行動', -0.560301, 0.1939965, True, False), ('睡眠', '生活行動', 0.6107483, -0.06961662,True, False), ('休養・くつろぎ', '生活行動', 0.2736665, -0.1304227, False, False), ('旅行・行楽', '生活行動', -0.4192268, 0.2343289, True, False), ] rep = pd.DataFrame(rows, columns=['指標','要因分類','男性','女性','男性有意','女性有意']) print('報告された相関係数(24指標):') print(rep[['要因分類','指標','男性','女性']].to_string(index=False)) print() print('有意(p<0.05)な指標数 — 男性:', int(rep['男性有意'].sum()), ' 女性:', int(rep['女性有意'].sum())) |
報告された相関係数(24指標): 要因分類 指標 男性 女性 自然環境 降水日数 0.189267 -0.272038 自然環境 降水量 -0.126495 -0.387614 自然環境 森林・人工林率 0.289169 -0.145072 社会的 平均月収 -0.368195 0.259813 社会的 最低賃金 -0.498596 0.239430 社会的 人口密度 -0.348455 0.153151 社会的 教師一人あたり生徒数 -0.391733 0.216207 社会的 完全失業率 0.086475 0.032204 食生活 カルシウム -0.124765 0.366784 食生活 ビタミンD -0.100207 0.052063 食生活 ビタミンA -0.224980 0.248942 食生活 酒類 -0.388716 0.019885 身辺事情 離婚率 -0.093310 -0.025046 身辺事情 父子・母子世帯率 0.226075 -0.298860 身辺事情 入院患者率 0.112583 -0.332586 身辺事情 外来患者率 -0.027385 -0.253042 生活行動 学業 -0.298869 -0.077028 生活行動 仕事 0.271466 -0.086703 生活行動 介護関係 0.009313 -0.195139 生活行動 趣味・娯楽の総数 -0.517588 0.208085 生活行動 スポーツ -0.560301 0.193996 生活行動 睡眠 0.610748 -0.069617 生活行動 休養・くつろぎ 0.273666 -0.130423 生活行動 旅行・行楽 -0.419227 0.234329 有意(p<0.05)な指標数 — 男性: 10 女性: 4
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # ── 図1:24指標×男女別の相関係数(表6〜10の報告値)── order = rep.iloc[::-1].reset_index(drop=True) # 上から降水日数になるよう逆順 y = np.arange(len(order)) fig, axes = plt.subplots(1, 2, figsize=(13, 10), sharey=True) for ax, sex in zip(axes, ['男性', '女性']): vals = order[sex].values sig = order[sex + '有意'].values colors = [] for v, s in zip(vals, sig): if s: colors.append('#C62828' if v >= 0 else '#1565C0') # 濃色=有意 else: colors.append('#EF9A9A' if v >= 0 else '#90CAF9') # 淡色=非有意 ax.barh(y, vals, color=colors, edgecolor='white') ax.axvline(0, color='#333', lw=1.1) ax.axvline(0.2, color='#bbb', ls=':', lw=0.8) ax.axvline(-0.2, color='#bbb', ls=':', lw=0.8) ax.set_xlim(-0.72, 0.72) ax.set_title('%s自殺率との相関' % sex, fontsize=13, fontweight='bold') ax.set_xlabel('相関係数 r(報告値)', fontsize=11) for yi, (v, s) in enumerate(zip(vals, sig)): if s: ax.text(v + (0.02 if v >= 0 else -0.02), yi, '*', va='center', ha='left' if v >= 0 else 'right', fontsize=15, fontweight='bold', color='#222') ax.grid(True, axis='x', alpha=0.25) axes[0].set_yticks(y) axes[0].set_yticklabels(order['指標'].tolist(), fontsize=10) fig.suptitle('図1 5要因24指標と自殺率の相関係数(原論文 表6〜10 の報告値の可視化)', fontsize=14, fontweight='bold') fig.text(0.5, 0.005, NOTE + ' 濃色=有意(p<0.05, *)、淡色=非有意。点線は|r|=0.2。', ha='center', fontsize=9, color='#B71C1C') fig.tight_layout(rect=[0, 0.035, 1, 0.965]) fig.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig1.png'), bbox_inches='tight') plt.close(fig) male_sig = rep.loc[rep['男性有意'], '指標'].tolist() female_sig = rep.loc[rep['女性有意'], '指標'].tolist() print('fig1 saved') print('男性で有意:', '、'.join(male_sig)) print('女性で有意:', '、'.join(female_sig)) |
fig1 saved 男性で有意: 平均月収、最低賃金、人口密度、教師一人あたり生徒数、酒類、学業、趣味・娯楽の総数、スポーツ、睡眠、旅行・行楽 女性で有意: 降水量、カルシウム、父子・母子世帯率、入院患者率
rep を横棒グラフで可視化し、男女で相関の向き・強さが違うことを一目で見せる。男性で有意だった指標の中には、実は別の変数を介した見かけの相関(疑似相関)が混ざっている可能性がある。原論文は、労働の対価を表す最低賃金と、その背景にある人口密度のどちらかの影響を取り除いた偏相関係数を計算し、真の関連かどうかを判定した(表11・表12)。
| 指標 | 除去した変数 | 単純相関 r | 偏相関 r | 判定(|偏相関|>0.2) |
|---|---|---|---|---|
| 森林・人工林率 | 人口密度 | 0.2892 | 0.0907 | 疑似相関 |
| 教師一人あたり生徒数 | 人口密度 | -0.3917 | -0.2357 | 真の相関 |
| 最低賃金 | 人口密度 | -0.4986 | -0.3938 | 真の相関 |
| 平均月収 | 最低賃金 | -0.3682 | 0.0907 | 疑似相関 |
| 人口密度 | 最低賃金 | -0.3485 | -0.1101 | 疑似相関 |
| 酒類 | 最低賃金 | -0.3887 | -0.1682 | 疑似相関 |
| 学業 | 最低賃金 | -0.2989 | -0.2637 | 真の相関 |
| 趣味・娯楽の総数 | 最低賃金 | -0.5176 | -0.2218 | 真の相関 |
| スポーツ | 最低賃金 | -0.5603 | -0.3359 | 真の相関 |
| 睡眠 | 最低賃金 | 0.6107 | 0.4311 | 真の相関 |
| 旅行・行楽 | 最低賃金 | -0.4192 | -0.1382 | 疑似相関 |
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # ── 図2:男性自殺率の単純相関 vs 偏相関(原論文 表7・11・12)── # 最低賃金または人口密度の影響を除去した偏相関で疑似相関を判定する mp = pd.DataFrame([ ('森林・人工林率', '人口密度', 0.2891686, 0.09068578), ('教師一人あたり生徒数','人口密度', -0.3917334, -0.2357294), ('最低賃金', '人口密度', -0.4985958, -0.3938469), ('平均月収', '最低賃金', -0.3681953, 0.09068578), ('人口密度', '最低賃金', -0.3484553, -0.1100749), ('酒類', '最低賃金', -0.3887164, -0.1681852), ('学業', '最低賃金', -0.2988691, -0.2637391), ('趣味・娯楽の総数', '最低賃金', -0.5175879, -0.2218496), ('スポーツ', '最低賃金', -0.560301, -0.3359372), ('睡眠', '最低賃金', 0.6107483, 0.4310617), ('旅行・行楽', '最低賃金', -0.4192268, -0.1382047), ], columns=['指標','除去変数','単純相関','偏相関']) mp['真の相関'] = mp['偏相関'].abs() > 0.2 # |偏相関|>0.2 は疑似相関でない fig, ax = plt.subplots(figsize=(11, 8.5)) yy = np.arange(len(mp))[::-1] h = 0.38 ax.barh(yy + h/2, mp['単純相関'], height=h, color='#B0BEC5', label='単純相関 r') pcol = ['#2E7D32' if t else '#C62828' for t in mp['真の相関']] ax.barh(yy - h/2, mp['偏相関'], height=h, color=pcol) ax.axvline(0, color='#333', lw=1.1) ax.axvline(0.2, color='#bbb', ls=':', lw=0.8); ax.axvline(-0.2, color='#bbb', ls=':', lw=0.8) ax.set_yticks(yy) ax.set_yticklabels(['%s\n(除去: %s)' % (i, r) for i, r in zip(mp['指標'], mp['除去変数'])], fontsize=9) ax.set_xlabel('相関係数 / 偏相関係数(報告値)', fontsize=11) ax.set_xlim(-0.72, 0.72) handles = [mpatches.Patch(color='#B0BEC5', label='単純相関 r'), mpatches.Patch(color='#2E7D32', label='偏相関(|r|>0.2:疑似相関でない)'), mpatches.Patch(color='#C62828', label='偏相関(|r|≦0.2:疑似相関)')] ax.legend(handles=handles, loc='lower left', fontsize=9, framealpha=0.9) ax.set_title('図2 男性自殺率:単純相関と偏相関の比較(原論文 表7・11・12 の報告値)', fontsize=12.5, fontweight='bold') ax.grid(True, axis='x', alpha=0.25) fig.text(0.5, 0.005, NOTE, ha='center', fontsize=9, color='#B71C1C') fig.tight_layout(rect=[0, 0.03, 1, 1]) fig.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig2.png'), bbox_inches='tight') plt.close(fig) survive = mp.loc[mp['真の相関'], '指標'].tolist() pseudo = mp.loc[~mp['真の相関'], '指標'].tolist() print('fig2 saved') print('偏相関でも |r|>0.2(疑似相関でない):', '、'.join(survive)) print('偏相関で |r|≦0.2(疑似相関と判定):', '、'.join(pseudo)) print('人口密度と最低賃金の相関 r = 0.8108688(強い正の相関・報告値)') |
fig2 saved 偏相関でも |r|>0.2(疑似相関でない): 教師一人あたり生徒数、最低賃金、学業、趣味・娯楽の総数、スポーツ、睡眠 偏相関で |r|≦0.2(疑似相関と判定): 森林・人工林率、平均月収、人口密度、酒類、旅行・行楽 人口密度と最低賃金の相関 r = 0.8108688(強い正の相関・報告値)
原論文はさらに、人口密度を横軸・最低賃金を縦軸にとった散布図に回帰直線を引き、各都道府県が回帰直線の上側(人口密度の割に賃金が高い=労働の対価が相対的に大きい)か下側(賃金が低い=対価が小さい)かを調べた。男性自殺率の低い上位10県は回帰直線より上側、高い上位10県は下側に多く位置した。
| 順位 | 自殺率が低い順 | 自殺率が高い順 |
|---|---|---|
| 1位 | 神奈川県 | 秋田県 |
| 2位 | 愛知県 | 山形県 |
| 3位 | 大分県 | 沖縄県 |
| 4位 | 山梨県 | 島根県 |
| 5位 | 福井県 | 岩手県 |
| 6位 | 兵庫県 | 宮崎県 |
| 7位 | 奈良県 | 福島県 |
| 8位 | 東京都 | 熊本県 |
| 9位 | 京都府 | 群馬県 |
| 10位 | 高知県 | 新潟県 |
女性で有意だった4指標(降水量・カルシウム・父子母子世帯率・入院患者率)は、いずれも当初の仮説と符号が一致しなかった。原論文は「入院患者率が低い県ほど自殺率が高い」ことに注目し、そもそも病院が足りず受診できないのではという仮説を立て、新たに人口1000人あたりの病院数という指標を追加した。
| 指標 | 単純相関 r | 偏相関 r(病院数を除去) | 判定 |
|---|---|---|---|
| 降水量 | -0.3876 | -0.2364 | 真の相関 |
| カルシウム | 0.3668 | 0.1793 | 疑似相関 |
| 母子・父子世帯率 | -0.2989 | -0.1150 | 疑似相関 |
| 入院患者率 | -0.3326 | 0.0609 | 疑似相関 |
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | # ── 図3:女性自殺率の単純相関 vs 偏相関(病院数の影響を除去・原論文 表9・15)── byoin_r, byoin_p = -0.3854302, 0.00746 # 人口千人あたり病院数×女性自殺率(追加指標) fp = pd.DataFrame([ ('降水量', -0.3876141, -0.2364077), ('カルシウム', 0.3667838, 0.1793106), ('母子・父子世帯率', -0.2988605, -0.1149966), ('入院患者率', -0.332586, 0.06085137), ], columns=['指標','単純相関','偏相関']) fp['真の相関'] = fp['偏相関'].abs() > 0.2 fig, ax = plt.subplots(figsize=(11, 6)) yy = np.arange(len(fp))[::-1] h = 0.38 ax.barh(yy + h/2, fp['単純相関'], height=h, color='#B0BEC5', label='単純相関 r') pcol = ['#2E7D32' if t else '#C62828' for t in fp['真の相関']] ax.barh(yy - h/2, fp['偏相関'], height=h, color=pcol) # 追加指標:人口千人あたり病院数(除去に使用した変数自身) ax.barh([len(fp) + 0.2], [byoin_r], height=0.5, color='#6A1B9A') ax.text(byoin_r - 0.02, len(fp) + 0.2, 'r=%.3f\np=%.5f' % (byoin_r, byoin_p), va='center', ha='right', fontsize=9, color='#4A148C') ax.axvline(0, color='#333', lw=1.1) ax.axvline(0.2, color='#bbb', ls=':', lw=0.8); ax.axvline(-0.2, color='#bbb', ls=':', lw=0.8) labels = fp['指標'].tolist() ax.set_yticks(list(yy) + [len(fp) + 0.2]) ax.set_yticklabels(labels + ['人口千人あたり病院数(追加・除去に使用)'], fontsize=9) ax.set_xlabel('相関係数 / 偏相関係数(報告値)', fontsize=11) ax.set_xlim(-0.62, 0.62) handles = [mpatches.Patch(color='#B0BEC5', label='単純相関 r'), mpatches.Patch(color='#2E7D32', label='偏相関(|r|>0.2)'), mpatches.Patch(color='#C62828', label='偏相関(|r|≦0.2:疑似相関)'), mpatches.Patch(color='#6A1B9A', label='追加指標:病院数×女性自殺率')] ax.legend(handles=handles, loc='lower left', fontsize=9, framealpha=0.9) ax.set_title('図3 女性自殺率:単純相関と偏相関(病院数の影響を除去)(原論文 表9・15 の報告値)', fontsize=11.5, fontweight='bold') ax.grid(True, axis='x', alpha=0.25) fig.text(0.5, 0.005, NOTE, ha='center', fontsize=9, color='#B71C1C') fig.tight_layout(rect=[0, 0.04, 1, 1]) fig.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig3.png'), bbox_inches='tight') plt.close(fig) print('fig3 saved') print('人口千人あたり病院数×女性自殺率: r=%.4f, p=%.5f(有意)' % (byoin_r, byoin_p)) print('病院数除去後に |r|>0.2 が残ったのは:', '、'.join(fp.loc[fp['真の相関'], '指標'].tolist())) |
fig3 saved 人口千人あたり病院数×女性自殺率: r=-0.3854, p=0.00746(有意) 病院数除去後に |r|>0.2 が残ったのは: 降水量
原論文は結論を述べる前に、次の限界を自ら挙げている。統計教育の観点でも重要な指摘である。
都道府県は47しかなく、相関係数の推定は不安定になりやすい。地域の数値をそのまま結果と結びつけることには慎重さが必要。
|r|>0.2 で「関連あり」と判定しているため、得られた相関の多くは弱い。強い相関は得られていない。
個人ではなく地域指標を用いており、指標が相互に影響し合うため、相関係数という数字だけで安易に判断しにくい。偏相関でも取り除けない別の変数の関与が残りうる。
本分析はあくまで関連の強さを示すもので、因果関係を証明したものではない。
原論文は SSDSE-A/B/C/D の複数データを組み合わせて男女別の自殺の背景要因を探索しました。自殺データ(厚労省)は SSDSE に無いため、原論文が使った SSDSE-D の生活時間・行動データの分析を再現します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | d_raw = pd.read_csv('data/raw/SSDSE-D-2023.csv', encoding='cp932', header=1) d_raw = d_raw[(d_raw['男女の別'] == '0_総数') & (d_raw['地域コード'] != 'R00000')] d = d_raw.set_index('都道府県') dv = lambda c: pd.to_numeric(d[c], errors='coerce') b_raw = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) b = b_raw[(b_raw['年度'] == 2021) & b_raw['地域コード'].str.match(r'^R\d{5}$', na=False)].set_index('都道府県') bv = lambda c: pd.to_numeric(b[c], errors='coerce') sleep = dv('睡眠') hobby = dv('趣味・娯楽の総数') divorce = bv('離婚件数') / bv('総人口') * 1000 r1, p1 = stats.pearsonr(sleep, divorce.reindex(sleep.index)) r2, p2 = stats.pearsonr(hobby, divorce.reindex(hobby.index)) print(f'睡眠時間 × 人口千対離婚件数 : r = {r1:+.3f} (p={p1:.4f})') print(f'趣味・娯楽行動者率 × 離婚件数: r = {r2:+.3f} (p={p2:.4f})') print('趣味・娯楽行動者率 下位5県:', '、'.join(hobby.nsmallest(5).index)) |
男女別に相関分析・無相関の検定・偏相関による疑似相関の検討を重ねた結果、原論文は次のように結論づけた。
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | # ── 図4:男女で異なる自殺の関連要因(有意な相関のまとめ・報告値)── theme = { '平均月収':'経済・労働', '最低賃金':'経済・労働', '人口密度':'経済・労働', '教師一人あたり生徒数':'経済・労働', '学業':'生活行動', '趣味・娯楽の総数':'生活行動', 'スポーツ':'生活行動', '睡眠':'生活行動', '旅行・行楽':'生活行動', '酒類':'食生活', 'カルシウム':'食生活', '降水量':'自然環境', '入院患者率':'健康・医療', '父子・母子世帯率':'健康・医療', '人口千人あたり病院数':'健康・医療', } tcol = {'経済・労働':'#1565C0', '生活行動':'#2E7D32', '食生活':'#E65100', '自然環境':'#607D8B', '健康・医療':'#C62828'} m = rep[rep['男性有意']][['指標','男性']].rename(columns={'男性':'r'}).copy() w = rep[rep['女性有意']][['指標','女性']].rename(columns={'女性':'r'}).copy() w = pd.concat([w, pd.DataFrame([{'指標':'人口千人あたり病院数','r':-0.3854302}])], ignore_index=True) for d in (m, w): d.sort_values('r', inplace=True) d.reset_index(drop=True, inplace=True) fig, axes = plt.subplots(1, 2, figsize=(13, 6)) for ax, d, ttl in zip(axes, (m, w), ('男性で有意な相関', '女性で有意な相関')): yy = np.arange(len(d)) cols = [tcol.get(theme.get(i, '自然環境'), '#999') for i in d['指標']] ax.barh(yy, d['r'], color=cols, edgecolor='white') ax.axvline(0, color='#333', lw=1.1) ax.set_yticks(yy); ax.set_yticklabels(d['指標'].tolist(), fontsize=10) ax.set_xlim(-0.65, 0.65) ax.set_xlabel('相関係数 r(報告値)', fontsize=11) ax.set_title(ttl, fontsize=13, fontweight='bold') ax.grid(True, axis='x', alpha=0.25) handles = [mpatches.Patch(color=c, label=k) for k, c in tcol.items()] fig.legend(handles=handles, loc='lower center', ncol=5, fontsize=9, framealpha=0.9, bbox_to_anchor=(0.5, -0.02)) fig.suptitle('図4 男女で異なる自殺の関連要因(有意な相関のまとめ・報告値)', fontsize=14, fontweight='bold') fig.text(0.5, -0.06, NOTE, ha='center', fontsize=9, color='#B71C1C') fig.tight_layout(rect=[0, 0.02, 1, 0.96]) fig.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig4.png'), bbox_inches='tight') plt.close(fig) print('fig4 saved') print('男性側:経済・労働系と生活行動系が中心') print('女性側:健康・医療系(病院数・入院患者率)が中心') |
fig4 saved 男性側:経済・労働系と生活行動系が中心 女性側:健康・医療系(病院数・入院患者率)が中心
本ページの図は「報告値の可視化」なので、SSDSE のダウンロードは不要です。原論文の相関係数がスクリプト内に転記されており、そのまま実行すると図が再生成されます。
html/figures/ に保存されます。相関分析・偏相関・無相関の検定は、研究だけでなく行政・医療・報道の現場で広く使われています。
この論文を読むときに初心者がやりがちな勘違いをまとめます。
本文で見慣れない言葉が出てきたら、ここに戻って確認してください。
この論文で使われている手法を「何のためか」「結果をどう読むか」「注意点」に分けて解説します。なお本論文のデータは、独立行政法人統計センターが提供する教育用標準データセット(SSDSE)と各府省の官庁統計を組み合わせています。
この研究を発展させる3つの方向です。
手を動かすのが最強の学習です。付属スクリプトをベースに挑戦してください。
2021_H5_1_shorei.py を実行し、図1〜4を再生成してください。初心者が抱きやすい疑問に、教育的観点から答えます。
この論文を理解できたか、クリックで確認しましょう。間違えても解説が出ます。
このページの分析は、この画面の中でそのまま実行できます。
Python をインストールする必要も、CSV をダウンロードする必要もありません。
下のセルの 「▶ ブラウザで実行」 を上から順に押すか、
「▶ 最初から全部実行」 で一気に流してください。
表示されるのは、本文の図表とまったく同じ計算の結果です
(動かしているのは再現スクリプト code/2021_H5_1_shorei.py そのもの)。
コードは書き換えられます。「✏️ 書き換える」で数字や変数を変えて ▶ を押すと、 結果がどう変わるかをその場で確かめられます(元に戻すボタンつき)。 ページを開いた時点で裏で実行環境の準備が始まっているので、待ち時間はほとんどありません。 初回だけ実行環境の取得にインターネット接続が必要です。