この教材は、原論文が使ったデータそのものを使えていません。そこで代わりのデータで同じ問いを追いかけ、結論の向き(増える/減る、強い/弱い)が原論文と一致するかを確かめます。「同じ数値が出る」ことは目標にしていません。
| 原論文が使ったデータ | SSDSE-C・SSDSE-2020B・SSDSE-D・e-Stat 分析単位:都道府県 中核手法:相関分析・重回帰分析 |
|---|---|
| この教材が使うデータ | CSV は読み込まない(原論文が報告した数値をそのまま図表化して読み解く) |
| 原論文(PDF) | 健康寿命の延伸に向けて 優秀賞/太佐 美結(フェリス女学院高等学校) |
原論文と同じ粒度のデータは、この教材にも同梱しています。これを読み込めば、原論文と同じ細かさで分析をやり直せます(下の「🐍 ブラウザで動かす」でコードを書き換えて試せます)。ただし原論文が使った項目がすべて収録されているとは限りません。足りない項目は、上の「できないこと」に書いた出典から取ってくる必要があります。
▶ ここに書いてある分析は、ページ下部の「🐍 ブラウザで動かす」でそのまま実行できます(インストール不要)。動かしているのは code/2021_H2_yushu.py(190 行)そのものです。
このページの4枚の図は原論文の報告値を可視化したものなので、外部データのダウンロードは不要です。付属スクリプトには数値が直接書き込まれており、そのまま実行すれば同じ図が得られます。
html/figures/ に保存されます(外部CSV不要)。
2016年の日本の男女平均寿命は 84.2歳で世界一の長寿国となった。しかし「寿命」は誕生から死亡までの期間であり、その中には介護などで日常生活が制限される期間も含まれる。WHO が提唱した健康寿命——「日常的に介護を必要としないで、自立した生活ができる生存期間」——をどれだけ延ばせるかが重要になっている。
国内で見ると、平均寿命が長いのは長野県・滋賀県、短いのは青森県で、男性では約 3.11年の差がある。一方、健康寿命が長いのは愛知県や山梨県などで、奈良県や京都府のように平均寿命が長くても健康寿命は比較的短い県もある。
本研究は次の8手順で進められた(原論文 図1 のフローチャート。フロー図そのものは原論文参照)。
| 手順 | 内容 |
|---|---|
| 手順1 | 男女別に、各都道府県の健康寿命と平均寿命の相関係数を確認する。 |
| 手順2 | 健康寿命に影響しそうな要因を『社会制度』『運動』『生活』『休息・余暇』『栄養・食生活』『気候』の観点から選定する。 |
| 手順3 | 『栄養・食生活』は SSDSE-C(家計消費データ)を用い、因子分析で食生活の指標を抽出する。 |
| 手順4 | 箱ひげ図で外れ値を特定し、除外すべきか(都道府県の特徴を表す値か)を検討する。 |
| 手順5 | 同一グループ内の説明変数間で相関を算出し、|r|≥0.7 なら健康寿命との相関が高い方を残す(多重共線性対策)。 |
| 手順6 | 選定した説明変数で重回帰分析を実施する。 |
| 手順7 | 重回帰式の精度(決定係数)・P値・残差を評価する。 |
| 手順8 | 妥当性が確認された後、健康寿命に影響する要因を考察し、延伸のための対策を提案する。 |
健康寿命に影響しそうな要因を6つの観点で洗い出した(原論文 図2 の特性要因図。図そのものは原論文参照)。
| 観点 | 含まれる要因の例 |
|---|---|
| 社会制度 | 医療(病院数・歯科診療所数・健康診断受診率)、育児、学習機会、図書館・博物館、高齢者学級 |
| 運動 | 通勤・通学、交通の発展度、1日の歩数、日常の運動機会、公園・スポーツ施設 |
| 生活 | 同世代・異世代交流、高齢者就業率、家族形態、未婚率・離婚率、ボランティア活動 |
| 栄養・食生活 | 和食/洋食/麺類、飲酒、間食、糖分、油と塩分、野菜・果物(→ 因子分析へ) |
| 休息・余暇 | 睡眠時間、趣味・娯楽時間、外出時間、公民館数、喫煙、飲酒 |
| 気候 | 気温・降水量・積雪・日照時間(このうち日照時間のみ使用) |
目的変数は『男性健康寿命』『女性健康寿命』の2つ。健康寿命は e-Stat から得た「日常的に介護を必要としないで、自立した生活ができる生存期間」を用いた。説明変数は SSDSE を可能な限り活用し、足りないものは e-Stat や外部データで補った(原論文 表1)。
| 種別 | 主な出典 |
|---|---|
| 目的変数(健康寿命・平均寿命) | e-Stat |
| 社会制度・運動・生活・休息余暇の各指標 | SSDSE-2020B / SSDSE-D / e-Stat |
| がん検診受診率 | 国民生活基礎調査 / 国立がん研究センター がん対策情報センター |
| 家計消費データ(→因子分析) | SSDSE-2020C(都道府県庁所在市別・2017〜2019年の平均値) |
各変数を箱ひげ図で確認し、外れ値の発生原因を1つずつ検討した(原論文 図3。箱ひげ図は原論文参照)。特別な理由による外れ値(例:東京の飲食店の多さなど)は除外を検討し、都道府県の特徴を表す値は残した。「外れ値だから機械的に消す」のではなく、意味を吟味してから残す/除くを決めている点が本研究の丁寧なところ。
個々の食品の消費量ではなく「食生活の特徴」をつかむため、SSDSE-C の家計消費データに因子分析を適用した。分析には EXCEL 上の統計分析ソフト HAD を使用している。
| 因子分析の設定 | 内容 |
|---|---|
| 因子数 | 固有値が1以上となるものを抽出 |
| 抽出法 | 主成分法 |
| 回転法 | 斜交回転 |
7因子が抽出され、そのうち解釈できた5つに名前を付けた(原論文 図4 の因子負荷量プロットは原論文参照)。
| 因子 | 命名 | 負荷量が大きかった品目(原論文の記述) |
|---|---|---|
| 因子1 | 和食 | 野菜・海藻、梅干し・漬物、中華麺、魚介類、大豆製品、果物、米(+) |
| 因子2 | 外食とテイクアウト | 外食・調理食品・菓子類・喫茶代(+)、小麦粉・米・砂糖(−) |
| 因子3 | 洋食[逆符号] | パン・肉類(−) |
| 因子4 | 濃い味 | しょう油・砂糖・小麦粉・みそ(+) |
| 因子5 | 家での飲み物 | コーヒー(+)/緑茶(−) |
重回帰の予測を歪める多重共線性を避けるため、同一グループ内の説明変数間で相関を算出し、|r|≥0.7 の組があれば、健康寿命との相関が高い方だけを分析に用いた(原論文 表3 の相関行列)。
まず出発点として、健康寿命と平均寿命の順位が一致するかを男女別に確認した。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import os import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False FIG_DIR = 'html/figures' os.makedirs(FIG_DIR, exist_ok=True) # すべての図に付す注記:この教材の図は「報告値の可視化」であって再計算ではない NOTE = '※報告値の可視化(再計算ではない)/原論文の報告値' |
html/figures/ を用意し、すべての図に付ける注記文字列 NOTE(「報告値の可視化(再計算ではない)」)を準備しました。この一行が、本ページの図が原論文の数値を写して描いたものであることの宣言です。Hiragino Sans)を設定します。NOTE をあえて定数にしておき、4枚すべての図に同じ注記を焼き込みます。読み手が「これは再計算ではない」と一目で分かるようにするためです。plt.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存、plt.close() でメモリ解放。図を量産するときの定番です。14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # 原論文(PDF)から転記した報告値。ここでは新しい統計計算は一切行わない。 # 4.1 平均寿命と健康寿命の相関係数(図5の報告値) corr_life_health = {'男性': 0.38, '女性': -0.03} # 表5 標準化偏回帰係数(本文5.2で解釈された主要な説明変数) # (変数名, β, p値, 有意か[p<=0.1]) male_coefs = [ ('スポーツ全般行動者率(男性)', 0.989, 0.000, True), ('胃・大腸・肺がん検診受診率(男性)', 0.519, 0.005, True), ('65歳以上就業者割合', 0.428, 0.010, True), ('一般診療所数(10万人あたり)', -0.490, 0.010, True), ] female_coefs = [ ('老人クラブ会員数(65歳以上人口10万あたり)', 0.446, 0.105, False), ('家での飲み物(緑茶ほど負の指標)', -0.333, 0.048, True), ] # 表4 重回帰式の評価(決定係数とP値の報告値) model_eval = { '男性': {'r2': 0.785, 'p': 0.000}, '女性': {'r2': 0.490, 'p': 0.288}, } |
male_coefs / female_coefs は (変数名, β, p値, 有意か)の4つ組で、原論文の表5から転記しています。corr_life_health(図5)と model_eval(表4)も同様に報告値です。コードに書かれた 0.38 や 0.785 という数字は、すべて PDF に載っている値です。{'男性': 0.38} は辞書。d['男性'] でキーから値を引けます。表やCSVを介さず「紙の数値」をそのままコードに持てるのが便利です。37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | fig, ax = plt.subplots(figsize=(7, 5)) sexes = list(corr_life_health.keys()) rvals = [corr_life_health[s] for s in sexes] colors = ['#1565C0' if v >= 0.2 else '#9E9E9E' for v in rvals] ax.bar(sexes, rvals, color=colors, width=0.5, alpha=0.9) ax.axhline(0, color='black', lw=1.0) ax.set_ylabel('平均寿命と健康寿命の相関係数 r') ax.set_title('平均寿命と健康寿命の順位は一致するか') plt.savefig(FIG_DIR + '/2021_H2_fig1.png', bbox_inches='tight') plt.close() print('Figure 1 saved: 平均寿命と健康寿命の相関係数(報告値)') print(f' 男性 r = {corr_life_health["男性"]:.2f}(弱い正の相関)') print(f' 女性 r = {corr_life_health["女性"]:.2f}(相関は見られない)') |
Figure 1 saved: 平均寿命と健康寿命の相関係数(報告値) 男性 r = 0.38(弱い正の相関) 女性 r = -0.03(相関は見られない)
r=0.38(弱い正の相関)、女性は r=-0.03(ほぼ相関なし)。つまり平均寿命が長い県ほど健康寿命も長い、とは言えない。だからこそ「健康寿命に効く要因は平均寿命とは別に探す必要がある」という本研究の問いにつながります。[式 for x in リスト] はリスト内包表記。rvals = [d[s] for s in sexes] のように、辞書から欲しい値だけを1行で取り出せます。表3の相関で健康寿命との相関が |r|≥0.2 の要因を説明変数に選び、男女別に重回帰分析を行った。説明変数は標準化し、標準化偏回帰係数で影響の大きさを比較した。まず男性モデルの主要な係数を見る。
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | def plot_coefs(coef_list, title, fname): """標準化偏回帰係数(報告値)の水平バーを描く共通関数。""" names = [c[0] for c in coef_list] betas = [c[1] for c in coef_list] bar_colors = ['#C62828' if b < 0 else '#1565C0' for b in betas] fig, ax = plt.subplots(figsize=(9, 0.9 * len(names) + 1.8)) ax.barh(range(len(names)), betas, color=bar_colors, height=0.55) ax.axvline(0, color='black', lw=1.1) ax.set_yticks(range(len(names))) ax.set_yticklabels(names) ax.invert_yaxis() ax.set_xlabel('標準化偏回帰係数 β(報告値)') ax.set_title(title) plt.savefig(FIG_DIR + '/' + fname, bbox_inches='tight') plt.close() |
plot_coefs() を定義しました。負の係数は赤、正は青で塗り分けます。男性・女性それぞれの図(Figure 2・3)を、この1つの関数を呼び分けて作ります。ax.invert_yaxis() で、リストの上に書いた変数がグラフでも上に来るようにしています。色分け(正=青/負=赤)は、健康寿命への効果の向きを直感的に読めるようにするためです。def で関数化。引数を変えて呼ぶだけで重複が消え、修正も1か所で済みます。68 69 70 71 72 73 74 75 | plot_coefs( male_coefs, '男性の健康寿命を説明する要因(標準化偏回帰係数)\nR²=0.785, P=0.000', '2021_H2_fig2.png', ) print('Figure 2 saved: 男性 標準化偏回帰係数(報告値)') for name, b, p, s in male_coefs: print(f' {name}: β={b:+.3f}, p={p:.3f}') |
Figure 2 saved: 男性 標準化偏回帰係数(報告値) スポーツ全般行動者率(男性): β=+0.989, p=0.000 胃・大腸・肺がん検診受診率(男性): β=+0.519, p=0.005 65歳以上就業者割合: β=+0.428, p=0.010 一般診療所数(10万人あたり): β=-0.490, p=0.010
スポーツ全般行動者率 β=+0.989 が突出して大きい正の効果。がん検診受診率 +0.519・65歳以上就業者割合 +0.428 も正。一方 一般診療所数 −0.490 は負——「医療機関が多いほど健康」という直感と逆で、原論文は「予防を大切にする県ほど健康寿命が長い可能性」と解釈しています。f"{b:+.3f}" の + は符号を必ず表示、.3f は小数3桁。係数の正負をそろえて並べると読みやすくなります。次に女性モデル。有意な説明変数は「家での飲み物」(緑茶の指標)だけであった。
76 77 78 79 80 81 82 83 | plot_coefs( female_coefs, '女性の健康寿命を説明する要因(標準化偏回帰係数)\nR²=0.490, P=0.288', '2021_H2_fig3.png', ) print('Figure 3 saved: 女性 標準化偏回帰係数(報告値)') for name, b, p, s in female_coefs: print(f' {name}: β={b:+.3f}, p={p:.3f}') |
Figure 3 saved: 女性 標準化偏回帰係数(報告値) 老人クラブ会員数(65歳以上人口10万あたり): β=+0.446, p=0.105 家での飲み物(緑茶ほど負の指標): β=-0.333, p=0.048
家での飲み物 β=−0.333(p=0.048)だけ。この指標は因子分析由来で「値が小さいほど緑茶消費が多い」ため、緑茶をよく飲む県ほど女性の健康寿命が長いと読めます。老人クラブ会員数 +0.446 はやや正だが p=0.105 で有意ではありません。f"{b:+.3f}" の + は符号を必ず表示、.3f は小数3桁。係数の正負をそろえて並べると読みやすくなります。最後に、2つのモデルの妥当性(説明力と予測への有用性)を比べる。
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4.5)) sexes = list(model_eval.keys()) r2 = [model_eval[s]['r2'] for s in sexes] pv = [model_eval[s]['p'] for s in sexes] ax1.bar(sexes, r2, color=['#1565C0', '#9E9E9E'], width=0.5) ax1.set_title('決定係数 R²(説明力)') ax2.bar(sexes, pv, color=['#2E7D32', '#C62828'], width=0.5) ax2.axhline(0.05, color='#E65100', ls='--', label='有意水準 0.05') ax2.set_title('重回帰式のP値') plt.savefig(FIG_DIR + '/2021_H2_fig4.png', bbox_inches='tight') plt.close() print('Figure 4 saved: 重回帰式の評価(報告値)') print(f' 男性: R²={model_eval["男性"]["r2"]:.3f}, P={model_eval["男性"]["p"]:.3f} → 予測に役立つ') print(f' 女性: R²={model_eval["女性"]["r2"]:.3f}, P={model_eval["女性"]["p"]:.3f} → 役立つとは言えない') |
Figure 4 saved: 重回帰式の評価(報告値) 男性: R²=0.785, P=0.000 → 予測に役立つ 女性: R²=0.490, P=0.288 → 役立つとは言えない
plt.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存、plt.close() でメモリ解放。図を量産するときの定番です。P値が 0.1 以下の説明変数を「健康寿命に有意に関係する要因」とみなし、男女別に考察する(原論文 5.2)。
健康寿命に効きそうな要因を多角的に洗い出し、因子分析で食生活の指標を作り、男女別に重回帰分析を行うことで、健康寿命に関係する要因を導けた。要因は男女で異なり、男性はスポーツ行動、女性は緑茶などの食生活が関連した。
本論文で使われた3つの手法を、定義・使いどころ・つまずきやすい注意点で整理します。データは統計センター(独立行政法人統計センター)が公開する SSDSE(教育用標準データセット) などを用います。
この論文を読むときに陥りやすい誤解を、原論文の数値に沿って解きほぐします。
本論文の理解に必要な用語をまとめます。
この研究を一歩進めるアイデアです(原論文の今後の課題を含む)。
手を動かすほど理解が深まります。付属スクリプト(報告値の可視化)を土台に挑戦してみましょう。
python3 code/2021_H2_yushu.py を実行し、4枚の図が出ることを確認。各図がどの報告値から描かれているかをコードで辿る。male_coefs を β の絶対値順に並べ替えて描く。影響の大きい要因が上に来るように sorted() を使ってみる。factor_analyzer 等で実行。原論文の「和食」「濃い味」に近い因子が出るか確かめる。因子分析・相関・重回帰は、健康分野に限らず幅広い現場で使われています。
初学者が抱きやすい疑問に答えます。
この論文を理解できたか、クリックで確認しましょう。間違えても解説が出ます。
このページの分析は、この画面の中でそのまま実行できます。
Python をインストールする必要も、CSV をダウンロードする必要もありません。
下のセルの 「▶ ブラウザで実行」 を上から順に押すか、
「▶ 最初から全部実行」 で一気に流してください。
表示されるのは、本文の図表とまったく同じ計算の結果です
(動かしているのは再現スクリプト code/2021_H2_yushu.py そのもの)。
コードは書き換えられます。「✏️ 書き換える」で数字や変数を変えて ▶ を押すと、 結果がどう変わるかをその場で確かめられます(元に戻すボタンつき)。 ページを開いた時点で裏で実行環境の準備が始まっているので、待ち時間はほとんどありません。 初回だけ実行環境の取得にインターネット接続が必要です。