このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本の選挙投票率は長期的に低下傾向にあり、特に地域間での格差が問題視されている。 投票率が高い地域・低い地域には、どのような社会経済的特徴の差異があるのか。 この問いに対して、都道府県別データを用いたOLS回帰分析・相関分析・時系列分析・地域別比較によって 定量的に迫るのが本研究のアプローチである。
まず「投票率の地域差都道府県別社会経済要因の回帰分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
本教育用コードでは、SSDSE-B(都道府県別統計)を用いて、 投票率の代理指標として「旅券発行率」(市民活動・社会参加意識の代理)を採用し、 論文と同様の分析手法を再現する。
SSDSE-B OLS回帰 相関分析 時系列分析 代理変数
社会科学の実証研究では、関心のある変数が直接入手できない場合に、 理論的・経験的に関連する代理変数(Proxy Variable)を用いることが標準的手法である。 本分析では以下の代理変数を設計した。
| 代理変数 | 計算式 | 代理する概念 | 理論的根拠 |
|---|---|---|---|
| 旅券発行率 | 一般旅券発行件数 / 総人口 × 1000 | 市民活動・社会参加意識 | 社会参加への積極性が高い市民は投票にも参加しやすい |
| 婚姻率 | 婚姻件数 / 総人口 × 1000 | 社会的絆・地域帰属意識 | Putnamの社会資本理論:絆が強い地域は集合的行動(投票)が活発 |
| 大学進学率 | 高校卒業者のうち進学者数 / 高校卒業者数 × 100 | 教育水準→政治関心 | 高学歴ほど政治的有効性感覚が高く投票率が高い傾向がある |
| 高齢化率 | 65歳以上人口 / 総人口 × 100 | 高齢化→投票率(正?負?) | 高齢者は投票率が高いが、過度な高齢化は社会活力低下も |
| 消費支出(対数) | log(消費支出(二人以上の世帯)) | 生活水準・経済力 | 経済的余裕が政治参加の機会コストを下げる |
代理変数を設計する際には「理論的妥当性」と「測定可能性」のバランスが重要である。 旅券発行率は海外旅行・ビジネス渡航など様々な要因に左右されるが、 社会的活発さ・市民活動性との相関は先行研究でも確認されている。 代理変数を使う際は、その限界(バイアスの方向性)を明示することが求められる。
2012年〜2023年の期間、6地域ブロック別に旅券発行率(千人あたり旅券発行件数)の平均値を追跡する。 この時系列パターンから、地域による市民活動性の恒常的な格差と、 新型コロナウイルス感染症(2020〜2021年)による一時的な落ち込みを確認できる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from scipy import stats import statsmodels.api as sm import warnings warnings.filterwarnings('ignore') plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 import os FIG_DIR = 'html/figures' DATA_B = 'data/raw/SSDSE-B-2026.csv' os.makedirs(FIG_DIR, exist_ok=True) df_b = pd.read_csv(DATA_B, encoding='cp932', header=1) df_b = df_b[df_b['地域コード'].str.match(r'^R\d{5}$', na=False)].copy() df_b['年度'] = df_b['年度'].astype(int) df_b = df_b.sort_values(['都道府県', '年度']).reset_index(drop=True) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。matplotlib.use('Agg') — グラフを画面表示せずファイルに保存するためのおまじない。plt.rcParams['font.family'] — グラフの日本語表示用フォント指定(Macは Hiragino Sans、Windowsなら Yu Gothic 等)。os.makedirs('html/figures', exist_ok=True) — 図の保存先フォルダを作る(既にあってもOK)。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。.astype(int) — 列を整数に変換(年度などを数値比較するため)。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。24 25 26 27 28 29 30 31 32 33 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 | # 変数生成 df_b['旅券発行率'] = df_b['一般旅券発行件数'] / df_b['総人口'] * 1000 df_b['婚姻率'] = df_b['婚姻件数'] / df_b['総人口'] * 1000 df_b['大学進学率'] = df_b['高等学校卒業者のうち進学者数'] / df_b['高等学校卒業者数'].replace(0, np.nan) * 100 df_b['高齢化率'] = df_b['65歳以上人口'] / df_b['総人口'] * 100 df_b['消費支出_log'] = np.log(df_b['消費支出(二人以上の世帯)'].clip(lower=1)) df_b['住宅地価_log'] = np.log(df_b['標準価格(平均価格)(住宅地)'].clip(lower=1)) region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄', } df_b['地域'] = df_b['都道府県'].map(region_map) region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12', } fig, ax = plt.subplots(figsize=(10, 5)) yearly = df_b.groupby(['年度', '地域'])['旅券発行率'].mean().reset_index() for reg, grp in yearly.groupby('地域'): ax.plot(grp['年度'], grp['旅券発行率'], marker='o', markersize=4, label=reg, color=region_colors.get(reg, 'gray')) ax.set_xlabel('年度', fontsize=12) ax.set_ylabel('旅券発行率(件/千人)', fontsize=12) ax.set_title('地域別 旅券発行率の推移(2012〜2023年)\n(社会参加・市民活動の代理指標)', fontsize=13, fontweight='bold') ax.legend(fontsize=9) ax.grid(alpha=0.3) plt.tight_layout() plt.savefig(os.path.join(FIG_DIR, '2022_H3_fig1_ts.png'), dpi=150, bbox_inches='tight') plt.close() print("Fig1 saved") |
Fig1 saved
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。2022年の都道府県横断データ(N=47)を用いて、旅券発行率・婚姻率・大学進学率・ 高齢化率・消費支出(対数)・住宅地価(対数)の6変数間の Pearson相関係数を算出した。
| 変数ペア | 相関係数(推定) | 解釈 |
|---|---|---|
| 旅券発行率 × 大学進学率 | 正(強) | 教育水準が高い地域は市民活動も活発 |
| 旅券発行率 × 婚姻率 | 正(中〜強) | 社会的絆が強い地域は社会参加も活発 |
| 旅券発行率 × 高齢化率 | 負(中) | 高齢化が進むほど旅券発行率が低い(若い人が多い地域で活発) |
| 大学進学率 × 高齢化率 | 負(強) | 高齢化地域は若者(進学者)が少ない:多重共線性の注意点 |
| 消費支出_log × 旅券発行率 | 正(弱〜中) | 所得・消費水準が高い地域は社会参加も高め |
相関係数r が「統計的に有意」とは、帰無仮説H₀:ρ=0(母相関係数がゼロ)を棄却できることを意味する。 N=47では検出力は限定的であり、|r|≥0.29程度でp<0.05となる目安がある。 「有意な相関」と「強い相関」を混同しないよう注意が必要。
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | df_2022 = df_b[df_b['年度'] == 2022].copy() analysis_vars = ['旅券発行率', '婚姻率', '大学進学率', '高齢化率', '消費支出_log', '住宅地価_log'] df_corr = df_2022[analysis_vars].dropna() corr = df_corr.corr() fig, ax = plt.subplots(figsize=(8, 6)) im = ax.imshow(corr, cmap='RdBu_r', vmin=-1, vmax=1) ax.set_xticks(range(len(analysis_vars))) ax.set_yticks(range(len(analysis_vars))) ax.set_xticklabels(analysis_vars, rotation=45, ha='right', fontsize=9) ax.set_yticklabels(analysis_vars, fontsize=9) for i in range(len(analysis_vars)): for j in range(len(analysis_vars)): val = corr.iloc[i, j] ax.text(j, i, f'{val:.2f}', ha='center', va='center', fontsize=8, color='white' if abs(val) > 0.5 else 'black') plt.colorbar(im, ax=ax, label='Pearson相関係数') ax.set_title('社会参加指標の相関ヒートマップ(2022年, N=47)', fontsize=13, fontweight='bold') plt.tight_layout() plt.savefig(os.path.join(FIG_DIR, '2022_H3_fig2_corr.png'), dpi=150, bbox_inches='tight') plt.close() print("Fig2 saved") |
Fig2 saved
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。相関分析で関連が示唆された変数を説明変数として、旅券発行率(社会参加の代理指標)を 目的変数とするOLS(最小二乗法)重回帰を実施した。
| 説明変数 | 係数(β) | 標準誤差 | t値 | p値 | 判定 |
|---|---|---|---|---|---|
| 定数項 | −70.18 | 51.02 | −1.376 | 0.176 | ns |
| 高齢化率 | −0.208 | 0.163 | −1.274 | 0.210 | ns |
| 大学進学率 | 0.183 | 0.043 | 4.244 | <0.001 | *** |
| 消費支出(対数) | 4.832 | 3.913 | 1.235 | 0.224 | ns |
| 婚姻率 | 3.308 | 1.110 | 2.979 | 0.005 | ** |
R²=0.824, 自由度修正済みR²=0.807, F統計量=49.11(p<0.001)
重回帰の偏回帰係数β は「他の説明変数を一定(コントロール)に保ったとき、 その変数が1単位増えた場合の目的変数の変化量」を意味する。 単純な相関係数と異なり、他変数の影響を取り除いた「純粋な」効果を推定する。
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | xvars = ['高齢化率', '大学進学率', '消費支出_log', '婚姻率'] df_reg = df_2022[['旅券発行率'] + xvars].dropna() X = sm.add_constant(df_reg[xvars]) res = sm.OLS(df_reg['旅券発行率'], X).fit() print(res.summary()) coefs = res.params.drop('const') ses = res.bse.drop('const') pvals = res.pvalues.drop('const') fig, ax = plt.subplots(figsize=(8, 5)) colors_c = ['#e05c5c' if p < 0.05 else '#888888' for p in pvals] ax.barh(range(len(coefs)), coefs, xerr=1.96 * ses, color=colors_c, alpha=0.8, error_kw={'elinewidth': 1.5, 'capsize': 4}) ax.set_yticks(range(len(coefs))) ax.set_yticklabels(coefs.index, fontsize=10) ax.axvline(0, color='black', linewidth=0.8) ax.set_xlabel('OLS回帰係数', fontsize=12) ax.set_title(f'旅券発行率の決定要因(N=47)\nR²={res.rsquared:.3f}(赤=p<0.05)', fontsize=12, fontweight='bold') ax.grid(axis='x', alpha=0.3) plt.tight_layout() plt.savefig(os.path.join(FIG_DIR, '2022_H3_fig3_ols.png'), dpi=150, bbox_inches='tight') plt.close() print("Fig3 saved") |
OLS Regression Results
==============================================================================
Dep. Variable: 旅券発行率 R-squared: 0.824
Model: OLS Adj. R-squared: 0.807
Method: Least Squares F-statistic: 49.11
Date: Mon, 18 May 2026 Prob (F-statistic): 2.67e-15
Time: 11:24:02 Log-Likelihood: -85.022
No. Observations: 47 AIC: 180.0
Df Residuals: 42 BIC: 189.3
Df Model: 4
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const -70.1813 51.017 -1.376 0.176 -173.138 32.775
高齢化率 -0.2083 0.163 -1.274 0.210 -0.538 0.122
大学進学率 0.1831 0.043 4.244 0.000 0.096 0.270
消費支出_log 4.8321 3.913 1.235 0.224 -3.066 12.730
婚姻率 3.3080 1.110 2.979 0.005 1.067 5.549
==============================================================================
Omnibus: 6.356 Durbin-Watson: 2.484
Prob(Omnibus): 0.042 Jarque-Bera (JB): 5.314
Skew: 0.640 Prob(JB): 0.0702
Kurtosis: 4.036 Cond. No. 1.49e+04
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.49e+04. This might indicate that there are
strong multicollinearity or other numerical problems.
Fig3 savedfig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。2022年時点の都道府県別旅券発行率を棒グラフで可視化する。 地域(6ブロック)を色分けすることで、地域的なパターンを視覚的に把握できる。
政治学者ロバート・パットナム(Robert Putnam)は、 「社会資本(Social Capital)」―市民間の信頼・ネットワーク・互酬性の規範―が 民主主義の機能(投票率を含む)を支えると論じた("Bowling Alone", 2000)。 本分析で確認された「婚姻率(社会的絆)→旅券発行率(社会参加)」の正の関係は、 Putnam理論の都道府県スケールでの統計的検証として解釈できる。
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | df_sorted = df_2022.sort_values('旅券発行率', ascending=True).dropna(subset=['旅券発行率']) fig, ax = plt.subplots(figsize=(8, 12)) bar_colors = [region_colors.get(df_sorted[df_sorted['都道府県'] == p]['地域'].values[0], 'gray') if len(df_sorted[df_sorted['都道府県'] == p]) > 0 else 'gray' for p in df_sorted['都道府県']] ax.barh(df_sorted['都道府県'], df_sorted['旅券発行率'], color=bar_colors, alpha=0.8) ax.axvline(df_2022['旅券発行率'].mean(), color='red', linestyle='--', linewidth=1.5, label=f'全国平均: {df_2022["旅券発行率"].mean():.2f}') ax.set_xlabel('旅券発行率(件/千人)', fontsize=12) ax.set_title('都道府県別 旅券発行率ランキング(2022年)', fontsize=13, fontweight='bold') ax.legend(fontsize=10) ax.grid(axis='x', alpha=0.3) plt.tight_layout() plt.savefig(os.path.join(FIG_DIR, '2022_H3_fig4_rank.png'), dpi=150, bbox_inches='tight') plt.close() print("Fig4 saved") print("All done!") |
Fig4 saved All done!
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。SSDSE-B(都道府県別統計)を用いた代理変数分析により、 社会参加(市民活動性)の都道府県間格差に関して以下の知見が得られた。
| 手法 | 目的 | 主な発見 |
|---|---|---|
| 時系列分析 | 地域差の経年変化を把握 | 都市部と地方の格差は構造的・持続的 |
| 相関ヒートマップ | 変数間の関連パターンの可視化 | 大学進学率・婚姻率と旅券発行率が正相関 |
| OLS回帰 | 各要因の独立した効果の推定 | 大学進学率・婚姻率が有意な正の効果 |
| 地域別ランキング | 都道府県間格差の可視化 | 上位は都市部、下位は農村部が集中 |
| データ | 出典 | 備考 |
|---|---|---|
| SSDSE-B-2026.csv | 統計数理研究所 SSDSE(社会・人口統計体系)都道府県データ | 2012〜2023年度, 47都道府県 |
| 一般旅券発行件数 | SSDSE-B収録(外務省・都道府県旅券事務所報告) | 旅券発行率の分子として使用 |
| 高等学校卒業者・進学者数 | SSDSE-B収録(文部科学省 学校基本調査) | 大学進学率の算出に使用 |
| 婚姻件数・総人口・65歳以上人口 | SSDSE-B収録(厚生労働省・総務省統計局) | 婚姻率・高齢化率の算出に使用 |
本教育用コードはすべて実データ(SSDSE-B-2026.csv)を使用。 合成データ・乱数生成は一切使用していない。 データファイルは統計数理研究所のウェブサイト(https://www.ism.ac.jp/SSDSE/)から入手可能。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。