論文一覧に戻る 🕸 論文ネットワーク 🗺 用語ネットワーク 統計データ分析コンペ 教育用再現集
2019年度(令和元年度) 統計データ分析コンペティション | 統計数理賞(大学生・一般の部)

マルチレベル分析を用いた
市町村大学等進学率の決定要因分析

⏱️ 推定読了時間: 約35分
松本 洋輔(一橋大学経済学部) | 手法:マルチレベル分析(ランダム切片モデル・ランダム切片傾きモデル) | データ:SSDSE・e-Stat 等(1304市町村×47都道府県の階層データ)
🔬 AIC/BIC🔬 マルチレベル分析🔬 ランダム切片・傾き🔬 級内相関(ICC)🏷 教育・学力
🔬 手法タグ / 🏷 応用タグ(クリックで同タグの論文をネットワーク検索)
🔬 再現カルテ — 原論文と同じデータ・同じ手法で再現(一部を除く)

この教材は原論文と同じデータを読み込み、同じ手順で計算し直しています。画面に出る数値と図は、あなたのブラウザがその場で計算した結果です。
⚠ ただし一部は再現していません:原論文 図1 の全国学力調査正答率は SSDSE に収録されていないため、 進学率×正答率の散布図(相関係数 0.226)は再現していません。 それ以外は同じデータで再計算しています。

原論文が使ったデータSSDSE-A・国勢調査報告(2015)・経済センサス-基礎調査(2014)・全国都道府県市区町村別面積調(2016)
分析単位:市区町村
中核手法:マルチレベル分析
この教材が使うデータ
原論文(PDF)マルチレベル分析を用いた市町村大学等進学率の決定要因分析
統計数理賞/松本 洋輔(一橋大学経済学部)
✅ この教材でできること
  • 分析に使うデータは同梱済みで、ブラウザ上でそのまま読み込める
突合監査の結果、主要データと中核手法はいずれも原論文と一致しています。

▶ ここに書いてある分析は、ページ下部の「🐍 ブラウザで動かす」でそのまま実行できます(インストール不要)。動かしているのは code/2019_U3_suri.py(235 行)そのものです。

🏅 論文審査会コメント(審査員はここを評価した)
「市町村大学進学率について、先行研究に基づき変数を選択し、マルチレベルモデルをよく理解した上で適用し、考察と共に一定の結果を導いており高く評価された。」
出典:統計センター「統計データ分析コンペティション」受賞論文PDF掲載の審査講評。プロの審査員が何を評価し、何を注文したかは論文の読み方の最良の手本になる。
📝 3行で分かる要約

目次

  1. 研究の背景:進学率の地域格差はなぜ生まれるか
  2. マルチレベル分析とは:なぜ普通の回帰ではダメなのか
  3. データと変数(SSDSE・e-Stat、1304市町村×47都道府県)
  4. 級内相関(ICC)の確認:都道府県要因は存在するか(図4)
  5. マルチレベル分析の結果(表7・図2)
  6. 都道府県要因はどこまで説明できたか(表8・図3)
  7. 考察:4つの発見と政策への含意
  8. まとめ:研究の強みと限界
  9. 📥 データの準備
  10. 💼 実社会での応用
  11. ⚠️ よくある誤解
  12. 📖 用語集
  13. 📐 手法ガイド
  14. 🚀 発展の可能性
  15. 🎯 自分でやってみよう
  16. 🤔 Q&A
  17. 🐍 ブラウザで動かす

🎯 この記事を読むと何ができるようになるか

📥 データの準備(再現コードを動かす前に)

このページの実データ計算(図1・図4・中心化デモ)を自分で動かすには、以下の手順でデータを準備してください。コードの編集は不要です。

1
データをダウンロードする 独立行政法人統計センターの SSDSE(教育用標準データセット)配布ページから、以下の2ファイルをダウンロードします。
SSDSE-A-2025.csv ← SSDSE-A(市区町村データ)📥 直接DL SSDSE-B-2026.csv ← SSDSE-B(都道府県・時系列データ)📥 直接DL
⬇ SSDSEダウンロードページを開く
2
ファイルを所定のフォルダに配置する ダウンロードしたCSVを、プロジェクトの data/raw/ フォルダに入れます。
2026 統計・データ解析コンペ/ ├── code/ │ └── 2019_U3_suri.py ← 実行するスクリプト └── data/ └── raw/ SSDSE-A-2025.csv ← ここに置く SSDSE-B-2026.csv ← ここに置く
3
スクリプトをそのまま実行する ターミナルでプロジェクトルートに移動し、以下を実行します。
python3 code/2019_U3_suri.py
図は html/figures/ に自動保存されます。

※ 原論文は SSDSE と e-Stat(学校基本調査・市町村税課税状況等の調・国勢調査・経済センサス基礎調査2014)・国土地理院のデータから「高等学校卒業生が存在する1304市町村」の階層データを構築しました。被説明変数の市町村別大学等進学率一人当たり課税対象所得は現行 SSDSE-A-2025 に未収録のため、原論文のモデル(表7・表8)は再推定できません。本ページでは図2・図3を原論文の報告値の可視化(再計算ではない)、図1・図4をSSDSE の実データによる計算として明確に区別します(詳細は「データと変数」の再現範囲を参照)。

研究の背景:進学率の地域格差はなぜ生まれるか

日本の大学等進学率は戦後から上昇傾向を維持し、近年は全国平均で50%超を記録している。しかし進学率には無視できない大きさの地域格差が依然として存在する。興味深いことに、原論文が図1で示すとおり、都道府県別の大学等進学率と中学校第3学年対象の全国学力調査正答率の相関係数はわずか0.226——中学時代の学力では、この格差をほとんど説明できないのである。

※ 大学等進学率=短大への入学も含む進学率。多くの先行研究が用いる大学学部進学率ではなく、市町村単位で入手可能なデータの一貫性を保つためこちらを採用(原論文 脚注1)。原論文 図1(進学率×正答率の散布図)は、全国学力調査の正答率が SSDSE 未収録のため本ページでは再現していない。グラフは原論文参照

都道府県別 高等学校卒業者進学率(2023年度、SSDSE-B-2026 実データ)
図1:都道府県別の高等学校卒業者進学率(2023年度、SSDSE-B-2026 から計算した実データ)。赤=上位5、青=下位5。最高(東京都 74.1%)と最低(沖縄県 46.7%)の差は27.4ポイント。原論文が2015年前後のデータで問題にした「進学率の地域格差」は現在も大きい。
📊 図の読み方
横棒
高等学校卒業者のうち大学・短大等への進学者の割合(SSDSE-B の学校基本調査由来データから計算)。原論文の被説明変数「大学等進学率」の都道府県版に相当する。
点線
47都道府県の平均値。上下に大きく広がっている=地域格差の存在そのものが研究の出発点。
注意
原論文は市町村単位(1304市町村)で分析した。この図は動機を示す都道府県単位の実データであり、原論文の数値の再現ではない。

進学率の地域格差は、機会均等や人材の有効活用の観点から数多く研究されてきた。上山(2011)は親の所得・職業・学歴や地域の大学収容率を、友田(1970)はそれらに加えて人口を、小林(2009)は大学への距離を要因として挙げる。大井(2013)は「経済的要因だけでは説明不十分」とし、地域特有の要因の存在を示唆した。しかし——これらはすべて都道府県単位の研究である。都道府県の内部にも都市部と郊外の格差が明らかに存在するのに、市町村単位の分析はされてこなかった。市町村単位の分析がなければ、都道府県がどのような市町村を重点的に支援すべきかも考察できない。

研究の問い(原論文 第1章) 教育格差是正政策の資料作成を目的として、(1) 都道府県要因を分離したうえでの、市町村単位の大学等進学率決定要因分析、(2) 都道府県要因の存在確認とその要因に関する分析——の二点を実施する。
分析の流れ
SSDSE+e-Stat
1304市町村×
47都道府県
変数加工・
中心化
(表3・表4)
モデル1
ヌルモデル
→ ICC=0.244
モデル2・3
ランダム切片
+説明変数
モデル4
ランダム切片
・傾き
論文審査会コメント(原論文より) 「市町村大学進学率について、先行研究に基づき変数を選択し、マルチレベルモデルをよく理解した上で適用し、考察と共に一定の結果を導いており高く評価された。」

マルチレベル分析 ランダム切片モデル ランダム切片・傾きモデル 級内相関(ICC) 集団平均中心化

やってみよう準備: ライブラリの読み込みと設定
📝 コード
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import os
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import statsmodels.api as sm
import statsmodels.formula.api as smf

plt.rcParams['font.family'] = 'Hiragino Sans'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 150

FIG_DIR = 'html/figures'
DATA_A = 'data/raw/SSDSE-A-2025.csv'
DATA_B = 'data/raw/SSDSE-B-2026.csv'
os.makedirs(FIG_DIR, exist_ok=True)
▼ 実行結果
このステップは print はしません。ライブラリの読み込みと図の保存先の設定だけです。次のステップへ進みましょう。
💡 解説
  • statsmodels.formula.apimixedlm が、本論文の核であるマルチレベルモデル(線形混合モデル)を推定する関数です(原論文は R 3.6.0 の lme4 系の枠組み、本ページは Python で同型のモデルを扱います)。
  • SSDSE-A(市区町村)と SSDSE-B(都道府県)の2つのデータを使います。「市区町村がレベル1、都道府県がレベル2」という階層をそのまま体験するためです。
💡 Python TIPS matplotlib.use('Agg') は画面表示なしで PNG を保存するバックエンド指定。サーバやスクリプト実行では最初に呼ぶのが安全です。
やってみようステップ2: 図1 都道府県別の高等学校卒業者進学率(実データ)
📝 コード
 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
# ===== ステップ2: 図1 都道府県別の高等学校卒業者進学率(SSDSE-B 実データ) =====
# 原論文 図1 は「都道府県別大学等進学率 × 全国学力調査正答率」の散布図
# (相関係数 0.226 = 中学時代の学力では進学率格差をほぼ説明できない)。
# 正答率は SSDSE 未収録のため散布図は原論文参照とし、ここでは格差の存在
# そのもの(研究の出発点)を最新の実データで確認する。
dfB = pd.read_csv(DATA_B, encoding='cp932', header=1)
dfB = dfB[dfB['地域コード'].str.match(r'^R\d{5}', na=False)].copy()
latest_y = dfB['年度'].max()
b = dfB[dfB['年度'] == latest_y].copy()
b['高等学校卒業者進学率'] = b['高等学校卒業者のうち進学者数'] / b['高等学校卒業者数'] * 100
b = b.sort_values('高等学校卒業者進学率')
fig, ax = plt.subplots(figsize=(8.5, 11))
cols = ['#C62828' if v >= b['高等学校卒業者進学率'].nlargest(5).min()
        else ('#1565C0' if v <= b['高等学校卒業者進学率'].nsmallest(5).max() else '#90A4AE')
        for v in b['高等学校卒業者進学率']]
ax.barh(range(len(b)), b['高等学校卒業者進学率'], color=cols, height=0.65)
ax.set_yticks(range(len(b)))
ax.set_yticklabels(b['都道府県'], fontsize=9)
mean_v = b['高等学校卒業者進学率'].mean()
ax.axvline(mean_v, color='#555', lw=1, ls='--')
ax.text(mean_v + 0.3, 0.5, f'47都道府県平均 {mean_v:.1f}%', fontsize=9, color='#555')
ax.set_xlabel('高等学校卒業者進学率 [%](大学・短大等への進学)')
ax.set_title(f'図1:都道府県別 高等学校卒業者進学率({latest_y}年度、SSDSE-B-2026 実データ)\n'
             '赤=上位5 / 青=下位5。原論文の問題意識である「進学率の地域格差」は現在も大きい\n'
             '(原論文 図1〔進学率×全国学力調査正答率の散布図、相関係数0.226〕は原論文参照)',
             fontsize=11)
ax.grid(axis='x', alpha=0.3)
fig.tight_layout()
fig.savefig(f'{FIG_DIR}/2019_U3_fig1.png', bbox_inches='tight')
plt.close(fig)
gap = b['高等学校卒業者進学率'].max() - b['高等学校卒業者進学率'].min()
print(f'【図1】{latest_y}年度の高等学校卒業者進学率(実データ): '
      f'最高 {b.iloc[-1]["都道府県"]} {b["高等学校卒業者進学率"].max():.1f}% / '
      f'最低 {b.iloc[0]["都道府県"]} {b["高等学校卒業者進学率"].min():.1f}% '
      f'(差 {gap:.1f}ポイント)')
▼ 実行結果
【図1】2023年度の高等学校卒業者進学率(実データ): 最高 東京都 74.1% / 最低 沖縄県 46.7% (差 27.4ポイント)
💡 解説
  • 原論文の出発点である「進学率の地域格差」を、現在の SSDSE-B-2026(2023年度)の実データで確認しています。最高(東京都 74.1%)と最低(沖縄県 46.7%)の差は27ポイント超——原論文が2015年前後のデータで問題にした格差は、今も歴然と存在します。
  • 原論文 図1(進学率×全国学力調査正答率の散布図、相関係数0.226)は、正答率データが SSDSE 未収録のため再現できません。グラフは原論文参照
💡 Python TIPS Series.nlargest(5).min() で「上位5位の境界値」が取れます。ランキングの色分けによく使うイディオムです。
マルチレベル分析とは:なぜ普通の回帰ではダメなのか

市町村は都道府県の中に入れ子(階層)になっている。本研究では市町村をレベル1、都道府県をレベル2と考える。ここで、同じ都道府県に属する市町村は共通の都道府県要因の影響を受けるため、互いに似た振る舞いをする——つまり級内相関が生じる。

級内相関があると最小二乗法(OLS)はどう壊れるか(原論文 2.1) OLS は「標本同士が独立」であることを前提にしている。都道府県要因の影響が市町村に及ぶ場合この前提が崩れ、標準誤差が実際より小さく推定され、説明変数の係数が有意になりやすくなる。「有意」の判定そのものが信用できなくなるのである。さらに、都道府県要因の中身を分析したいという本研究の目的にも OLS では応えられない。

ランダム切片モデル(モデル1〜3に対応、原論文 式1・式2)

レベル1(市町村): Yij = β0j + β1 Xij + Rij
レベル2(都道府県): β0j = γ00 + γ01 Zj + Uj

Yij は都道府県 j に属する市町村 i の大学等進学率、Xij は市町村レベルの説明変数、Rij は市町村レベルの残差。通常の回帰と決定的に違うのは、切片 β0j に添え字 j が付いていること——切片が都道府県ごとに変動する(=切片におけるランダム効果)。さらにレベル2の式で、その切片を都道府県レベル変数 Zj(大学収容率・距離)で予測できる部分と、未採択の都道府県要因 Uj に分解する。Uj の分散の変化を見ることで、採択した都道府県レベル変数が都道府県要因をどれだけ説明したかを確認できるのがこのモデルの強みである。

ランダム切片・傾きモデル(モデル4に対応、原論文 式3〜5)

レベル1(市町村): Yij = β0j + β1j Xij + Rij
レベル2(切片): β0j = γ00 + γ01 Zj + U0j
レベル2(傾き): β1j = γ10 + U1j

今度は傾き β1j にも添え字 j が付く。「所得が進学率に効く強さ」自体が都道府県によって異なることを許すモデルである。原論文のモデル4では、計算が収束しかつ当てはまりが改善した一人当たり課税対象所得の傾きのみにランダム効果を仮定した(他の変数の傾きと、都道府県レベル変数との交差レベル交互作用は考慮していない——原論文 脚注4)。

分析手順(原論文 2.2)

モデル内容目的
モデル1定数項のみのヌルモデル(NULL MODEL)級内相関(ICC)を計算し、都道府県要因の存在を確認
モデル2+市町村レベルの説明変数4つ市町村レベル変数の影響を確認
モデル3+都道府県レベルの説明変数2つ(切片に投入)都道府県レベル変数の説明力と、都道府県要因に占める割合を確認
モデル4所得の傾きにもランダム効果(ランダム切片・傾き)都道府県要因が市町村レベル変数の「傾き」に与える影響を考察

第4章の分析では、説明変数の分散を市町村レベルと都道府県レベルに分離するため、市町村レベル変数を集団平均中心化(各市町村の値から所属都道府県の平均を引く)、都道府県レベル変数を全体平均中心化(全体平均を引く)している(中心化の選択は Enders and Tofighi 2007 に依拠、分析はすべて R 3.6.0)。

やってみようステップ5: 集団平均中心化を実データでやってみる
📝 コード
174
175
176
177
178
179
180
181
182
183
184
# ===== ステップ5: 集団平均中心化を実データでやってみる(SSDSE-A) =====
# 原論文は市町村レベル変数を「集団平均中心化」(各市町村の値から所属都道府県の
# 平均を引く)してから投入した。都道府県間の差を取り除き、係数を「同じ県の中で
# 値が高い市町村ほど…」という市町村レベルの効果として解釈できるようにする操作。
dfA['知識率_県平均'] = dfA.groupby('都道府県')['知識集約型産業従事者率'].transform('mean')
dfA['知識率_集団平均中心化'] = dfA['知識集約型産業従事者率'] - dfA['知識率_県平均']
chk = dfA.groupby('都道府県')['知識率_集団平均中心化'].mean().abs().max()
print('【集団平均中心化】知識集約型産業従事者率(SSDSE-A 実データ)')
print(f'  中心化後の都道府県平均の最大絶対値 = {chk:.1e} (どの県でも平均0になった)')
print(f"  例)東京都 千代田区: 元の値 {dfA.loc[dfA['市区町村']=='千代田区','知識集約型産業従事者率'].iloc[0]:.1f}%"
      f" → 中心化後 {dfA.loc[dfA['市区町村']=='千代田区','知識率_集団平均中心化'].iloc[0]:+.1f}")
▼ 実行結果
【集団平均中心化】知識集約型産業従事者率(SSDSE-A 実データ)
  中心化後の都道府県平均の最大絶対値 = 1.9e-15 (どの県でも平均0になった)
  例)東京都 千代田区: 元の値 46.5% → 中心化後 +28.9
💡 解説
  • 集団平均中心化=各市区町村の値から「所属都道府県の平均」を引く操作。原論文は市町村レベル変数すべてにこれを行いました(脚注2)。
  • これにより変数から都道府県間の差が消え、係数は「同じ県の中で値が高い市町村ほど進学率が高いか」という純粋な市町村レベルの効果として解釈できます。中心化しないと市町村レベルと都道府県レベルの影響が混ざります。
  • 千代田区の例:元の値46.5%は全国的に見て極端に高いですが、東京都平均も高いので中心化後は+28.9。この「+28.9」が市町村レベルの情報です。都道府県レベル変数には全体平均中心化(全体平均を引くだけ)を使います(Enders and Tofighi 2007)。
💡 Python TIPS groupby(...).transform('mean') は「グループ平均を元の行数のまま返す」ので、そのまま引き算できます。agg との違いはここ。

データと変数(SSDSE・e-Stat、1304市町村×47都道府県)

使用データ(原論文 第3章)

SSDSE(独立行政法人統計センターの教育用標準データセット)とe-Stat から入手可能なデータを主に使用。市町村レベルは国勢調査(2015)・経済センサス基礎調査(2014)・学校基本調査(2013〜2015)・市町村税課税状況等の調(2015・2016)、都道府県レベルは学校基本調査(2014・2015)と国土地理院の都道府県庁間距離である。高等学校卒業生が存在しない市町村はサンプルから除外し、n=1304市町村。なお市町村別高等学校卒業生は「高校所在市町村」の卒業生であり、生徒の居住市町村ではない点に原論文自身が注意を促している。

1304
市町村(レベル1)
47
都道府県(レベル2)
4+2
説明変数(市町村4+都道府県2)
R 3.6.0
分析環境

加工済み変数(原論文 表3・表4)

レベル変数加工方法(原論文の定義)
市町村大学等進学率(%)[被説明変数]100×大学等進学者数÷高校卒業者数(学校基本調査)
一人当たり課税対象所得(十万円)課税対象所得÷(所得割の納税義務者数×100)
知識集約型産業従事者率(%)100×(情報通信+金融保険+不動産物品賃貸+学術研究専門技術+教育学習支援の従業者数)÷従業者総数
人口密度人口総数÷総面積
65歳以上人口比率(%)65歳以上人口の比率(100×人口比、国勢調査2015)
都道府県都道府県別大学等収容率(%)100×(2015年大学学部生・短大学生数−2014年同−+2015年大学学部・短大卒業者数)÷高等学校卒業者数
min(東京までの距離, 京都までの距離)各道府県庁から東京都庁・京都府庁までの距離の小さい方(km、国土地理院)

※ 変数選択は先行研究に基づく:親の所得・職業・学歴(上山2011)→所得・産業従事者率、居住地の環境(友田1970)→都市化の代理として人口密度・年齢構成、大学への距離(小林2009)→大学等収容率が非常に高い東京都・京都府までの距離。島(1999)の「大学進学便益」は進学率との同時決定性の懸念から不採用。15〜64歳人口比率とその他産業従事者率は、それぞれ65歳以上人口比率・知識集約型産業従事者率と強い相関があり多重共線性回避のため除外された(原論文 3.2)。

基本統計量(原論文 表5・表6 の転記)

大学等進学率(%)一人当たり課税対象所得(十万)知識集約型産業従事者率(%)人口密度65歳以上人口比率(%)
最小値019.94000
中央値41.1427.69.8522.580630.1
平均値40.0828.6410.78713.108130.61
最大値94.01102.3537.494223.8025100
度数13041304130413041304
都道府県別大学等収容率(%)min(東京までの距離, 京都までの距離)(km)
最小値19.090
中央値41.48227.6
平均値47.12307.5
最大値159.711245.2
度数4747

※ 原論文 表5・表6 の報告値の転記(第一・第三四分位数は省略)。進学率の最小0%・最大94.01%、人口密度の最大223.8=市町村間の格差は都道府県単位で見るよりはるかに大きい。大学等収容率の最大159.71%は「県外からの進学者も収容している」ことを意味する(京都・東京など)。

再現可能性の整理(本ページの方針)

本ページで「実データ計算」できる範囲・できない範囲
  • 実データ計算(図1・図4・中心化デモ):知識集約型産業従事者率・人口密度・65歳以上人口比率は、SSDSE-A-2025(市区町村データ)で原論文 表3 と同じ定義のまま計算できる(年次と市区町村数は異なる)。都道府県別の進学率は SSDSE-B-2026 で計算できる。
  • 原論文の報告値の可視化(図2・図3・表7・表8):被説明変数「市町村別大学等進学率」(学校基本調査の市町村集計)と「一人当たり課税対象所得」(市町村税課税状況等の調)は SSDSE-A 未収録のため、原論文のマルチレベルモデルは再推定できない。表7・表8 の結果は原論文の報告値をそのままグラフ化・転記した(再計算ではない)。
  • 原論文参照:原論文 図1(進学率×全国学力調査正答率の散布図)と図2〜図5(市町村別進学率×各説明変数の都道府県別散布図)は、被説明変数が SSDSE 未収録のため再現不可。グラフは原論文参照
やってみようステップ1: SSDSE-A から原論文と同型の市区町村変数を作る
📝 コード
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# ===== ステップ1: SSDSE-A(市区町村)から原論文と同型の説明変数を作る =====
# 原論文 表3 の加工方法に従う(経済センサスの産業分類は同一。年次は異なる)。
#   知識集約型産業従事者率 = (情報通信+金融保険+不動産物品賃貸+
#                             学術研究専門技術+教育学習支援) / 従業者総数 ×100
#   人口密度 [人/km2] = 総人口 / 総面積(SSDSE-A の面積単位は ha → /100 で km2)
#   65歳以上人口比率 = 65歳以上人口 / 総人口 ×100
dfA = pd.read_csv(DATA_A, encoding='cp932', skiprows=2)
knowledge = ['従業者数(民営)(情報通信業)', '従業者数(民営)(金融業、保険業)',
             '従業者数(民営)(不動産業、物品賃貸業)',
             '従業者数(民営)(学術研究、専門・技術サービス業)',
             '従業者数(民営)(教育、学習支援業)']
dfA = dfA[dfA['従業者数(民営)'] > 0].copy()
dfA['知識集約型産業従事者率'] = dfA[knowledge].sum(axis=1) / dfA['従業者数(民営)'] * 100
dfA['人口密度'] = dfA['総人口'] / (dfA['総面積(北方地域及び竹島を除く)'] / 100)
dfA['65歳以上人口比率'] = dfA['65歳以上人口'] / dfA['総人口'] * 100
print(f"【SSDSE-A-2025】{len(dfA)}市区町村 × {dfA['都道府県'].nunique()}都道府県の階層データ")
print('  ※ 原論文は高等学校卒業生が存在する 1304市町村(学校基本調査ベース)')
print('  ※ 被説明変数「市町村別大学等進学率」と「一人当たり課税対象所得」は')
print('     SSDSE-A 未収録 → 原論文のモデルの再推定は不可(表7・表8 は報告値で提示)')
q = dfA[['知識集約型産業従事者率', '人口密度', '65歳以上人口比率']].describe().round(2)
print(q.loc[['min', '25%', '50%', 'mean', '75%', 'max']].to_string())
▼ 実行結果
【SSDSE-A-2025】1741市区町村 × 47都道府県の階層データ
  ※ 原論文は高等学校卒業生が存在する 1304市町村(学校基本調査ベース)
  ※ 被説明変数「市町村別大学等進学率」と「一人当たり課税対象所得」は
     SSDSE-A 未収録 → 原論文のモデルの再推定は不可(表7・表8 は報告値で提示)
      知識集約型産業従事者率      人口密度  65歳以上人口比率
min          0.00      0.00      10.27
25%          4.11     52.30      28.92
50%          6.41    189.63      34.57
mean         7.37   1069.22      34.75
75%          9.02    766.26      40.06
max         46.53  23182.09      65.24
💡 解説
  • 原論文 表3 の加工方法(J2・L2・N2)を そのままの定義で SSDSE-A-2025 に適用しています。知識集約型産業=情報通信・金融保険・不動産物品賃貸・学術研究専門技術・教育学習支援の5分類という定義も原論文と同じです。
  • ただし被説明変数「市町村別大学等進学率」(学校基本調査の市町村集計)と「一人当たり課税対象所得」(市町村税課税状況等の調)は SSDSE-A に未収録。だから原論文のモデルは再推定できず、表7・表8 は「報告値の可視化」として扱います
  • 市区町村数も原論文の1304(高等学校卒業生が存在する市町村のみ)と本ページの1741(全市区町村)で異なる点に注意してください。
💡 Python TIPS df[cols].sum(axis=1) は複数列の横方向の合計。axis=0(縦・列ごと)との違いを意識しましょう。
1
級内相関(ICC)の確認:都道府県要因は存在するか

マルチレベル分析を使う妥当性は、まず級内相関(ICC)の存在で確かめる。定数項のみのモデル1(ヌルモデル)を推定すると、進学率の全分散が「都道府県間の分散」と「市町村間の分散」に分解される。原論文の結果は——

0.244
原論文のICC(モデル1、報告値)
被説明変数=市町村別大学等進学率
約24.4%
進学率の分散のうち
都道府県間の差異で説明される割合
0.186
本ページの実データデモのICC
(別変数:知識集約型産業従事者率)

ICC=0.244——大学等進学率のばらつきの約24.4%は、市町村間の差ではなく都道府県間の差によって説明される(原論文 4.1)。無視するには大きすぎる値であり、マルチレベル分析の妥当性が確認された。原論文はさらに図2〜図5(市町村別進学率×各説明変数の都道府県別散布図)でも都道府県要因の存在を視覚的に確認しているが、これらは被説明変数が SSDSE 未収録のためグラフは原論文参照

かわりに本ページでは、SSDSE-A-2025 の実データを使って「級内相関がある」とはどういう状態かを体感する。市区町村の知識集約型産業従事者率(原論文 表3 と同じ定義で計算)を47都道府県別に並べた箱ひげ図が図4だ。これは手法のデモであり、原論文の ICC=0.244 の検算ではない(変数が違う)。

市区町村の知識集約型産業従事者率の都道府県別分布(SSDSE-A-2025 実データ)
図4:級内相関を体感する——市区町村の知識集約型産業従事者率の都道府県別分布(SSDSE-A-2025 実データによる手法デモ。中央値の昇順)。箱の位置が県ごとに系統的にずれており、ヌルモデルの ICC は 0.186。原論文の ICC=0.244 は被説明変数「大学等進学率」についての報告値であり、この図はその再計算ではない
📊 図の読み方
その都道府県に属する市区町村の第1〜第3四分位範囲。赤線は中央値。
縦のずれ
箱全体の位置が県ごとに上下している=「どの県にあるか」だけで市区町村の値がある程度予測できる=級内相関の存在
ICC=0.186
ヌルモデル(ランダム切片のみ)による分散分解:都道府県レベル分散4.77÷(4.77+20.86)。この変数ではばらつきの約19%が都道府県間の差。
注意
原論文と同じ手順・別の変数による教育用デモ。0.186 と原論文の 0.244 を比較して何かを結論することはできない。
やってみようステップ6: 図4 級内相関(ICC)を実データで計算する
📝 コード
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
# ===== ステップ6: 図4 級内相関(ICC)を実データで体感する(手法のデモ) =====
# 市区町村の「知識集約型産業従事者率」が都道府県というグループでどれだけ
# 塊になっているかを、(1)箱ひげ図 と (2)ヌルモデル(ランダム切片のみの
# マルチレベルモデル)の ICC で確かめる。原論文のモデル1(被説明変数は
# 大学等進学率、ICC=0.244)と同じ手順を、SSDSE-A で使える別の変数に適用
# した「手法のデモ」であり、原論文の数値の検算ではない。
null_model = smf.mixedlm('知識集約型産業従事者率 ~ 1', dfA, groups=dfA['都道府県'])
res = null_model.fit(reml=True)
var_u = res.cov_re.iloc[0, 0]          # 都道府県レベルの分散
var_e = res.scale                      # 市区町村レベルの残差分散
icc = var_u / (var_u + var_e)
print('【図4】ヌルモデル(ランダム切片のみ)による級内相関 — SSDSE-A 実データ')
print(f'  都道府県レベル分散 = {var_u:.2f} / 市区町村レベル分散 = {var_e:.2f}')
print(f'  ICC = {var_u:.2f} / ({var_u:.2f} + {var_e:.2f}) = {icc:.3f}')
print(f'  → 知識集約型産業従事者率のばらつきの約{icc*100:.1f}%は都道府県間の差')
print('  (原論文の ICC=0.244 は「市町村別大学等進学率」についての報告値。別の変数)')

order = dfA.groupby('都道府県')['知識集約型産業従事者率'].median().sort_values().index
data = [dfA.loc[dfA['都道府県'] == p, '知識集約型産業従事者率'].values for p in order]
fig, ax = plt.subplots(figsize=(9, 11))
bp = ax.boxplot(data, vert=False, patch_artist=True, showfliers=False, widths=0.6)
for patch in bp['boxes']:
    patch.set_facecolor('#BBDEFB'); patch.set_edgecolor('#1565C0')
for med in bp['medians']:
    med.set_color('#C62828')
ax.set_yticklabels(order, fontsize=9)
ax.set_xlabel('市区町村の知識集約型産業従事者率 [%](原論文 表3 と同じ定義で計算)')
ax.set_title('図4:級内相関を体感する — 市区町村の知識集約型産業従事者率の都道府県別分布\n'
             f'(SSDSE-A-2025 実データによる手法デモ。ヌルモデルの ICC = {icc:.3f}\n'
             '箱の位置が県ごとに系統的にずれる=都道府県レベルの要因が存在する',
             fontsize=11)
ax.grid(axis='x', alpha=0.3)
fig.tight_layout()
fig.savefig(f'{FIG_DIR}/2019_U3_fig4.png', bbox_inches='tight')
plt.close(fig)
top3 = dfA.groupby('都道府県')['知識集約型産業従事者率'].median().nlargest(3)
print('  都道府県中央値の上位3:', ' / '.join(f'{k} {v:.1f}%' for k, v in top3.items()))
▼ 実行結果
【図4】ヌルモデル(ランダム切片のみ)による級内相関 — SSDSE-A 実データ
  都道府県レベル分散 = 4.77 / 市区町村レベル分散 = 20.86
  ICC = 4.77 / (4.77 + 20.86) = 0.186
  → 知識集約型産業従事者率のばらつきの約18.6%は都道府県間の差
  (原論文の ICC=0.244 は「市町村別大学等進学率」についての報告値。別の変数)
  都道府県中央値の上位3: 東京都 16.6% / 神奈川県 12.3% / 大阪府 11.3%
💡 解説
  • mixedlm('y ~ 1', groups=都道府県)ヌルモデル(定数項+ランダム切片のみ)。原論文のモデル1と同じ構造です。
  • ICC=都道府県レベル分散÷全体分散。この実データデモでは 4.77/(4.77+20.86)=0.186。市区町村の知識集約型産業従事者率のばらつきの約19%は「どの県にあるか」で決まっています。
  • 注意:これは手法のデモです。原論文の ICC=0.244 は被説明変数「市町村別大学等進学率」についての報告値で、ここで計算したのは別の変数。0.186 と 0.244 を比べて優劣を論じることはできません。
💡 Python TIPS MixedLM の結果オブジェクトでは、グループ分散が res.cov_re、残差分散が res.scale に入っています。ICC は自分で割り算して求めます。
2
マルチレベル分析の結果(表7・図2)

モデル1〜4の推定結果が原論文 表7 である。下表はその報告値の転記(カッコ内は標準誤差。市町村レベル変数は集団平均中心化後、都道府県レベル変数は全体平均中心化後の値)。

被説明変数:大学等進学率モデル1モデル2モデル3モデル4
(Intercept)40.88*** (1.30)40.89*** (1.31)40.91*** (0.94)40.81*** (0.95)
〔市町村〕一人当たり課税対象所得0.46** (0.14)0.46** (0.14)1.16*** (0.24)
〔市町村〕知識集約型産業従事者率0.67*** (0.14)0.67*** (0.14)0.63*** (0.14)
〔市町村〕人口密度0.09*** (0.03)0.09*** (0.03)0.09*** (0.03)
〔市町村〕65歳以上人口比率−0.64*** (0.09)−0.64*** (0.09)−0.48*** (0.09)
〔都道府県〕都道府県別大学収容率0.16*** (0.04)0.14*** (0.03)
〔都道府県〕min(東京までの距離, 京都までの距離)−0.02*** (0.00)−0.02*** (0.00)
AIC11260.3811038.8011023.4611011.03
BIC11275.9011075.0111070.0211067.94
Log Likelihood−5627.19−5512.40−5502.73−5494.52
Var: prefecture (Intercept)66.4269.2429.129.91
Var: Residual306.79254.34254.4247.64
Var: prefecture 一人当たり課税対象所得0.52
Cov: prefecture (Intercept)×一人当たり課税対象所得−1.19

※ 原論文 表7 の報告値の転記。*** p<0.001、** p<0.01、* p<0.05。Num. obs.=1304、Num. groups: prefecture=47(全モデル共通)。緑=正で有意、赤=負で有意。

マルチレベル分析の係数(原論文 表7 の報告値の可視化)
図2:モデル3(ランダム切片、青丸)とモデル4(ランダム切片・傾き、橙四角)の係数。本図は原論文 表7 の報告値をそのまま可視化したもので、再計算ではない。横線は係数±1.96×標準誤差(距離の標準誤差は報告値0.00のため横線がほぼ点になる)。
📊 図の読み方
固定効果(全国共通の平均的な効き方)の推定値。0より右=その変数が大きい市町村・都道府県ほど進学率が高い。
横線
係数±1.96×標準誤差(報告値から描画)。0の縦線をまたがなければおおよそ5%水準で有意。
青→橙の変化
所得(0.46→1.16)と65歳以上人口比率(−0.64→−0.48)はモデル4で大きく変わる。所得の傾きにランダム効果を許すとモデルの構造自体が変わることの現れ。
単位に注意
係数の大小は変数の単位に依存する。距離の−0.02は「1kmあたり」なので、500kmなら約−10ポイントに相当する大きな効果。

市町村レベル変数の結果(原論文 4.2-1)

一人当たり課税対象所得・知識集約型産業従事者率・人口密度は有意に正、65歳以上人口比率は有意に負。これは都道府県単位の先行研究と概ね一致するが、決定的に新しいのは市町村単位でも同じ変数が有意だと示したこと——進学率格差は県と県の間だけでなく、同じ県の中の市町村間でも所得や産業構造によって生じている。

さらにモデル4はモデル3より AIC・BIC が小さく、都道府県間で所得の係数が異なるモデルの方が当てはまりがよい。そしてランダム効果の共分散(切片×所得傾き)は−1.19 と負:切片が大きい(=県要因として進学率の底が高い)都道府県ほど、所得が進学率に与える影響が小さい。

都道府県レベル変数の結果(原論文 4.2-2)

先行研究と同様に、都道府県別大学等収容率は有意に正(地元に進学先の「席」が多いほど進学しやすい)、東京又は京都までの距離は有意に負(大学集積地から遠いほど進学しにくい)。

やってみようステップ3: 図2 原論文 表7 の係数の可視化(報告値の転記)
📝 コード
107
108
109
110
111
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
# ===== ステップ3: 図2 原論文 表7 の係数の可視化(報告値。再計算ではない) =====
# (変数名, モデル3係数, SE, モデル4係数, SE, レベル)  … 原論文 表7 の転記
paper_t7 = [
    ('一人当たり課税対象所得(十万円)', 0.46, 0.14, 1.16, 0.24, '市町村'),
    ('知識集約型産業従事者率(%)',      0.67, 0.14, 0.63, 0.14, '市町村'),
    ('人口密度',                       0.09, 0.03, 0.09, 0.03, '市町村'),
    ('65歳以上人口比率(%)',           -0.64, 0.09, -0.48, 0.09, '市町村'),
    ('都道府県別大学収容率(%)',        0.16, 0.04, 0.14, 0.03, '都道府県'),
    ('min(東京までの距離,京都までの距離)', -0.02, 0.00, -0.02, 0.00, '都道府県'),
]
fig, ax = plt.subplots(figsize=(9.6, 5.6))
ys = np.arange(len(paper_t7))[::-1]
for y, (name, b3, se3, b4, se4, lv) in zip(ys, paper_t7):
    for b_, se_, dy, c, m in [(b3, se3, 0.16, '#1565C0', 'o'), (b4, se4, -0.16, '#E65100', 's')]:
        ax.plot([b_ - 1.96 * se_, b_ + 1.96 * se_], [y + dy, y + dy], color=c, lw=2)
        ax.plot(b_, y + dy, m, color=c, ms=7)
ax.axvline(0, color='#555', lw=0.8, ls='--')
ax.set_yticks(ys)
ax.set_yticklabels([f"〔{r[5]}{r[0]}" for r in paper_t7], fontsize=10)
ax.plot([], [], 'o-', color='#1565C0', label='モデル3(ランダム切片)')
ax.plot([], [], 's-', color='#E65100', label='モデル4(ランダム切片・傾き)')
ax.legend(loc='lower right', fontsize=10)
ax.set_xlabel('大学等進学率への係数(点=係数、横線=係数±1.96×標準誤差)')
ax.set_title('図2:マルチレベル分析の係数(原論文 表7 の報告値の可視化。再計算ではない)\n'
             'いずれの係数もモデル3・4で5%水準より強い有意(所得は**、他は***)\n'
             '市町村レベル変数は集団平均中心化後、都道府県レベル変数は全体平均中心化後の値',
             fontsize=11)
ax.grid(axis='x', alpha=0.3)
fig.tight_layout()
fig.savefig(f'{FIG_DIR}/2019_U3_fig2.png', bbox_inches='tight')
plt.close(fig)
print('【図2】原論文 表7 の報告値(モデル3 → モデル4)')
for name, b3, se3, b4, se4, lv in paper_t7:
    print(f'  〔{lv}{name}: {b3:+.2f}{b4:+.2f}')
print('  ※ モデル4では所得の傾きにランダム効果(分散0.52、切片との共分散 -1.19)')
▼ 実行結果
【図2】原論文 表7 の報告値(モデル3 → モデル4)
  〔市町村〕一人当たり課税対象所得(十万円): +0.46 → +1.16
  〔市町村〕知識集約型産業従事者率(%): +0.67 → +0.63
  〔市町村〕人口密度: +0.09 → +0.09
  〔市町村〕65歳以上人口比率(%): -0.64 → -0.48
  〔都道府県〕都道府県別大学収容率(%): +0.16 → +0.14
  〔都道府県〕min(東京までの距離,京都までの距離): -0.02 → -0.02
  ※ モデル4では所得の傾きにランダム効果(分散0.52、切片との共分散 -1.19)
💡 解説
  • リスト paper_t7 の数値は原論文 表7 の転記(係数と標準誤差)であり、再計算ではありません。
  • モデル3→モデル4で注目すべきは65歳以上人口比率(−0.64→−0.48)と所得(0.46→1.16)の変化。所得の傾きに都道府県ごとのランダム効果を認めると、固定部分(全国共通の平均的な傾き)の推定値が大きく変わる——傾きが県によって違うことの間接的な現れです。
  • 距離の係数は−0.02と小さく見えますが、単位が km なので「東京・京都から500km遠いと進学率が約10ポイント低い」に相当します。係数の大小は単位に依存します。
💡 Python TIPS エラーバー付きの点推定は ax.plot([lo, hi], [y, y])ax.plot(b, y, 'o') の2行で描けます。フォレストプロットの基本形です。
やってみようステップ7: 原論文 表7 のモデル比較指標(報告値の整理)
📝 コード
224
225
226
227
228
229
230
231
232
233
234
# ===== ステップ7: 原論文 表7 のモデル比較指標(報告値の整理) =====
print('\n【原論文 表7 の報告値】モデルの当てはまり(AIC・BIC は小さいほどよい)')
t7 = pd.DataFrame({
    'AIC': [11260.38, 11038.80, 11023.46, 11011.03],
    'BIC': [11275.90, 11075.01, 11070.02, 11067.94],
    'LogLik': [-5627.19, -5512.40, -5502.73, -5494.52],
}, index=['モデル1(ヌル)', 'モデル2(市町村)', 'モデル3(+都道府県)', 'モデル4(+傾き)'])
print(t7.to_string())
print('  → モデル4が最良: 都道府県間で「所得の傾き」が異なるモデルの当てはまりが最もよい')
print('  → 切片と所得傾きのランダム効果の共分散 -1.19(負): 都道府県要因の切片が')
print('     大きい県ほど、所得が進学率に与える影響が小さい(原論文 4.2-1)')
▼ 実行結果
【原論文 表7 の報告値】モデルの当てはまり(AIC・BIC は小さいほどよい)
                  AIC       BIC   LogLik
モデル1(ヌル)     11260.38  11275.90 -5627.19
モデル2(市町村)    11038.80  11075.01 -5512.40
モデル3(+都道府県)  11023.46  11070.02 -5502.73
モデル4(+傾き)    11011.03  11067.94 -5494.52
  → モデル4が最良: 都道府県間で「所得の傾き」が異なるモデルの当てはまりが最もよい
  → 切片と所得傾きのランダム効果の共分散 -1.19(負): 都道府県要因の切片が
     大きい県ほど、所得が進学率に与える影響が小さい(原論文 4.2-1)
💡 解説
  • AIC・BIC・対数尤度のいずれで見てもモデル4(ランダム切片・傾きモデル)が最良。「所得→進学率」の効き方が県によって違うと考える方がデータに合います。
  • 切片と所得傾きの共分散が負(−1.19)である点が原論文の政策的示唆の核心:都道府県要因の切片が大きい(=県全体として進学率の底が高い)県ほど、所得の傾きが小さい。都道府県要因を底上げする政策は、所得格差が進学率格差に転化するのを間接的に和らげる可能性がある(原論文 第5章)。
💡 Python TIPS pd.DataFrame(dict, index=[...])to_string() で、報告値の整理表をコンソールに揃えて出力できます。
3
都道府県要因はどこまで説明できたか(表8・図3)

採択した2つの都道府県レベル変数が「都道府県要因」のどの程度を占めるのかを確認するため、原論文はモデル2に大学等収容率のみを加えたモデル3-1と、距離のみを加えたモデル3-2を推定した(表8)。判定に使うのは都道府県間による切片のばらつき Var: prefecture (Intercept) の減少である。

モデル2モデル3-1
(+大学収容率)
モデル3-2
(+距離)
モデル3
(+両方)
都道府県別大学収容率0.20*** (0.04)0.16*** (0.04)
min(東京までの距離, 京都までの距離)−0.02*** (0.00)−0.02*** (0.00)
Var: prefecture (Intercept)69.2442.7246.3829.1
Var: Residual254.34254.34254.32254.4
AIC11038.8011026.0111033.2711023.46
Log Likelihood−5512.40−5505.00−5508.64−5502.73

※ 原論文 表8 の報告値の転記(市町村レベル変数4つの係数は4モデルすべてで表7のモデル2と同一のため省略)。Num. obs.=1304、Num. groups=47。

分散成分の比較(原論文 表7・表8 の報告値の可視化)
図3:分散成分の比較。本図は原論文 表7・表8 の報告値をそのまま可視化したもので、再計算ではない。左:都道府県切片の分散は収容率で69.24→42.72、距離で→46.38、両方で→29.10まで減少。右:市町村レベルの残差分散は都道府県変数を入れてもほぼ不変(254前後)——都道府県レベル変数は切片(県ごとの底上げ)にのみ効く。
📊 図の読み方
左パネル
「まだ説明できていない都道府県要因」の大きさ。減った分=その変数が説明した都道府県要因。
右パネル
市町村レベルの残差分散。モデル2で306.79→254.34に減った(市町村変数の寄与)あとは、都道府県変数を足しても動かない。
残る29.1
両方の都道府県変数を入れても無視できない大きさの切片のばらつきが残る=説明しきれない都道府県要因(原論文は県民性などを候補として挙げ、データ化を課題とする)。

結論として、大学等収容率と東京・京都までの距離のどちらも、都道府県要因の決して少なくない部分を占める。ただし両方を入れても29.1の切片分散が残ることに原論文は注意を促している。

やってみようステップ4: 図3 都道府県切片の分散の比較(報告値の転記)
📝 コード
143
144
145
146
147
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
# ===== ステップ4: 図3 都道府県切片分散の比較(原論文 表7・表8 の報告値) =====
# 「採択した都道府県レベル変数が、都道府県要因(切片のばらつき)をどれだけ
#   説明したか」を Var: prefecture (Intercept) の減少で確認する(原論文 4.2-2)。
models = ['モデル1\n(ヌル)', 'モデル2\n(+市町村変数)', 'モデル3-1\n(+大学収容率)',
          'モデル3-2\n(+距離)', 'モデル3\n(+両方)', 'モデル4\n(+所得の傾き)']
var_pref = [66.42, 69.24, 42.72, 46.38, 29.10, 29.91]   # 表7・表8の報告値
var_res  = [306.79, 254.34, 254.34, 254.32, 254.40, 247.64]
fig, axes = plt.subplots(1, 2, figsize=(11, 4.6))
colors = ['#78909C', '#78909C', '#42A5F5', '#42A5F5', '#1565C0', '#E65100']
axes[0].bar(models, var_pref, color=colors)
for i, v in enumerate(var_pref):
    axes[0].text(i, v + 1, f'{v:.1f}', ha='center', fontsize=10)
axes[0].set_ylabel('Var: prefecture (Intercept)')
axes[0].set_title('都道府県切片の分散(都道府県要因の残り)', fontsize=11)
axes[1].bar(models, var_res, color=colors)
for i, v in enumerate(var_res):
    axes[1].text(i, v + 3, f'{v:.0f}', ha='center', fontsize=10)
axes[1].set_ylabel('Var: Residual')
axes[1].set_title('市町村レベルの残差分散', fontsize=11)
for ax in axes:
    ax.tick_params(axis='x', labelsize=8.5)
    ax.grid(axis='y', alpha=0.3)
fig.suptitle('図3:分散成分の比較(原論文 表7・表8 の報告値の可視化。再計算ではない)\n'
             '大学収容率と距離を両方入れると都道府県切片の分散は 69.24 → 29.10 に減少(それでも残る)',
             fontsize=11)
fig.tight_layout(rect=[0, 0, 1, 0.90])
fig.savefig(f'{FIG_DIR}/2019_U3_fig3.png', bbox_inches='tight')
plt.close(fig)
print('【図3】都道府県切片の分散(原論文の報告値): '
      f'モデル2 {var_pref[1]} → モデル3-1 {var_pref[2]} → モデル3-2 {var_pref[3]} → モデル3 {var_pref[4]}')
▼ 実行結果
【図3】都道府県切片の分散(原論文の報告値): モデル2 69.24 → モデル3-1 42.72 → モデル3-2 46.38 → モデル3 29.1
💡 解説
  • マルチレベル分析の醍醐味は、「レベル2の分散がどれだけ減ったか」で都道府県レベル変数の説明力を測れること(原論文 4.2-2)。大学収容率だけで 69.24→42.72、距離だけで 69.24→46.38、両方で 29.10 まで減ります。
  • それでも 29.1 の分散が残る=説明しきれない都道府県要因(原論文は県民性などを候補に挙げる)が存在します。
  • 右パネルの残差分散(市町村レベル)は都道府県変数を入れてもほぼ変わりません。都道府県レベル変数は切片(県ごとの底上げ分)にしか効かないためで、レベルごとの分散が分離されている証拠です。
💡 Python TIPS fig.suptitlefig.tight_layout(rect=[0,0,1,0.90]) で、全体タイトルとサブプロットの重なりを防げます。
考察:4つの発見と政策への含意(原論文 第5章)

発見1:市町村単位でも先行研究の変数は有意

所得・知識集約型産業従事者率・人口密度・65歳以上人口比率に目を向けた政策は、都道府県単位だけでなく市町村単位でも有用と予測できる。どの市町村を重点支援すべきかの指標になる。

発見2:進学率のばらつきの約24%は都道府県要因

市町村要因では説明できない部分が確かに存在する。都道府県単位の適切な政策は、県内の市町村全体に一括して波及しうる。

発見3:収容率と距離は都道府県要因の中核

両変数は都道府県切片のばらつきを大きく減少させた(69.24→29.10)。大学の収容力・大学集積地へのアクセスに焦点を置いた政策は有用と推測される。

発見4:所得の「効き方」は県によって違う

切片と所得傾きの共分散は負(−1.19)。都道府県要因の切片を底上げする政策を行えば、所得格差が進学率格差に転化する度合いを間接的に減らせる可能性がある。

政策的含意のポイント 本研究の目的は「国・都道府県が市町村単位での進学率向上政策を打ち出すための指標作成」。マルチレベル分析だからこそ、市町村向けの施策(所得・産業・人口構成に着目)都道府県向けの施策(収容率・アクセスに着目)を別々のレベルで、しかも相互作用(発見4)まで含めて設計できる。ただし原論文自身が「より具体的な政策提言には因果関係に関する議論・投資効果の検討が必要」と明記している。
まとめ:研究の強みと限界

この研究の強み

原論文自身が認める限界(第5章)

⚠️ よくある誤解と注意点

この論文(とマルチレベル分析全般)を読むときに、初心者が陥りやすい誤解を整理します。

誤解1:「ICC=0.244 = モデルが進学率の24.4%を説明した」
ICC は決定係数(R²)ではない。「進学率の全ばらつきのうち、都道府県間の差に由来する割合」という分散の分解であり、何かを「説明できた」割合ではない。説明変数を1つも入れないヌルモデルから計算される点を思い出そう。「どのレベルの要因を探すべきか」の道しるべになる値である。
誤解2:「係数が大きい変数ほど重要」
表7の係数は変数の単位に依存する。距離の−0.02は一見小さいが「1kmあたり」なので、東京・京都から1000km離れた道県では約−20ポイントに相当する。逆に所得の0.46は「十万円あたり」。単位を無視した大小比較は無意味で、重要度を比べるなら「現実的にありうる変化幅×係数」で考える必要がある。
誤解3:「ランダム切片の『ランダム』=無作為抽出」
ここでの「ランダム」は切片(や傾き)を確率変数としてモデル化するという意味で、標本の無作為抽出とは無関係。「47都道府県それぞれに固有の定数を推定する」(固定効果的発想)のではなく、「切片は平均γ00・分散σ²の分布から生じる」と考えることで、分散という1つの数字で都道府県要因の大きさを測れるようになる。
誤解4:「有意な係数=因果関係が証明された」
本研究は観察データの分析であり、「所得を上げれば進学率が上がる」という因果関係の証明ではない。原論文自身が「より具体的な政策提言に落とし込むためには、因果関係に関する議論・政策候補それぞれの投資効果についての検討等が必要」と明記している。島(1999)の大学進学便益を同時決定性(進学率が低いから便益が高まる逆経路)を理由に変数から外した判断は、著者が因果の向きに自覚的である証拠でもある。
誤解5:「本ページの実データ計算で原論文を検算できた」
できていない。被説明変数(市町村別大学等進学率)と所得が SSDSE 未収録のため、原論文のモデルの再推定は不可能で、表7・表8・図2・図3はすべて原論文の報告値の転記・可視化である。本ページの図4(ICC=0.186)は別の変数を使った手法のデモにすぎず、原論文の ICC=0.244 と比較して優劣や正誤を論じることはできない。

📖 用語集(この論文を読むための最小限)

本文中の 用語 をクリックすると詳しい解説がポップアップします。ここでは特に重要な概念だけまとめます。

マルチレベル分析
「市町村が都道府県に入れ子になっている」ような階層データで、複数のレベルの説明変数を同時に扱える回帰モデルの総称(階層線形モデル・線形混合モデルとも)。変動項(ランダム効果)をレベルごとに置くことで級内相関を正しく処理する。
級内相関(ICC)
同じグループ(都道府県)に属する個体(市町村)同士の値がどれだけ似ているかの指標。ヌルモデルの「グループ間分散÷(グループ間分散+グループ内分散)」で計算する。本論文では0.244(原論文の報告値)。
ランダム切片モデル
回帰式の切片が都道府県ごとに確率的に変動することを許すモデル。「県ごとの底上げ・底下げ」を表現する。本論文のモデル1〜3。
ランダム切片・傾きモデル
切片に加えて傾き(説明変数の効き方)も都道府県ごとに変動することを許すモデル。本論文のモデル4は所得の傾きのみに適用し、AIC・BICで最良だった。
集団平均中心化
各市町村の値から所属都道府県の平均を引く変換。都道府県間の差を除去し、係数を「同じ県の中での差」の効果として解釈可能にする。市町村レベル変数に適用(原論文 脚注2)。
全体平均中心化
変数から全体の平均を引く変換。都道府県レベル変数に適用。切片の解釈(=平均的な県の予測値)を容易にする(原論文 脚注3)。
大学等進学率
高校卒業者のうち大学・短大等へ進学した者の割合。市町村単位で入手可能なデータの一貫性のため、大学学部進学率ではなくこちらを採用(原論文 脚注1)。
大学等収容率
その都道府県の大学・短大の「席」の多さを表す指標。100×(大学学部生・短大生数の1年間の増分+卒業者数)÷高校卒業者数で計算。最大は159.71%(県外からの進学者も収容)。

📐 使っている手法をわかりやすく解説

統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。

◆ 統計の基本概念(この論文を読む前提)

🔍 なぜ「市町村データを全部プールした重回帰」ではダメなのか
何?
1304市町村を1つの表に並べて重回帰すれば良さそうに見える。しかし同じ県の市町村は共通の県要因を受けて互いに似る(級内相関)。
何が壊れる?
OLSの前提「標本間の独立」が崩れ、標準誤差が実際より小さく推定される。結果、本当は有意でない変数まで「有意」に見えてしまう(原論文 2.1)。
この論文では
ICC=0.244(報告値)と大きく、独立の仮定は明確に不成立。だからマルチレベルモデルが必然になる。
読み方
階層データ(生徒×学校、患者×病院、店舗×地域…)を見たら、まず「級内相関はないか?」と疑うのがこの論文から学べる姿勢。

◆ この論文で使われている手法

🏗 マルチレベル分析(階層線形モデル)
何?
レベル1(市町村)の回帰式の切片や傾きを、レベル2(都道府県)の回帰式でさらに説明する2段構えのモデル。両レベルの説明変数を同時に扱える。
どう使う?
本論文では市町村4変数+都道府県2変数を投入し、R 3.6.0 で推定。モデル1→4と段階的に複雑化した。
何がわかる?
係数(固定効果)に加えて、レベル2の分散の変化から「都道府県レベル変数が都道府県要因をどれだけ説明したか」が読める。
結果の読み方
固定効果は通常の回帰と同様に係数・標準誤差・有意水準で読む。分散成分(Var: prefecture, Var: Residual)はレベルごとの「残されたばらつき」。
⚠️ 注意点
(1) レベル2の標本数が効く——係数の検定力はレベル2の数(ここでは47都道府県)に強く依存する。グループ数が少ない(目安30未満)と分散成分の推定が不安定になる。(2) 中心化の選択で係数の意味が変わる——集団平均中心化と全体平均中心化では「市町村レベルの効果」の定義自体が変わるため、必ず明記する(本論文は明記している)。(3) 級内相関が無視できるなら使わない——ICCがほぼ0なら通常のOLSで十分。モデルの複雑化は常にコストを伴う。
📏 級内相関(ICC)とヌルモデル
何?
説明変数なし・ランダム切片のみの「ヌルモデル」を推定し、全分散をグループ間とグループ内に分解。グループ間の割合がICC。
どう使う?
本論文の分析手順の第一歩(モデル1)。ICC=0.244 → 進学率のばらつきの約24.4%が都道府県間の差 → マルチレベル分析の妥当性を確認。
何がわかる?
「どのレベルに要因を探しに行くべきか」の配分。ICCが大きいほど上位レベルの要因分析の価値が高い。
結果の読み方
0.05〜0.10程度でも級内相関の無視は危険とされる。0.244はかなり大きい部類。
⚠️ 注意点
(1) ICCは説明力ではない——R²と混同しない(よくある誤解1参照)。(2) 推定法・ソフトで微妙に値が変わる——REML/ML、分散の推定方法によりICCは変わりうる。報告時は推定環境を書く(本論文は R 3.6.0 と明記)。(3) グループの定義に依存する——「都道府県」でなく「通学圏」でグループ化すればICCは別の値になる。グループ設定自体が分析上の意思決定。
🎢 ランダム切片・傾きモデル
何?
説明変数の傾きにもグループごとのランダム効果を認めるモデル。「所得の効き方は県によって違う」を数式で表現できる。
どう使う?
本論文のモデル4。一人当たり課税対象所得の傾きのみに適用(他の変数では計算が収束しなかったか、当てはまりが改善しなかった)。AIC・BIC・対数尤度のすべてでモデル3より改善。
何がわかる?
傾きの分散(0.52)=効き方の県ごとのばらつき、切片との共分散(−1.19)=「底が高い県ほど所得が効かない」という交互作用的な構造。
結果の読み方
共分散の符号が本論文の政策的示唆の核心。負→県要因の底上げが所得格差の影響を和らげる。
⚠️ 注意点
(1) 収束しないことが日常的にある——ランダム効果を増やすほど推定は難しくなる。本論文も「計算上の制約」で傾きと都道府県変数の関係を分析できなかったと明記。(2) どの傾きをランダムにするかは理論とAIC/BICの両輪で——全部ランダムにするのは推定不能への近道。(3) 共分散の解釈は中心化に依存——集団平均中心化していない場合、切片×傾きの共分散は解釈が変わる。
⚖️ 集団平均中心化・全体平均中心化
何?
説明変数から平均を引く前処理。引く平均が「所属グループの平均」なら集団平均中心化、「全体の平均」なら全体平均中心化。
どう使う?
本論文は市町村レベル変数に集団平均中心化、都道府県レベル変数に全体平均中心化を適用(Enders and Tofighi 2007 を参照)。
何がわかる?
集団平均中心化により、市町村変数の係数が「県間の差」の混入なしに「県内での差」の効果として解釈できる。
結果の読み方
表7の係数はすべて中心化後の値。所得0.46は「同じ県の中で所得が十万円高い市町村は進学率が0.46ポイント高い」。
⚠️ 注意点
(1) 中心化の選択は結果を変える——集団平均中心化はグループ間情報を変数から完全に除去するため、レベル2に平均値を戻し入れるかどうかも含めて設計判断。(2) 「とりあえず標準化」とは別物——標準偏差で割る標準化は単位を消すが、レベルの分離はしない。(3) ランダム傾きモデルでは特に重要——中心化しないと切片・傾きの分散/共分散の解釈が大きく歪む。
🧮 AIC・BICによるモデル比較
何?
当てはまりの良さ(対数尤度)に複雑さのペナルティを課した指標。小さいほどよい。BICの方がペナルティが重い。
どう使う?
本論文ではモデル1→2→3→4の順にAIC(11260→11039→11023→11011)・BICがともに減少し、モデル4を採用。
何がわかる?
「ランダム傾きを足す価値があるか」のような、検定しにくいモデル構造の比較ができる。
結果の読み方
差が10以上なら明確な差とされることが多い。モデル3→4のAIC差は約12。
⚠️ 注意点
(1) 同じデータ・同じ被説明変数でしか比較できない——サンプルの異なるモデルのAIC比較は無意味。(2) REMLで推定した場合、固定効果の異なるモデルのAIC比較は不適切——固定効果を比べるならML推定に切り替えるのが定石。(3) AIC最小=真のモデルではない——あくまで「候補の中で予測的に最良」の目安。

🚀 発展の可能性(結果 X → 新仮説 Y → 課題 Z)

この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。

① 居住地ベースのデータとベイズ推定で精度を上げる
結果 X
本論文のデータは高校所在地ベースで、高卒者ゼロの市町村は除外。過疎地域では分母が小さく進学率が年により大きく振れる。
新仮説 Y
「居住市町村ベースで測り直すと、通学圏の中心都市の効果が分離され、市町村変数の係数は変わる」。
課題 Z
居住地ベースの進学データの収集・突合。小標本市町村については原論文も提案するベイズ推定(縮約推定)で進学率を安定化してから同じモデルを再推定する。
② 交差レベル交互作用:傾きの違いを「説明」する
結果 X
所得の傾きは県によって違い(分散0.52)、切片と負の共分散(−1.19)を持つ。しかし「なぜ違うのか」は未分析(計算の収束の問題、原論文 第5章)。
新仮説 Y
「大学等収容率が高い県ほど所得の傾きが小さい」——地元に進学先が多ければ、所得による進学制約が緩むはず。
課題 Z
傾きの式に都道府県レベル変数を入れた交差レベル交互作用モデル(式5の完全形)の推定。収束問題にはベイズ推定(Stan/brms)や変数の標準化が有効。
③ 説明しきれない都道府県要因(切片分散29.1)の正体を探す
結果 X
収容率と距離を入れても切片分散29.1が残る。原論文は県民性を候補に挙げる。
新仮説 Y
「県別の教育文化指標(社会調査の教育意識項目、私立高校比率、塾・予備校の密度など)が残りの切片分散を説明する」。
課題 Z
候補指標のデータ化と、モデル3への追加投入→切片分散の減少幅で判定(本論文の表8と同じ検証デザインが再利用できる)。

🎯 自分でやってみよう(5つのチャレンジ)

このページのスクリプト(code/2019_U3_suri.py)を出発点に、難易度順の5つの課題に挑戦してみましょう。

難易度 ★☆☆☆☆
CH1. 別の変数でICCを計算する
ステップ6の mixedlm の被説明変数を 65歳以上人口比率人口密度 に変えて、ICCを計算してみよう。どの変数が最も「都道府県で塊になっている」だろうか? 人口密度で試すなら対数変換(np.log1p)した方がよい理由も考えてみよう。
難易度 ★★☆☆☆
CH2. 図1を複数年度で描いて格差の推移を見る
ステップ2は最新年度(2023年度)のみ。SSDSE-B は2012〜2023年度を収録しているので、都道府県別進学率の最大値−最小値(レンジ)を年度ごとに計算して折れ線にしてみよう。地域格差は縮まっているか?
難易度 ★★★☆☆
CH3. ランダム切片モデルに説明変数を入れる(モデル2の型)
ステップ6のヌルモデルを拡張し、mixedlm('知識集約型産業従事者率 ~ 人口密度 + 65歳以上人口比率', ...) のように市区町村レベル変数を投入してみよう(原論文のモデル1→モデル2に相当する操作)。投入前後で res.cov_re(都道府県分散)と res.scale(残差分散)はどう変わるか?
難易度 ★★★★☆
CH4. 集団平均中心化の効果を実験で確かめる
CH3のモデルを「中心化なし」と「集団平均中心化あり」(ステップ5の列を利用)の2通りで推定し、係数を比較しよう。中心化なしの係数には市区町村レベルと都道府県レベルの影響が混在する——という原論文 脚注2の主張を、自分の実験結果で説明できれば合格。
難易度 ★★★★★
CH5. ランダム傾きモデルを推定する(モデル4の型)
mixedlm(..., re_formula='~人口密度') のように re_formula を指定すると傾きにもランダム効果が入る(原論文のモデル4に相当)。切片と傾きの共分散の符号はどうなったか? 収束しない場合は変数の標準化やスケーリングを試そう——「収束との闘い」自体が原論文の追体験である(原論文も計算の収束の問題で交差レベル交互作用を断念している)。
💡 ヒント: 詰まったら本サイトの他の論文(ランダム効果モデルを使っている 2019年 優秀賞など)のスクリプトをコピーして組み合わせるのが効率的です。手法ガイド・用語集も参考に。

💼 この手法は実社会でこう使われている

マルチレベル分析(階層線形モデル)は「個人がグループに入れ子になったデータ」がある所ならどこでも使われています。具体的なシーンを紹介します。

🏫
教育効果研究(生徒×学校)
「学級規模は成績に効くか」のような問いは、生徒(レベル1)×学校(レベル2)の典型的な階層データ。PISA・全国学力調査の公式分析でもマルチレベルモデルが標準装備です。本論文はその市町村×都道府県版といえます。
🏥
医療の質の評価(患者×病院)
手術成績の病院間比較では、患者の重症度(レベル1)を調整しつつ病院のランダム効果(レベル2)を推定します。病院の「切片」がまさに施設の実力の指標になります。
🏛️
行政の政策設計(市町村×都道府県)
本論文と同じ構図。市町村向け施策と都道府県向け施策を別レベルで設計し、「どのレベルに介入すると波及が大きいか」を分散成分から判断できます。
📈
マーケティング(店舗×地域)
チェーン店の売上分析では店舗(レベル1)×商圏・地域(レベル2)の階層を考慮しないと、地域要因を店舗の実力と誤認します。販促の「効き方」が地域で違う=ランダム傾きの発想もそのまま使われます。
🧠
心理学・反復測定(測定×個人)
同じ人を何度も測定する縦断研究では、測定(レベル1)×個人(レベル2)とみなして成長曲線をランダム切片・傾きでモデル化します。「傾きの個人差」の分析は本論文のモデル4と同型です。
🌏
国際比較調査(個人×国)
世界価値観調査などの国際比較では、個人の回答(レベル1)に国の制度・文化(レベル2)がどう効くかをマルチレベルで分析します。国ごとの「効き方の違い」も交差レベル交互作用で検証されます。

🤔 よくある質問(読者からの想定Q&A)

この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。

Q1. マルチレベル分析と「都道府県ダミーを入れた重回帰」は何が違うのですか?
ダミー変数(固定効果)でも県ごとの切片の違いは表現できます。しかしその場合、切片を46個の係数として使い切ってしまうため、「大学収容率」「距離」のような都道府県レベル変数を追加で入れることができません(完全な多重共線性になる)。ランダム切片として扱えば、切片のばらつきを分散1つで表現でき、その分散を都道府県レベル変数で「説明する」という本論文の分析(表8)が可能になります。
Q2. この分析、自分でも再現できますか?
原論文のモデルの完全再現は、被説明変数(市町村別大学等進学率)と所得データが SSDSE 未収録のためできません。e-Stat の学校基本調査(市町村集計)と市町村税課税状況等の調から自分でデータを組めば再現に挑戦できます。手法そのものは本ページのスクリプトで SSDSE-A を使ってすぐに体験できます(ステップ5・6)。
Q3. モデル4で所得の係数が0.46から1.16に跳ね上がったのはなぜですか?
モデル4では所得の傾きが「全国共通の固定部分(1.16)+県ごとのランダムなずれ」に分解されます。固定部分は県ごとの傾きの平均的な水準を表すようになり、モデル2・3の「全市町村を一律とみなした傾き0.46」とは推定対象の意味が変わります。切片との負の共分散(−1.19)が示すように、切片の大きい県では傾きが小さくなる方向に調整されるため、単純な大小比較はできません(原論文 表7 の報告値)。
Q4. 結論は「所得を上げれば進学率が上がる」という因果関係を示していますか?
いいえ。観察データの分析であり「強い関連」を示したにとどまります。原論文自身が、具体的な政策提言には因果関係の議論と投資効果の検討が必要と明記しています。また著者は「大学進学便益」を同時決定性(進学率が低い地域ほど大卒プレミアムが高まる逆経路)を理由に説明変数から外しており、因果の向きの難しさに自覚的です。
Q5. もっと深く学ぶには何を読めばいいですか?
マルチレベル分析の入門書(『マルチレベル分析入門』など階層線形モデルの教科書)が最短ルートです。中心化の選択については原論文も参照している Enders and Tofighi (2007, Psychological Methods) が定番。Python なら statsmodels の MixedLM、R なら lme4 パッケージのドキュメントが実践的です。本サイトの他の論文(ランダム効果モデルを使った2019年優秀賞など)との読み比べも効果的です。

✅ 理解度チェック(4問)

この論文を理解できたか、クリックで確認しましょう。間違えても解説が出ます。

🐍 ブラウザで動かす — インストール不要でこの論文の分析を再現する

このページの分析は、この画面の中でそのまま実行できます。 Python をインストールする必要も、CSV をダウンロードする必要もありません。 下のセルの 「▶ ブラウザで実行」 を上から順に押すか、 「▶ 最初から全部実行」 で一気に流してください。 表示されるのは、本文の図表とまったく同じ計算の結果です (動かしているのは再現スクリプト code/2019_U3_suri.py そのもの)。

コードは書き換えられます。「✏️ 書き換える」で数字や変数を変えて ▶ を押すと、 結果がどう変わるかをその場で確かめられます(元に戻すボタンつき)。 ページを開いた時点で裏で実行環境の準備が始まっているので、待ち時間はほとんどありません。 初回だけ実行環境の取得にインターネット接続が必要です。