このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
パットナム(Robert D. Putnam)が提唱したソーシャルキャピタル(社会関係資本)の概念は、「信頼・規範・ネットワーク」という無形の社会的資産が地域の経済効率・行政サービス・住民の幸福度を高めるという理論である。イタリア地域比較研究(1993年)でソーシャルキャピタルと行政パフォーマンスの正の関係を実証して以来、日本でも少子高齢化・地域格差の文脈でその測定と政策活用が注目されている。
まず「ボランティア・社会参加活動と地域コミュニティ指標の分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
日本では「コミュニティの希薄化」と「社会参加活動の地域格差」が政策課題となっている。本研究では、ソーシャルキャピタルの直接測定が困難なため、SSDSE-B(47都道府県統計)で取得できる代理変数を用いてコミュニティ指標を構築し、相関分析・重回帰分析・クラスタリングによってその地域的パターンを明らかにする。
ソーシャルキャピタル SSDSE-B 2022年 47都道府県 Ward法クラスタリング
SSDSE-B(社会・人口統計体系データセット B)2026年版を使用。2022年(令和4年)断面の47都道府県データを分析に用いる(n = 47)。
| データ名 | 提供元 | 対象年度 | サンプル数 |
|---|---|---|---|
| SSDSE-B-2026.csv | 統計センター(NSTAC) | 2022年度(令和4年) | 47都道府県 |
ソーシャルキャピタル・コミュニティ参加の直接指標は統計データとして整備されていないため、SSDSE-Bで入手可能な変数を代理変数(proxy variable)として採用する。
| 変数名 | 元データ | 計算式 | 理論的意味 | 予想効果 |
|---|---|---|---|---|
| 保育所数/千人 | 保育所等数 | 保育所等数÷総人口×1000 | 子育てコミュニティ基盤 | +(正) |
| 医療施設数/千人 | 一般病院数+一般診療所数 | (病院数+診療所数)÷総人口×1000 | 医療・福祉コミュニティ | +(正) |
| 幼稚園数/千人 | 幼稚園数 | 幼稚園数÷総人口×1000 | 就学前コミュニティ | +(正) |
| リサイクル率 | ごみのリサイクル率 | (%)そのまま | 市民参加・環境意識 | +(正) |
| 転出率/千人 | 転出者数(日本人移動者) | 転出者数÷総人口×1000 | 地域定着度(逆指標) | −(負) |
| 高齢化率 | 65歳以上人口 | 65歳以上人口÷総人口×100 | 高齢コミュニティ構造 | ? |
| 合計特殊出生率 | 合計特殊出生率 | (そのまま) | 地域活力・若年層定着 | +(正) |
| 【目的変数】 教養娯楽費 | 教養娯楽費(二人以上世帯) | (円、そのまま) | 社会参加・余暇活動への支出 = 社会参加指標の代理 | — |
ソーシャルキャピタルのような「直接観測不可能な概念」を統計的に分析するには、理論的に関連する観測可能な変数(代理変数)を用いる。代理変数の妥当性は、概念的整合性・データの信頼性・多重共線性の検討によって評価される。
1 2 3 4 5 6 7 | pop = df['総人口'] # (1) 保育所数/千人 … 子育てコミュニティの代理変数 df['保育所数_千人'] = df['保育所等数'] / pop * 1000 # (2) 病院・診療所数/千人 … 医療・地域福祉の代理変数 df['医療施設数_千人'] = (df['一般病院数'] + df['一般診療所数']) / pop * 1000 |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。8 9 10 11 12 13 14 15 | # (3) 幼稚園数/千人 … 就学前教育コミュニティ df['幼稚園数_千人'] = df['幼稚園数'] / pop * 1000 # (4) 教養娯楽費(社会参加コストの代理) df['教養娯楽費'] = df['教養娯楽費(二人以上の世帯)'] # (5) ごみのリサイクル率 … 環境意識・市民参加の代理変数 df['リサイクル率'] = df['ごみのリサイクル率'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。16 17 18 19 20 21 22 23 | # (6) 転出率 … 低いほど地域定着(地域凝集性の逆指標) df['転出率_千人'] = df['転出者数(日本人移動者)'] / pop * 1000 # (7) 高齢化率 … コミュニティ構造の指標 df['高齢化率'] = df['65歳以上人口'] / pop * 100 # (8) 合計特殊出生率 … 地域活力・若年層定着の指標 df['出生率'] = df['合計特殊出生率'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。24 25 26 27 28 29 | # 目的変数: 教養娯楽費(社会参加・余暇活動への支出 = 社会参加指標の代理) Y_NAME = '教養娯楽費' # 説明変数 X_NAMES = ['保育所数_千人', '医療施設数_千人', '幼稚園数_千人', 'リサイクル率', '転出率_千人', '高齢化率', '出生率'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # 地域区分マップ region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } df['地域'] = df['都道府県'].map(region_map) df['地域色'] = df['地域'].map(region_colors) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。53 54 55 56 | # 分析用サブデータ(欠損除去) cols_use = [Y_NAME] + X_NAMES dfa = df[['都道府県', '地域', '地域色'] + cols_use].dropna().copy() print(f"分析対象: {len(dfa)}都道府県") |
分析対象: 47都道府県
df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。社会参加関連変数8変数(目的変数を含む)のPearson相関行列を可視化する。赤色が正相関、青色が負相関を示す。
市民参加意識の代理変数「リサイクル率」と目的変数「教養娯楽費」の散布図を地域色別に表示する。回帰直線(点線)は有意な正の傾向(r = 0.293, p = 0.046)を示す。
| 変数ペア | 相関係数 r | p値 | 判定 |
|---|---|---|---|
| リサイクル率 vs 教養娯楽費 | 0.293 | 0.046 | 有意(p < 0.05) |
| 保育所数/千人 vs 教養娯楽費 | −0.566 | <0.001 | 有意(p < 0.001) |
| 高齢化率 vs 教養娯楽費 | −0.463 | 0.001 | 有意(p < 0.01) |
| 合計特殊出生率 vs 教養娯楽費 | −0.525 | <0.001 | 有意(p < 0.001) |
相関係数 r は−1から+1の範囲をとり、2変数の線形関係の強さと方向を表す。帰無仮説「母相関 = 0」に対する検定(t検定)でp < 0.05であれば「有意な相関あり」と判断する。ただし相関は因果関係を意味しない点に注意が必要である。
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | fig1, ax1 = plt.subplots(figsize=(9, 7)) n = len(corr_mat) im = ax1.imshow(corr_mat.values, cmap='RdBu_r', vmin=-1, vmax=1, aspect='auto') plt.colorbar(im, ax=ax1, fraction=0.04, pad=0.04) ax1.set_xticks(range(n)) ax1.set_yticks(range(n)) ax1.set_xticklabels(corr_mat.columns, fontsize=9, rotation=45, ha='right') ax1.set_yticklabels(corr_mat.columns, fontsize=9) for i in range(n): for j in range(n): val = corr_mat.values[i, j] color = 'white' if abs(val) > 0.55 else 'black' ax1.text(j, i, f'{val:.2f}', ha='center', va='center', fontsize=8, color=color, fontweight='bold') ax1.set_title('社会参加関連変数のPearson相関行列(2022年・47都道府県)', fontsize=13, pad=15) fig1.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2020_U5_1_fig1.png'), dpi=150, bbox_inches='tight') plt.close(fig1) print("fig1 保存完了") |
fig1 保存完了
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。複数のコミュニティ指標変数が「社会参加指標(教養娯楽費)」に与える独立した影響を、重回帰分析によって定量化する。解釈を容易にするため、全変数を標準化(Z変換)してから回帰分析を行い、標準化偏回帰係数 β を比較する。
| 説明変数 | 標準化偏回帰係数 β | p値 | 有意性 |
|---|---|---|---|
| 保育所数/千人 | −0.228 | 0.186 | n.s. |
| 医療施設数/千人 | +0.050 | 0.733 | n.s. |
| 幼稚園数/千人 | +0.033 | 0.801 | n.s. |
| リサイクル率 | +0.226 | 0.070 | n.s. (p < 0.10) |
| 転出率/千人 | −0.140 | 0.389 | n.s. |
| 高齢化率 | −0.344 | 0.045 | * p < 0.05 |
| 合計特殊出生率 | −0.344 | 0.055 | n.s. (p < 0.10) |
説明変数が異なる単位・スケールを持つ場合、標準化(平均0・標準偏差1に変換)してから回帰を行うと、偏回帰係数の絶対値が変数の「相対的重要度」を直接比較できるようになる。これが標準化偏回帰係数 β(ベータ係数)である。
78 79 80 81 82 83 84 85 | fig2, ax2 = plt.subplots(figsize=(9, 6)) for region, grp in dfa.groupby('地域'): ax2.scatter(grp['リサイクル率'], grp[Y_NAME], color=region_colors[region], s=60, label=region, zorder=3, alpha=0.85) for _, row in grp.iterrows(): ax2.annotate(row['都道府県'], (row['リサイクル率'], row[Y_NAME]), fontsize=6.5, ha='center', va='bottom', xytext=(0, 4), textcoords='offset points', color='#333') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | # 回帰線 x_plot = dfa['リサイクル率'].values y_plot = dfa[Y_NAME].values slope, intercept, r_val, p_val, _ = stats.linregress(x_plot, y_plot) x_line = np.linspace(x_plot.min(), x_plot.max(), 100) ax2.plot(x_line, slope * x_line + intercept, color='#333', linewidth=1.5, linestyle='--', zorder=2) ax2.set_xlabel('ごみのリサイクル率(%)', fontsize=11) ax2.set_ylabel('教養娯楽費(円,二人以上世帯)', fontsize=11) ax2.set_title(f'リサイクル率と社会参加指標の関係\n(r = {r_val:.3f}, p = {p_val:.4f}, 47都道府県, 2022年)', fontsize=12) ax2.legend(loc='upper left', fontsize=9, framealpha=0.85) ax2.grid(True, alpha=0.3, linestyle='--') fig2.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2020_U5_1_fig2.png'), dpi=150, bbox_inches='tight') plt.close(fig2) print("fig2 保存完了") print(f" リサイクル率 vs 教養娯楽費: r={r_val:.3f}, p={p_val:.4f}") |
fig2 保存完了 リサイクル率 vs 教養娯楽費: r=0.293, p=0.0458
stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。47都道府県を「社会参加・地域コミュニティ特性」の観点から類型化するため、7つのコミュニティ指標変数(説明変数)を用いたWard法階層クラスタリングを実施する。変数は全て標準化したうえでユークリッド距離に基づいてクラスタリングする。
| クラスター類型 | 主な都道府県 | コミュニティ特性 |
|---|---|---|
| 大都市型 | 東京都・大阪府・神奈川県・愛知県・埼玉県 | 高社会参加費・低保育所密度・低高齢化 |
| 地方中核都市型 | 宮城県・広島県・福岡県・石川県・静岡県 | 中規模コミュニティ・バランス型 |
| 地方農村型 | 秋田県・島根県・山形県・鳥取県・高知県 | 高齢化率高・リサイクル率低・保育所密度高 |
| 九州・南方型 | 沖縄県・宮崎県・鹿児島県・熊本県 | 高出生率・独自コミュニティ構造 |
Ward法は、クラスター内の平方和(分散)の増加量が最小になるよう逐次的に結合する階層クラスタリング手法である。デンドログラム(樹形図)の縦軸は「Ward距離」を示し、長い結合線は性質が大きく異なるグループが合流していることを意味する。
105 106 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 | x_labels = [ '保育所数/千人', '医療施設数/千人', '幼稚園数/千人', 'リサイクル率', '転出率/千人', '高齢化率', '合計特殊出生率' ] sorted_idx = np.argsort(coefs) sorted_coefs = coefs[sorted_idx] sorted_labels = [x_labels[i] for i in sorted_idx] sorted_pvals = pvals[sorted_idx] sorted_ci_lo = conf.values[sorted_idx, 0] sorted_ci_hi = conf.values[sorted_idx, 1] colors_bar = ['#e05c5c' if p < 0.05 else '#aab4c8' for p in sorted_pvals] fig3, ax3 = plt.subplots(figsize=(8, 5)) bars = ax3.barh(range(len(sorted_coefs)), sorted_coefs, color=colors_bar, height=0.55, zorder=3) for i, (lo, hi) in enumerate(zip(sorted_ci_lo, sorted_ci_hi)): ax3.plot([lo, hi], [i, i], color='#555', linewidth=1.5, zorder=4) ax3.plot([lo, lo], [i - 0.15, i + 0.15], color='#555', linewidth=1.5, zorder=4) ax3.plot([hi, hi], [i - 0.15, i + 0.15], color='#555', linewidth=1.5, zorder=4) ax3.axvline(0, color='#333', linewidth=1, linestyle='-') ax3.set_yticks(range(len(sorted_labels))) ax3.set_yticklabels(sorted_labels, fontsize=10) ax3.set_xlabel('標準化偏回帰係数 (β)', fontsize=11) ax3.set_title(f'重回帰分析:標準化偏回帰係数\n(目的変数:教養娯楽費, R²={ols_model.rsquared:.3f})', fontsize=12) ax3.grid(True, axis='x', alpha=0.3, linestyle='--') # 有意・非有意の凡例 from matplotlib.patches import Patch legend_elements = [Patch(facecolor='#e05c5c', label='p < 0.05(有意)'), Patch(facecolor='#aab4c8', label='p ≥ 0.05(非有意)')] ax3.legend(handles=legend_elements, loc='lower right', fontsize=9) fig3.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2020_U5_1_fig3.png'), dpi=150, bbox_inches='tight') plt.close(fig3) print("fig3 保存完了") |
fig3 保存完了
import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。分析結果から得られた知見をもとに、地域コミュニティ活性化と社会参加促進のための政策提言を以下に示す。
高齢化率が有意に社会参加を抑制する結果(β = −0.344)を踏まえ、高齢者が参加しやすいコミュニティ活動の設計・インフラ整備が必要。サロン活動・地域カフェなどの低コスト参加型の場の創出が有効。
リサイクル率と社会参加の正の関係(r = 0.293)は、環境施策が市民参加意識全般を高める「スピルオーバー効果」を示唆する。ごみ分別・資源循環活動を地域コミュニティ活動の入口として位置付ける戦略が有効。
クラスタリング分析は4つの地域類型を示した。大都市型・地方農村型ではコミュニティ課題の性質が異なるため、一律の政策ではなく地域類型に応じた差別化された介入が必要。
保育所整備(単純相関 r = −0.566)が都市化・人口規模と交絡している点に留意しつつ、子育てサポートネットワーク(ファミリーサポートセンター等)の充実が地域定着と社会参加向上に貢献すると考えられる。
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | 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 from scipy import stats from sklearn.preprocessing import StandardScaler from scipy.cluster.hierarchy import dendrogram, linkage plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 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) |
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) — 列を整数に変換(年度などを数値比較するため)。StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。163 164 165 | # 2022年断面 df = df_b[df_b['年度'] == 2022].copy().reset_index(drop=True) assert len(df) == 47, f"47都道府県になっていません: {len(df)}行" |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。166 167 168 169 170 171 172 173 174 175 176 177 178 179 | corr_vars = cols_use corr_labels = { '教養娯楽費': '教養娯楽費\n(社会参加指標)', '保育所数_千人': '保育所数\n/千人', '医療施設数_千人': '医療施設数\n/千人', '幼稚園数_千人': '幼稚園数\n/千人', 'リサイクル率': 'リサイクル率', '転出率_千人': '転出率\n/千人', '高齢化率': '高齢化率', '出生率': '合計特殊\n出生率', } corr_df = dfa[corr_vars].copy() corr_df.columns = [corr_labels[c] for c in corr_vars] corr_mat = corr_df.corr() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | X_raw = dfa[X_NAMES].values y_raw = dfa[Y_NAME].values scaler_x = StandardScaler() X_std = scaler_x.fit_transform(X_raw) scaler_y = StandardScaler() y_std = scaler_y.fit_transform(y_raw.reshape(-1, 1)).flatten() X_sm = sm.add_constant(X_std) ols_model = sm.OLS(y_std, X_sm).fit() print("\n=== 標準化OLS 結果 ===") print(ols_model.summary()) coefs = ols_model.params[1:] # 定数項を除く pvals = ols_model.pvalues[1:] conf_arr = ols_model.conf_int() if hasattr(conf_arr, 'iloc'): conf = conf_arr.iloc[1:] else: conf = pd.DataFrame(conf_arr[1:], columns=['lower', 'upper']) |
=== 標準化OLS 結果 ===
OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.500
Model: OLS Adj. R-squared: 0.411
Method: Least Squares F-statistic: 5.578
Date: Mon, 18 May 2026 Prob (F-statistic): 0.000167
Time: 11:23:44 Log-Likelihood: -50.386
No. Observations: 47 AIC: 116.8
Df Residuals: 39 BIC: 131.6
Df Model: 7
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const -1.249e-16 0.113 -1.1e-15 1.000 -0.229 0.229
x1 -0.2283 0.170 -1.346 0.186 -0.571 0.115
x2 0.0500 0.146 0.344 0.733 -0.244 0.345
x3 0.0326 0.129 0.254 0.801 -0.228 0.293
x4 0.2255 0.121 1.865 0.070 -0.019 0.470
x5 -0.1401 0.161 -0.871 0.389 -0.465 0.185
x6 -0.3435 0.166 -2.067 0.045 -0.680 -0.007
x7 -0.3435 0.173 -1.982 0.055 -0.694 0.007
==============================================================================
Omnibus: 7.882 Durbin-Watson: 1.662
Prob(Omnibus): 0.019 Jarque-Bera (JB): 6.848
Skew: 0.853 Prob(JB): 0.0326
Kurtosis: 3.764 Cond. No. 3.61
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。199 200 201 202 203 204 205 206 207 208 | cluster_vars = X_NAMES X_clust = dfa[cluster_vars].values scaler_c = StandardScaler() X_clust_std = scaler_c.fit_transform(X_clust) Z = linkage(X_clust_std, method='ward', metric='euclidean') # 都道府県ラベルに地域名を付与 pref_labels = [f"{row['都道府県']}" for _, row in dfa.iterrows()] leaf_colors_list = [dfa.iloc[i]['地域色'] for i in range(len(dfa))] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | fig4, ax4 = plt.subplots(figsize=(14, 6)) dend = dendrogram(Z, labels=pref_labels, ax=ax4, color_threshold=0.7 * max(Z[:, 2]), leaf_rotation=90, leaf_font_size=8.5) # 葉ラベルに地域色を適用 xlabels = ax4.get_xticklabels() for lbl in xlabels: pref = lbl.get_text() row = dfa[dfa['都道府県'] == pref] if not row.empty: lbl.set_color(row.iloc[0]['地域色']) ax4.set_title('Ward法階層クラスタリング:社会参加・地域コミュニティ特性(47都道府県, 2022年)', fontsize=12) ax4.set_ylabel('Ward距離', fontsize=10) ax4.set_xlabel('') ax4.grid(True, axis='y', alpha=0.3, linestyle='--') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。225 226 227 228 229 230 231 232 233 234 235 | # 地域凡例 handles_legend = [ plt.Line2D([0], [0], marker='o', color='w', markerfacecolor=c, markersize=8, label=r) for r, c in region_colors.items() ] ax4.legend(handles=handles_legend, title='地域区分', loc='upper right', fontsize=8, title_fontsize=9) fig4.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2020_U5_1_fig4.png'), dpi=150, bbox_inches='tight') plt.close(fig4) print("fig4 保存完了") |
fig4 保存完了
{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | print("\n=== KEY STATISTICS ===") print(f"サンプル数: {len(dfa)}") print(f"R²: {ols_model.rsquared:.4f}") print(f"Adj R²: {ols_model.rsquared_adj:.4f}") print(f"F統計量: {ols_model.fvalue:.3f}, p={ols_model.f_pvalue:.4f}") print("\n各変数の標準化偏回帰係数:") for name, lbl in zip(X_NAMES, x_labels): idx = X_NAMES.index(name) print(f" {lbl}: β={coefs[idx]:.4f}, p={pvals[idx]:.4f}") # リサイクル率と教養娯楽費の相関 r_rc, p_rc = stats.pearsonr(dfa['リサイクル率'], dfa[Y_NAME]) r_bs, p_bs = stats.pearsonr(dfa['保育所数_千人'], dfa[Y_NAME]) r_ko, p_ko = stats.pearsonr(dfa['高齢化率'], dfa[Y_NAME]) r_ou, p_ou = stats.pearsonr(dfa['出生率'], dfa[Y_NAME]) print(f"\nリサイクル率 vs 教養娯楽費: r={r_rc:.4f}, p={p_rc:.4f}") print(f"保育所数/千人 vs 教養娯楽費: r={r_bs:.4f}, p={p_bs:.4f}") print(f"高齢化率 vs 教養娯楽費: r={r_ko:.4f}, p={p_ko:.4f}") print(f"出生率 vs 教養娯楽費: r={r_ou:.4f}, p={p_ou:.4f}") print("\n全図の生成が完了しました。") |
=== KEY STATISTICS === サンプル数: 47 R²: 0.5003 Adj R²: 0.4106 F統計量: 5.578, p=0.0002 各変数の標準化偏回帰係数: 保育所数/千人: β=-0.2283, p=0.1861 医療施設数/千人: β=0.0500, p=0.7329 幼稚園数/千人: β=0.0326, p=0.8012 リサイクル率: β=0.2255, p=0.0698 転出率/千人: β=-0.1401, p=0.3889 高齢化率: β=-0.3435, p=0.0454 合計特殊出生率: β=-0.3435, p=0.0546 リサイクル率 vs 教養娯楽費: r=0.2927, p=0.0458 保育所数/千人 vs 教養娯楽費: r=-0.5657, p=0.0000 高齢化率 vs 教養娯楽費: r=-0.4628, p=0.0011 出生率 vs 教養娯楽費: r=-0.5247, p=0.0002 全図の生成が完了しました。
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。本研究では、ソーシャルキャピタル・社会参加活動と地域コミュニティ指標の関係を、SSDSE-B(47都道府県)の2022年データを用いて統計的に分析した。相関分析・重回帰分析・Ward法クラスタリングの3手法を組み合わせることで、以下の主要な知見が得られた。
本研究の手法論的な特徴は、代理変数の理論的構築→相関分析による変数選択→標準化回帰による変数重要度の定量化→クラスタリングによる地域類型化というデータサイエンスの標準的な分析フローを統計コンペの文脈で実践した点にある。今後は、ボランティア登録者数・NPO法人数などの直接指標を組み込んだ分析、および時系列パネルデータによる因果推論へと発展させることが期待される。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。