この教材は、元データが公開されていないため再計算ができません。原論文が論文中に報告した数値をたどって図表にし、「その数値からどこまで言えるか」を読み解く形で学びます。数値そのものは原論文からの引用であり、この教材が計算したものではありません。
| 原論文が使ったデータ | 論文本文からは特定できなかった 分析単位:その他 中核手法:偏相関分析・回帰分析・相関分析 |
|---|---|
| この教材が使うデータ | CSV は読み込まない(原論文が報告した数値をそのまま図表化して読み解く) |
| 原論文(PDF) | 気温と脳卒中の発症リスクについて 優秀賞/山野瑞起・岩見拓海・黒子風大・柏木創太(兵庫県立姫路西高等学校) |
▶ ここに書いてある分析は、ページ下部の「🐍 ブラウザで動かす」でそのまま実行できます(インストール不要)。動かしているのは code/2020_H2_yushu.py(224 行)そのものです。
このページに掲載した図は、原論文(PDF)が本文・表・図で報告した数値をそのまま可視化したものです。生データからの再計算ではありません。理由は以下のとおりです。
code/2020_H2_yushu.py は原論文の報告値を書き写して描画するだけなので、ダウンロード不要でそのまま実行できます。html/figures/ に保存されます。各図には「原論文の報告値の可視化(再計算ではない)」と明記しています。
日本人の死因のうち約半数は、がん・心疾患・脳卒中の三大疾病が占める。なかでも脳卒中(脳血管疾患)は発症後に障害が残ることが多く、原論文によれば2018年の死因の 8%(人口動態調査)を占める。
原論文の生徒たちは、脳卒中による死亡者数が冬(1月)に最も多く、夏(6月)に最も少ないという月別の傾向(人口動態調査2019)に着目した。ここから「脳卒中は気温という環境的要因で起こりうるのではないか」という問いが立てられている。
相関分析 偏相関分析 年齢調整死亡率 気候区分
| データ | 年度 | 出典 |
|---|---|---|
| 総人口・15歳未満・15〜64歳・65歳以上人口 | 2015 | SSDSE(独立行政法人統計センター) |
| 脳卒中による総死亡数 | 2012〜2019 | 人口動態調査(厚生労働省) |
| 日間平均気温・日間最高/最低気温 | 2011〜2019 | 過去の気象データ(気象庁) |
| 2人以上の世帯における床暖房普及率 | 2014 | 全国消費実態調査(総務省) |
| 指標名 | 計算方法 |
|---|---|
| 脳卒中死亡率(10万人対) | 年齢調整死亡率(下記)に10万を掛けた値 |
| 月間平均気温(℃) | 日間平均気温を月ごとに平均 |
| 月間平均最高・最低気温差(℃) | (日最高気温−日最低気温)を月ごとに平均した値 |
気温の変動の仕方が異なる地域のデータをとるため、気象庁の気候区分から各区分1都市ずつ、計9都市を選んだ。大病院の近さなどによる医療格差の影響を最小限にするため政令指定都市から選定し、政令指定都市がない四国は省略、九州南部は代わりに熊本市を選んでいる。
| 気候区分 | 都市 | 気候区分 | 都市 |
|---|---|---|---|
| 北海道 | 札幌市 | 近畿 | 大阪市 |
| 東北 | 仙台市 | 中国 | 広島市 |
| 関東甲信 | さいたま市 | 九州北部 | 福岡市 |
| 北陸 | 新潟市 | 九州南部 | 熊本市 |
| 東海 | 名古屋市 | (四国は政令指定都市がなく省略) | |
モデル都市ごとに年齢構成が異なると死亡率も影響を受けるため、人口を15歳未満・15〜64歳・65歳以上の3階級に分け、厚生労働省の方式で年齢調整を行っている。基準人口には昭和60年モデル人口を用いる。
本教材では、10万人あたりの年齢調整死亡率を単に「脳卒中死亡率」と呼ぶ(原論文の呼称に合わせる)。
| 変数 | 出典 | SSDSE収録 | この教材での扱い |
|---|---|---|---|
| 年齢階級別人口(2015) | SSDSE-A | ○ | 収録。ただし脳卒中死亡数の年齢別按分データがなく、年齢調整の再計算は不可 |
| 脳卒中死亡数 | 人口動態調査 | × | 原論文の報告値を可視化 |
| 日間平均・最高・最低気温 | 気象庁 | × | 原論文の報告値を可視化 |
| 床暖房普及率 | 全国消費実態調査 | × | 原論文の報告値を可視化 |
気温が下がると外気温と室温との差が大きくなり、ヒートショック(短時間の急激な温度変化による血圧の急変)が起きやすくなる——という考えから、月間平均気温と脳卒中死亡率には負の相関があると予想した。2019年1〜12月の各モデル都市のデータを用いて、都市ごとに相関係数を求めている。
| モデル都市 | 相関係数 | モデル都市 | 相関係数 |
|---|---|---|---|
| 札幌市 | −0.80 | 大阪市 | −0.66 |
| 仙台市 | −0.60 | 広島市 | −0.19 |
| 新潟市 | −0.43 | 福岡市 | −0.63 |
| さいたま市 | −0.72 | 熊本市 | −0.58 |
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import os import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import Patch 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 = '原論文の報告値の可視化(再計算ではない)' # ============================================================ # 原論文の報告値(PDF原本より転記。捏造なし) # ============================================================ |
matplotlib.use('Agg') は画面表示せず PNG に保存するための指定。NOTE には全図に添える「原論文の報告値の可視化(再計算ではない)」の注記を入れておきます。53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # ── 図1(原論文)2018年 日本人の死因割合(人口動態調査)────────── cause_labels = ['悪性新生物\n(がん) 27%', '心疾患 15%', '脳血管疾患\n(脳卒中) 8%', 'その他 49%'] cause_values = [27, 15, 8, 49] cause_colors = ['#4C72B0', '#2E5C9A', '#C62828', '#B0B0B0'] cause_explode = [0, 0, 0.10, 0] # ── 表4(原論文)各モデル都市の相関係数(月間平均気温×脳卒中死亡率, 2019年) # 北日本地域 = 札幌・仙台・新潟 corr_cities = ['札幌市', '仙台市', '新潟市', 'さいたま市', '大阪市', '広島市', '福岡市', '熊本市'] corr_values = [-0.80, -0.60, -0.43, -0.72, -0.66, -0.19, -0.63, -0.58] corr_is_north = [True, True, True, False, False, False, False, False] # ── 仮説3(原論文4.3節)相関・偏相関のまとめ ───────────────── # 気温×脳卒中(床暖房の影響を除く前の相関) : -0.33 # 気温×脳卒中(床暖房の影響を除いた後の偏相関) : -0.40(仮説に反し強まった) # 気温×床暖房普及率(相関) : -0.43 # 床暖房普及率×脳卒中(外気温の影響を除く偏相関) : -0.25(弱い負の相関, 1月) pcorr_labels = ['気温×脳卒中\n(床暖房を除く前)', '気温×脳卒中\n(床暖房を除いた後・偏相関)', '気温×床暖房\n普及率', '床暖房普及率×脳卒中\n(気温を除く偏相関・1月)'] pcorr_values = [-0.33, -0.40, -0.43, -0.25] pcorr_colors = ['#4C72B0', '#C62828', '#6A1B9A', '#2E7D32'] # ── 仮説の検証結果まとめ(原論文5節の解釈より)────────────── hypotheses = [ ('仮説1-1', '月間平均気温が低いほど脳卒中死亡率は高い', '支持', '8都市すべてで負の相関(表4)。ただし札幌市は例外的に死亡率が低い'), ('仮説1-2', '日較差(最高−最低気温差)が大きいほど死亡率は高い', '不支持', '札幌は負・仙台はほぼ無相関。1日の気温差は影響なし'), ('仮説2-1', '月間平均気温が低い年は死亡率が高い', '不支持', '各年1月で回帰直線がほぼ水平。年単位の絶対気温は無関係'), ('仮説2-2', '前年より気温が低い年は死亡率が高い', '不支持', '都市によりばらつき。一概には言えない'), ('仮説3-1', '床暖房普及率が高い都市ほど死亡率は低い', '支持(弱)', '外気温を除いた偏相関 −0.25。札幌の低さを説明'), ('仮説3-2', '床暖房を除くと気温と死亡率の相関は弱まる', '不支持', '偏相関は −0.33→−0.40 と逆に強化。室内要因を除いても相関は残る'), ] |
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # 図1: 2018年 日本人の死因割合(原論文 図1 の報告値) # ============================================================ fig1, ax1 = plt.subplots(figsize=(8, 7)) wedges, texts, autotexts = ax1.pie( cause_values, labels=cause_labels, colors=cause_colors, explode=cause_explode, startangle=90, counterclock=False, autopct='', textprops={'fontsize': 13}, wedgeprops={'edgecolor': 'white', 'linewidth': 1.5} ) ax1.set_title('図1:2018年 日本人の死因割合\n脳卒中(脳血管疾患)は全体の8%', fontsize=15, fontweight='bold', pad=18) ax1.text(0, -1.35, f'出典: 人口動態調査(2018年)/{NOTE}', ha='center', va='center', fontsize=10, color='#666') plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2020_H2_fig1.png'), dpi=150, bbox_inches='tight') plt.close() print('図1(死因割合)保存完了') |
ax.pie(...) で円グラフを描画。explode で脳卒中(脳血管疾患)のスライスだけ少し飛び出させて強調しています。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 | # 図2: 各モデル都市の相関係数(原論文 表4 の報告値) # ============================================================ fig2, ax2 = plt.subplots(figsize=(10, 6.5)) order = np.argsort(corr_values) # 強い負相関を上に cities_o = [corr_cities[i] for i in order] vals_o = [corr_values[i] for i in order] north_o = [corr_is_north[i] for i in order] colors_o = ['#C62828' if n else '#4C72B0' for n in north_o] y = np.arange(len(cities_o)) bars = ax2.barh(y, vals_o, color=colors_o, edgecolor='white', height=0.68) for yi, v in zip(y, vals_o): ax2.text(v - 0.02, yi, f'{v:.2f}', va='center', ha='right', fontsize=12, color='white', fontweight='bold') ax2.set_yticks(y) ax2.set_yticklabels(cities_o, fontsize=12) ax2.set_xlim(-0.9, 0.05) ax2.axvline(0, color='#333', lw=1) ax2.set_xlabel('相関係数(月間平均気温 × 脳卒中死亡率, 2019年)', fontsize=12) ax2.set_title('図2:各モデル都市の相関係数(原論文 表4)\nすべての都市で負の相関=気温が低いほど脳卒中死亡率は高い', fontsize=13, fontweight='bold') ax2.legend(handles=[Patch(facecolor='#C62828', label='北日本地域(札幌・仙台・新潟)'), Patch(facecolor='#4C72B0', label='その他の地域')], loc='lower left', fontsize=10, framealpha=0.9) ax2.grid(True, axis='x', alpha=0.3) ax2.text(0.99, 0.02, NOTE, transform=ax2.transAxes, ha='right', va='bottom', fontsize=9, color='#888', bbox=dict(boxstyle='round', facecolor='#F5F5F5', alpha=0.8)) plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2020_H2_fig2.png'), dpi=150, bbox_inches='tight') plt.close() print('図2(相関係数)保存完了') |
np.argsort で相関が強い(負に大きい)都市を上に並べ替えています。148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | # 図3: 偏相関分析の結果(原論文 4.3節 仮説3-1/3-2 の報告値) # ============================================================ fig3, ax3 = plt.subplots(figsize=(10, 6.5)) x = np.arange(len(pcorr_labels)) bars = ax3.bar(x, pcorr_values, color=pcorr_colors, edgecolor='white', width=0.6) for xi, v in zip(x, pcorr_values): ax3.text(xi, v - 0.02, f'{v:.2f}', ha='center', va='top', fontsize=13, color='white', fontweight='bold') ax3.set_xticks(x) ax3.set_xticklabels(pcorr_labels, fontsize=10.5) ax3.axhline(0, color='#333', lw=1) ax3.set_ylim(-0.55, 0.08) ax3.set_ylabel('(偏)相関係数', fontsize=12) ax3.set_title('図3:床暖房普及率を第3変数とした偏相関分析(原論文 4.3節)\n' '床暖房の影響を除くと相関は −0.33 → −0.40 とむしろ強まった(仮説に反する結果)', fontsize=12.5, fontweight='bold') # −0.33 → −0.40 の強化を示す矢印 ax3.annotate('', xy=(0.72, -0.40), xytext=(0.28, -0.33), arrowprops=dict(arrowstyle='->', color='#C62828', lw=2.2, connectionstyle='arc3,rad=-0.35')) ax3.text(2.5, -0.50, '室内要因(床暖房)を除いても、外気温と脳卒中死亡率の相関は残る', ha='center', va='center', fontsize=11, color='#C62828', fontweight='bold') ax3.grid(True, axis='y', alpha=0.3) ax3.text(0.99, 0.02, NOTE, transform=ax3.transAxes, ha='right', va='bottom', fontsize=9, color='#888', bbox=dict(boxstyle='round', facecolor='#F5F5F5', alpha=0.8)) plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2020_H2_fig3.png'), dpi=150, bbox_inches='tight') plt.close() print('図3(偏相関分析)保存完了') |
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | # 図4: 6つの仮説と検証結果のまとめ(原論文5節の解釈より) # ============================================================ fig4, ax4 = plt.subplots(figsize=(11, 6.5)) ax4.axis('off') verdict_color = {'支持': '#2E7D32', '支持(弱)': '#F9A825', '不支持': '#C62828'} n = len(hypotheses) row_h = 1.0 for i, (hid, desc, verdict, note) in enumerate(hypotheses): yy = (n - i - 1) * row_h ax4.add_patch(plt.Rectangle((0, yy + 0.06), 11, row_h - 0.12, facecolor='#F8F9FA' if i % 2 else '#FFFFFF', edgecolor='#DEE2E6', lw=0.8)) ax4.text(0.15, yy + row_h/2, hid, fontsize=12, fontweight='bold', va='center', ha='left', color='#333') ax4.text(1.35, yy + row_h/2, desc, fontsize=11, va='center', ha='left') ax4.add_patch(plt.Rectangle((7.05, yy + 0.22), 1.55, row_h - 0.44, facecolor=verdict_color[verdict], alpha=0.9)) ax4.text(7.82, yy + row_h/2, verdict, fontsize=11, fontweight='bold', va='center', ha='center', color='white') ax4.text(8.85, yy + row_h/2, note, fontsize=8.5, va='center', ha='left', color='#555') ax4.set_xlim(0, 11) ax4.set_ylim(-0.2, n * row_h + 0.6) ax4.text(0, n * row_h + 0.15, '図4:6つの仮説と検証結果のまとめ', fontsize=14, fontweight='bold', ha='left', color='#C62828') ax4.text(11, -0.15, NOTE, fontsize=9, color='#888', ha='right', va='top') plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2020_H2_fig4.png'), dpi=150, bbox_inches='tight') plt.close() print('図4(仮説まとめ)保存完了') # ============================================================ # コンソール出力(HTML埋め込み確認用) # ============================================================ print('\n=== 原論文の報告値(転記)===') print('■ 2018年 死因割合: 悪性新生物27% / 心疾患15% / 脳卒中8% / その他49%') print('■ 表4 相関係数(月間平均気温×脳卒中死亡率, 2019年)') for c, v, nth in zip(corr_cities, corr_values, corr_is_north): print(f' {c:<8} r = {v:+.2f} {"[北日本]" if nth else ""}') print('■ 仮説3の(偏)相関') for l, v in zip(['気温×脳卒中(除く前)', '気温×脳卒中(除いた後・偏相関)', '気温×床暖房普及率', '床暖房×脳卒中(気温除く偏相関・1月)'], pcorr_values): print(f' {l:<28} = {v:+.2f}') print('\n全図の生成が完了しました。') print(f'出力先: {os.path.abspath(FIG_DIR)}') |
図1(死因割合)保存完了 図2(相関係数)保存完了 図3(偏相関分析)保存完了 図4(仮説まとめ)保存完了 === 原論文の報告値(転記)=== ■ 2018年 死因割合: 悪性新生物27% / 心疾患15% / 脳卒中8% / その他49% ■ 表4 相関係数(月間平均気温×脳卒中死亡率, 2019年) 札幌市 r = -0.80 [北日本] 仙台市 r = -0.60 [北日本] 新潟市 r = -0.43 [北日本] さいたま市 r = -0.72 大阪市 r = -0.66 広島市 r = -0.19 福岡市 r = -0.63 熊本市 r = -0.58 ■ 仮説3の(偏)相関 気温×脳卒中(除く前) = -0.33 気温×脳卒中(除いた後・偏相関) = -0.40 気温×床暖房普及率 = -0.43 床暖房×脳卒中(気温除く偏相関・1月) = -0.25 全図の生成が完了しました。 出力先: /Users/matsumotoshimpei/Dropbox/Works_Researches/2026 統計・データ解析コンペ/html/figures
札幌市の例外をきっかけに、原論文は「気温のどの側面が効くのか」を切り分けるため、日較差・年単位の絶対気温・前年比の気温という3つの仮説を順に検証している。いずれも散布図(原論文 図5・図6・図7)で確認しているが、これらの数表は原論文に掲載されていないため、グラフは原論文を参照されたい。
| 仮説 | 内容と予想 | 結果 |
|---|---|---|
| 仮説1-2 | 月間平均の最高・最低気温差(日較差)が大きいほど死亡率は高い(正の相関を予想) | 不支持:札幌市は負、仙台市はほぼ無相関。1日の気温差は影響しない |
| 仮説2-1 | 月間平均気温が低い年は死亡率が高い(1月に絞り2012〜2019年で検証、負の相関を予想) | 不支持:どの都市でも回帰直線が横軸とほぼ平行で相関なし |
| 仮説2-2 | 前年に比べて気温が低い年は死亡率が高い(前年1月との気温差で検証、負の相関を予想) | 不支持:さいたま・福岡は負、仙台は正、札幌はほぼ変化なしと都市差が大きい |
仮説2-1・2-2 のように「予想した相関が見られなかった」結果は、失敗ではなく要因を絞り込むための重要な手がかりである。年単位の気温で説明できないと分かったからこそ、原論文は次に室温(床暖房)という別の要因へと考察を進められた。回帰直線が横軸と平行に近い=傾きがほぼ0=相関が弱い、という読み方も基本として押さえたい。
ヒートショックの発生には外気温だけでなく室温も関わる。暖房が完備された住宅では部屋ごとの室温差が小さくヒートショックが起こりにくい——と考え、原論文は床暖房普及率(2人以上世帯・全国消費実態調査2014)を取り上げて偏相関分析を行った。
外気温(月間平均気温)の影響を除いて、2019年1月の各都市データで偏相関分析を行ったところ、偏相関係数は −0.25 と弱い負の相関を示した。図の中では、同じ北日本地域でも札幌市は仙台市より床暖房普及率が高く、これが「札幌市の脳卒中死亡率が仙台市より大幅に低い」ことを説明する一因と考えられる。
月間平均気温と床暖房普及率の相関は −0.43(負の相関)であった。そこで床暖房普及率を第3変数として偏相関分析を行った結果は、原論文の予想に反するものだった。
| 気温と脳卒中死亡率の関係 | 係数 |
|---|---|
| 床暖房普及率の影響を除く前(相関係数) | −0.33 |
| 床暖房普及率の影響を除いた後(偏相関係数) | −0.40 |
偏相関は、注目する2変数(気温と死亡率)から第3の変数(床暖房普及率)の影響を統計的に取り除いたうえでの関係の強さを測る。第3変数が両者に効いて見かけの相関を作っている(交絡)場合、偏相関は元の相関より小さくなる。本研究では逆に大きくなったため、「気温→脳卒中の関係は床暖房では説明しきれない」と結論できる。
原論文の解釈(5節)を整理すると、次のようになる。
原論文は、気温差や暖房器具の普及率以外に「気温が低くなると脳卒中リスクが高まる」原因があると述べ、室温や防寒対策の程度など外気温以外の要素の関与を今後の検討課題としている。
| データ | 出典 | SSDSE収録 |
|---|---|---|
| 年齢階級別人口(2015) | 独立行政法人統計センター SSDSE-A | ○ |
| 脳卒中による総死亡数(2012〜2019) | 厚生労働省 人口動態調査 | × |
| 日間平均・最高・最低気温(2011〜2019) | 気象庁 過去の気象データ | × |
| 床暖房普及率(2014) | 総務省 全国消費実態調査 | × |
本スクリプトは原論文(PDF)の報告値を書き写して描画するもので、生データからの再計算ではありません。気象・疾患・床暖房のデータは SSDSE に未収録のため、各図には「原論文の報告値の可視化(再計算ではない)」と明記しています。新たな数値の捏造はしていません。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。
この論文を理解できたか、クリックで確認しましょう。間違えても解説が出ます。
このページの分析は、この画面の中でそのまま実行できます。
Python をインストールする必要も、CSV をダウンロードする必要もありません。
下のセルの 「▶ ブラウザで実行」 を上から順に押すか、
「▶ 最初から全部実行」 で一気に流してください。
表示されるのは、本文の図表とまったく同じ計算の結果です
(動かしているのは再現スクリプト code/2020_H2_yushu.py そのもの)。
コードは書き換えられます。「✏️ 書き換える」で数字や変数を変えて ▶ を押すと、 結果がどう変わるかをその場で確かめられます(元に戻すボタンつき)。 ページを開いた時点で裏で実行環境の準備が始まっているので、待ち時間はほとんどありません。 初回だけ実行環境の取得にインターネット接続が必要です。