このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本における住宅価格は都市と地方で大きな格差が生じており、その構造的要因を定量的に解明することは政策立案上も重要である。本研究は SSDSE-B の都道府県パネルデータ(47都道府県 × 12年)を用いて、住宅地価格の格差を生む要因を重回帰・Ridge・Lasso・空間パネルモデルで分析した。
まず「住宅価格の格差と影響を与える要因―空間パネルモデルに基づく研究―」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
SSDSE-B パネルデータ Ridge・Lasso 空間的自己相関
SSDSE(社会・人口統計体系)-B は都道府県レベルの統計データを収録する。本分析では 2012〜2023 年の 12 年間、47 都道府県の合計 564 件(=47×12)を使用する。
| 項目 | 内容 |
|---|---|
| 対象 | 47都道府県(地域コード R〇〇〇〇〇) |
| 期間 | 2012〜2023年(12年間) |
| 観測数 | 564件(47×12) |
| 目的変数 | 標準価格(平均価格)(住宅地)[円/㎡] |
| 変数名 | 単位 | 想定効果 |
|---|---|---|
| 総人口 | 人 | 正(需要増加) |
| 月間有効求人数(一般) | 件 | 正(雇用活発 → 流入) |
| 月間有効求職者数(一般) | 人 | 負(労働供給過多) |
| 消費支出(二人以上の世帯) | 円/月 | 正(所得水準反映) |
| 65歳以上人口 | 人 | 負(高齢化 → 需要減) |
| 大学学生数 | 人 | 正(都市機能) |
| 着工新設住宅戸数 | 戸 | 負(供給増 → 価格下落) |
| 標準価格(商業地) | 円/㎡ | 正(都市活力との連動) |
SSDSE-B は header=1 で読み込み、地域コードが R で始まる都道府県行のみ抽出する。
1 2 3 4 5 6 7 8 | 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() print("=" * 60) print(f"■ 読み込み完了: {len(df_b)}行 × {df_b.shape[1]}列") print(f" 年度: {sorted(df_b['年度'].unique())}") print(f" 都道府県数: {df_b['都道府県'].nunique()}") print("=" * 60) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # ── 使用列 ───────────────────────────────────────────────────── TARGET = '標準価格(平均価格)(住宅地)' FEATURES = [ '総人口', '月間有効求人数(一般)', '月間有効求職者数(一般)', '消費支出(二人以上の世帯)', '65歳以上人口', '大学学生数', '着工新設住宅戸数', '標準価格(平均価格)(商業地)', ] FEATURE_LABELS = [ '総人口', '有効求人数', '有効求職者数', '消費支出', '65歳以上人口', '大学学生数', '着工新設住宅戸数', '商業地価格', ] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。33 34 35 36 37 38 39 | # 数値変換 for c in [TARGET] + FEATURES: df_b[c] = pd.to_numeric(df_b[c], errors='coerce') # 欠損除外 df_clean = df_b.dropna(subset=[TARGET] + FEATURES).copy() print(f"欠損除外後: {len(df_clean)}行") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | # 2022年断面データ df_2022 = df_b[df_b['年度'] == 2022].copy() df_2022 = df_2022.dropna(subset=[TARGET] + FEATURES).reset_index(drop=True) print(f"2022年データ: N={len(df_2022)}") # ── 地域区分(大都市圏 / 地方) ───────────────────────────────── URBAN = ['東京都', '神奈川県', '埼玉県', '千葉県', '大阪府', '京都府', '愛知県', '兵庫県'] def region_label(pref): if pref == '東京都': return '東京都' elif pref in URBAN: return '主要都市圏' else: return '地方' df_2022['地域区分'] = df_2022['都道府県'].apply(region_label) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # 地域区分カラーマップ REGION_COLOR = {'東京都': '#C62828', '主要都市圏': '#1565C0', '地方': '#43A047'} # ── 時系列用: 代表都道府県の選択 ──────────────────────────────── # 都市圏: 東京都, 大阪府, 愛知県 地方: 北海道, 宮城県, 福岡県, 鹿児島県 PREF_TS = { '東京都': ('#C62828', '-', 'D'), '大阪府': ('#E65100', '--', 's'), '愛知県': ('#FF8F00', ':', '^'), '北海道': ('#1565C0', '-', 'o'), '宮城県': ('#0277BD', '--', 'v'), '福岡県': ('#1B5E20', ':', 'P'), '鹿児島県': ('#6A1B9A', '-.', 'X'), } |
============================================================ ■ 読み込み完了: 564行 × 112列 年度: [np.int64(2012), np.int64(2013), np.int64(2014), np.int64(2015), np.int64(2016), np.int64(2017), np.int64(2018), np.int64(2019), np.int64(2020), np.int64(2021), np.int64(2022), np.int64(2023)] 都道府県数: 47 ============================================================ 欠損除外後: 564行 2022年データ: N=47
x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。2012〜2023年にわたる住宅地価格の推移を、東京都・大阪府・愛知県(都市圏)と北海道・宮城県・福岡県・鹿児島県(地方)に分けて比較する。
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | fig1, ax1 = plt.subplots(figsize=(10, 6)) years = sorted(df_clean['年度'].unique()) for pref, (color, ls, marker) in PREF_TS.items(): ts = df_clean[df_clean['都道府県'] == pref].sort_values('年度') ax1.plot(ts['年度'], ts[TARGET] / 1000, color=color, linestyle=ls, marker=marker, markersize=5, linewidth=1.8, label=pref) ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('住宅地 標準価格(千円/㎡)', fontsize=12) ax1.set_title('住宅地価格の時系列推移(2012〜2023年)\n都市圏と地方の格差', fontsize=13, fontweight='bold') ax1.legend(loc='upper left', fontsize=9, ncol=2, framealpha=0.9) ax1.set_xticks(years) ax1.set_xticklabels([str(y) for y in years], rotation=45, ha='right', fontsize=9) ax1.grid(True, alpha=0.3) ax1.yaxis.set_major_formatter( matplotlib.ticker.FuncFormatter(lambda x, _: f'{x:,.0f}') ) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | # 都市 / 地方 の区分ラベル ax1.annotate('都市圏', xy=(2023, df_clean[(df_clean['都道府県']=='東京都') & (df_clean['年度']==2023)][TARGET].values[0] / 1000), xytext=(2021.5, 360), fontsize=10, color='#C62828', arrowprops=dict(arrowstyle='->', color='#C62828', lw=1.2)) ax1.annotate('地方', xy=(2023, df_clean[(df_clean['都道府県']=='鹿児島県') & (df_clean['年度']==2023)][TARGET].values[0] / 1000), xytext=(2021.0, 60), fontsize=10, color='#6A1B9A', arrowprops=dict(arrowstyle='->', color='#6A1B9A', lw=1.2)) plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2022_U5_16_fig1_ts.png'), bbox_inches='tight', dpi=150) plt.close(fig1) print("\n図1保存: 2022_U5_16_fig1_ts.png") |
図1保存: 2022_U5_16_fig1_ts.png
r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。2022年時点の住宅地価格(円/㎡)を47都道府県で比較する。都市圏(赤・青)と地方(緑)の色分けにより、空間的集積が一目で確認できる。
| 順位 | 都道府県 | 住宅地価格(千円/㎡) | 区分 |
|---|---|---|---|
| 1 | 東京都 | 389.1 | 東京都 |
| 2 | 神奈川県 | 183.3 | 主要都市圏 |
| 3 | 大阪府 | 152.2 | 主要都市圏 |
| 4 | 埼玉県 | 116.2 | 主要都市圏 |
| 5 | 京都府 | 109.9 | 主要都市圏 |
| 45 | 鳥取県 | 19.0 | 地方 |
| 46 | 青森県 | 15.9 | 地方 |
| 47 | 秋田県 | 13.2 | 地方 |
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | df_rank = df_2022[['都道府県', TARGET, '地域区分']].sort_values(TARGET).reset_index(drop=True) fig2, ax2 = plt.subplots(figsize=(9, 13)) colors2 = [REGION_COLOR[r] for r in df_rank['地域区分']] bars = ax2.barh( range(len(df_rank)), df_rank[TARGET] / 1000, color=colors2, alpha=0.82, edgecolor='white', height=0.75 ) ax2.set_yticks(range(len(df_rank))) ax2.set_yticklabels(df_rank['都道府県'], fontsize=9) ax2.set_xlabel('住宅地 標準価格(千円/㎡)', fontsize=11) ax2.set_title('47都道府県 住宅地価格ランキング(2022年)\nSSDSE-B 実データ', fontsize=12, fontweight='bold') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | # 東京都に値ラベル top_val = df_rank[TARGET].max() / 1000 ax2.text(top_val + 2, len(df_rank) - 1, f'{top_val:,.0f}', va='center', fontsize=8, color='#C62828', fontweight='bold') ax2.axvline(df_2022[TARGET].mean() / 1000, color='gray', linestyle='--', linewidth=1.2, label=f'全国平均={df_2022[TARGET].mean()/1000:.0f}千円/㎡') ax2.legend(fontsize=9, loc='lower right') ax2.grid(axis='x', alpha=0.3) from matplotlib.patches import Patch legend_handles = [ Patch(color=REGION_COLOR['東京都'], alpha=0.82, label='東京都'), Patch(color=REGION_COLOR['主要都市圏'], alpha=0.82, label='主要都市圏'), Patch(color=REGION_COLOR['地方'], alpha=0.82, label='地方'), ] ax2.legend(handles=legend_handles + [ plt.Line2D([0], [0], color='gray', linestyle='--', label=f'全国平均={df_2022[TARGET].mean()/1000:.0f}千円/㎡') ], fontsize=9, loc='lower right') plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2022_U5_16_fig2_rank.png'), bbox_inches='tight', dpi=150) plt.close(fig2) print("図2保存: 2022_U5_16_fig2_rank.png") |
図2保存: 2022_U5_16_fig2_rank.png
import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。8つの説明変数を StandardScaler で標準化したうえで OLS・Ridge(α=1.0)・Lasso(α=0.01)を適用し、標準化係数を比較する。正則化(Ridge・Lasso)は多重共線性への対処と変数選択に用いられる。
ペナルティなし。残差平方和を最小化。多重共線性があると係数が不安定になる。
係数の二乗和にペナルティ。全係数を一様に縮小するが、ゼロにはしない。
係数の絶対値和にペナルティ。不要な変数の係数を完全にゼロにして変数選択を行う。
| 変数 | OLS 係数 | p値 | 有意性 | Ridge 係数 | Lasso 係数 |
|---|---|---|---|---|---|
| 総人口 | 195,266 | <0.001 | *** | 19,031 | 195,248 |
| 有効求人数 | −17,129 | 0.024 | * | −20,221 | −17,129 |
| 有効求職者数 | 2,560 | 0.832 | n.s. | −7,094 | 2,556 |
| 消費支出 | 826 | 0.569 | n.s. | 1,518 | 826 |
| 65歳以上人口 | −107,300 | <0.001 | *** | 1,820 | −107,287 |
| 大学学生数 | 6,486 | 0.431 | n.s. | 20,418 | 6,486 |
| 着工新設住宅戸数 | −67,714 | <0.001 | *** | 11,116 | −67,706 |
| 商業地価格 | 46,970 | <0.001 | *** | 34,933 | 46,970 |
OLS: R²=0.988, F=393.3 (p<0.001), N=47都道府県(2022年断面)。係数は標準化後(単位:円/㎡)。
Ridge(L2正則化)とLasso(L1正則化)の本質的な違いは「ペナルティの形状」にある。L2ペナルティは係数の二乗和を罰するため、全係数を等割合で縮小し、ゼロにはしない。L1ペナルティは係数の絶対値和を罰するため、小さな係数を完全にゼロに落とす(スパース解)。住宅価格分析では多重共線性(総人口と65歳以上人口の相関など)が問題になるため、正則化は特に有効。
正則化強度 alpha を変化させると係数がどう変わるかを「正則化パス」として可視化できる。alpha が大きいほど収縮が強まり、最終的に全係数がゼロに近づく(Ridge)またはゼロになる(Lasso)。この可視化により、どの変数が「安定して重要か」「どの alpha で変数が脱落するか」を直感的に把握できる。
正則化の強度 alpha は「データから選ぶ」必要がある。最も一般的な方法は k-fold クロスバリデーション(CV)で汎化誤差(RMSE)を最小化する alpha を探すこと。N=47 と小さいサンプルでは特にOLSは過学習しやすく、正則化モデルがCV-RMSEで優れる場合が多い。AIC・BICは変数の数にペナルティを与える情報量規準で、Lassoのスパース解との相性が良い。
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | n_feat = len(FEATURE_LABELS) x_pos = np.arange(n_feat) width = 0.25 fig3, ax3 = plt.subplots(figsize=(12, 6)) bars_ols = ax3.bar(x_pos - width, ols_coefs / 1000, width, label='OLS', color='#1565C0', alpha=0.80, edgecolor='white') bars_ridge = ax3.bar(x_pos, ridge_coefs / 1000, width, label='Ridge (α=1.0)', color='#2E7D32', alpha=0.80, edgecolor='white') bars_lasso = ax3.bar(x_pos + width, lasso_coefs / 1000, width, label='Lasso (α=0.01)', color='#E65100', alpha=0.80, edgecolor='white') ax3.axhline(0, color='gray', linewidth=0.8, linestyle='--') ax3.set_xticks(x_pos) ax3.set_xticklabels(FEATURE_LABELS, rotation=30, ha='right', fontsize=10) ax3.set_ylabel('標準化係数(×10³ 円/㎡ 単位)', fontsize=11) ax3.set_title('OLS・Ridge・Lasso の係数比較(2022年断面, 標準化後)\n' '正則化による係数の収縮効果', fontsize=12, fontweight='bold') ax3.legend(fontsize=10) ax3.grid(axis='y', alpha=0.3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。172 173 174 175 176 177 178 179 180 181 182 | # Lasso でゼロになった変数にマーク for i, (lc, name) in enumerate(zip(lasso_coefs, FEATURE_LABELS)): if abs(lc) < 1e-6: ax3.text(i + width, 0.5, 'Lasso=0', ha='center', va='bottom', fontsize=7.5, color='#E65100', rotation=0) plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2022_U5_16_fig3_model.png'), bbox_inches='tight', dpi=150) plt.close(fig3) print("図3保存: 2022_U5_16_fig3_model.png") |
図3保存: 2022_U5_16_fig3_model.png
df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。2022年の47都道府県を地域区分(東京都・主要都市圏・地方)で色分けし、総人口と住宅地価格の散布図を描く。人口集中が価格を押し上げる都市圏クラスターと、人口が多くても価格が低い地方の差異が視覚的に確認できる。
総人口と住宅地価格の強い正相関は「集積の経済」を反映している。人口が集まる地域では雇用・サービス・インフラが充実し、さらに人口が集まる好循環(正のフィードバック)が生じる。逆に地方では人口流出→サービス低下→さらなる流出という悪循環が起きやすい。この構造的格差を解消するには、住宅価格の低い地方の「移住コスト障壁の低さ」を活用し、テレワーク普及・地方移住補助などと組み合わせる政策が統計的に支持される。
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import statsmodels.api as sm from sklearn.linear_model import Ridge, Lasso from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline from scipy import stats 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) |
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)。StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。205 206 207 208 209 210 211 212 213 | y_2022 = df_2022[TARGET].values X_2022 = df_2022[FEATURES].values # OLS(標準化あり → 標準化係数) scaler = StandardScaler() X_scaled = scaler.fit_transform(X_2022) ols_model = sm.OLS(y_2022, sm.add_constant(X_scaled)).fit() ols_coefs = np.array(ols_model.params[1:]) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | # Ridge (alpha=1.0, random_state=42) ridge = Ridge(alpha=1.0, random_state=42) ridge.fit(X_scaled, y_2022) ridge_coefs = ridge.coef_ # Lasso (alpha=0.01, random_state=42) lasso = Lasso(alpha=0.01, random_state=42, max_iter=10000) lasso.fit(X_scaled, y_2022) lasso_coefs = lasso.coef_ print("\n" + "=" * 60) print("■ OLS / Ridge / Lasso 係数比較(標準化後)") print("=" * 60) print(f"{'変数':<20} {'OLS':>12} {'Ridge':>12} {'Lasso':>12}") print("-" * 60) for name, o, r, la in zip(FEATURE_LABELS, ols_coefs, ridge_coefs, lasso_coefs): print(f"{name:<20} {o:>12.1f} {r:>12.1f} {la:>12.1f}") print(f"\nOLS R² = {ols_model.rsquared:.4f}") print(ols_model.summary2()) |
============================================================
■ OLS / Ridge / Lasso 係数比較(標準化後)
============================================================
変数 OLS Ridge Lasso
------------------------------------------------------------
総人口 195266.1 19030.9 195247.9
有効求人数 -17129.0 -20220.9 -17129.0
有効求職者数 2560.2 -7093.8 2556.1
消費支出 826.4 1517.5 826.2
65歳以上人口 -107300.4 1819.7 -107287.2
大学学生数 6485.9 20418.0 6486.4
着工新設住宅戸数 -67714.4 11116.1 -67705.8
商業地価格 46969.7 34932.6 46970.0
OLS R² = 0.9881
Results: Ordinary least squares
=====================================================================
Model: OLS Adj. R-squared: 0.986
Dependent Variable: y AIC: 979.5017
Date: 2026-05-18 11:24 BIC: 996.1530
No. Observations: 47 Log-Likelihood: -480.75
Df Model: 8 F-statistic: 393.3
Df Residuals: 38 Prob (F-statistic): 4.28e-34
R-squared: 0.988 Scale: 5.5515e+07
---------------------------------------------------------------------
Coef. Std.Err. t P>|t| [0.025 0.975]
---------------------------------------------------------------------
const 53372.3404 1086.8181 49.1088 0.0000 51172.1922 55572.4887
x1 195266.1096 31464.8675 6.2058 0.0000 131568.8155 258963.4037
x2 -17129.0176 7311.6614 -2.3427 0.0245 -31930.7022 -2327.3329
x3 2560.1547 11988.4772 0.2136 0.8320 -21709.2486 26829.5579
x4 826.3681 1437.1346 0.5750 0.5687 -2082.9588 3735.6949
x5 -107300.4150 22643.6727 -4.7386 0.0000 -153140.1337 -61460.6962
x6 6485.9287 8148.8658 0.7959 0.4310 -10010.5876 22982.4450
x7 -67714.3871 16238.2202 -4.1701 0.0002 -100586.9453 -34841.8290
x8 46969.7211 6467.5861 7.2623 0.0000 33876.7776 60062.6646
---------------------------------------------------------------------
Omnibus: 4.963 Durbin-Watson: 2.281
Prob(Omnibus): 0.084 Jarque-Bera (JB): 4.408
Skew: -0.399 Prob(JB): 0.110
Kurtosis: 4.271 Condition No.: 97
=====================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors
is correctly specified.[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | fig4, ax4 = plt.subplots(figsize=(9, 7)) for region, color in REGION_COLOR.items(): sub = df_2022[df_2022['地域区分'] == region] ax4.scatter(sub['総人口'] / 1e6, sub[TARGET] / 1000, c=color, s=60, alpha=0.85, label=region, zorder=3) # 都道府県名ラベル(東京・大阪・秋田など主要県) for _, row in sub.iterrows(): if row[TARGET] > 100000 or row['都道府県'] in ['秋田県', '青森県', '鳥取県', '北海道', '大阪府']: ax4.annotate(row['都道府県'], xy=(row['総人口']/1e6, row[TARGET]/1000), xytext=(3, 3), textcoords='offset points', fontsize=7.5, color=color) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | # 回帰直線(全体) x4 = df_2022['総人口'].values / 1e6 y4 = df_2022[TARGET].values / 1000 z4 = np.polyfit(x4, y4, 1) xs4 = np.linspace(x4.min(), x4.max(), 200) ax4.plot(xs4, np.poly1d(z4)(xs4), 'k--', linewidth=1.2, alpha=0.6, label='回帰直線(全体)') r4, p4 = stats.pearsonr(x4, y4) ax4.set_xlabel('総人口(百万人)', fontsize=12) ax4.set_ylabel('住宅地 標準価格(千円/㎡)', fontsize=12) ax4.set_title(f'総人口と住宅地価格の関係(2022年)\n' f'r = {r4:.3f} (p = {p4:.4f}) N=47都道府県', fontsize=12, fontweight='bold') ax4.legend(fontsize=10, loc='upper left') ax4.grid(True, alpha=0.3) plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2022_U5_16_fig4_scatter.png'), bbox_inches='tight', dpi=150) plt.close(fig4) print("図4保存: 2022_U5_16_fig4_scatter.png") print("\n" + "=" * 60) print("■ 全図の生成完了(4枚)") print(" 2022_U5_16_fig1_ts.png : 住宅地価格 時系列") print(" 2022_U5_16_fig2_rank.png : 47都道府県 価格ランキング") print(" 2022_U5_16_fig3_model.png : OLS vs Ridge vs Lasso 係数比較") print(" 2022_U5_16_fig4_scatter.png: 総人口 vs 住宅地価格 散布図") print("=" * 60) |
図4保存: 2022_U5_16_fig4_scatter.png ============================================================ ■ 全図の生成完了(4枚) 2022_U5_16_fig1_ts.png : 住宅地価格 時系列 2022_U5_16_fig2_rank.png : 47都道府県 価格ランキング 2022_U5_16_fig3_model.png : OLS vs Ridge vs Lasso 係数比較 2022_U5_16_fig4_scatter.png: 総人口 vs 住宅地価格 散布図 ============================================================
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。SSDSE-B の都道府県パネルデータ(47都道府県 × 12年)を用いた分析の結果:
| データ | 出典 |
|---|---|
| SSDSE-B-2026.csv(都道府県データ) | 統計数理研究所 SSDSE(社会・人口統計体系) |
| 標準価格(平均価格)(住宅地) | 国土交通省 地価公示(SSDSE-B 収録) |
| 総人口・65歳以上人口・大学学生数 等 | 総務省統計局・文部科学省(SSDSE-B 収録) |
本教育用コードは SSDSE-B-2026.csv の実データのみを使用(合成データは一切使用しない)。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。