📍 あなたが今見ているもの
論文中に 「調整済み決定係数」として登場する用語。
調整済み決定係数 とは:R²はモデルに変数を増やすほど大きくなるバイアスを持つ。それを変数の数で調整した指標。
💡 30秒で分かる結論
- 定義:R²はモデルに変数を増やすほど大きくなるバイアスを持つ。それを変数の数で調整した指標。
- カテゴリ:回帰モデル
📖 詳細な解説
この用語は、 統計データ解析・データサイエンスの世界で重要な概念の1つです。 ジャストインタイム型学習では、 必要なときに参照し、 関連概念と合わせて学ぶことで定着を図ります。
基本的な定義
この用語の基本的な意味、 数学的定義、 直感的理解について、 上記の3つの概念マップを通じて、 関連する用語と一緒に把握しましょう。
使い時の判断基準
- データの種類は何か(連続値 / カテゴリ / 順序)
- サンプルサイズは十分か(n > 30 が目安)
- 仮定は満たされているか(正規性、 独立性等)
- 結果の解釈に必要な情報は揃っているか
Python による実装例
🎯 解説: SSDSE-B-2026 の重回帰で説明変数を段階的に追加し、 R² と調整済み R² の差を観察する。 調整済み R² は説明変数数 k に対して罰則を加えるため、 「無駄な変数を追加すると下がる」性質を持つ。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
# SSDSE データの読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
# 基本統計
df.describe()
df.info()
# 可視化
df.hist(bins=30, figsize=(15, 10))
plt.show()
|
📥 入力例: data/raw/SSDSE-B-2026.csv
X1: A1101(総人口)のみ
X2: A1101 + A4101(出生数)
X3: A1101 + A4101 + ランダム変数
📤 実行例: モデル | R² | 調整済み R²
X1 | 0.991 | 0.991
X2 | 0.994 | 0.993
X3 | 0.994 | 0.992 (低下!)
💬 読み方: ランダム変数を加えても R² は維持されるが、 調整済み R² は下がる。 これが「意味のない変数を見抜く」フィルター機能。 モデル比較・変数選択では必ず調整済み R² を見る。
📖 包括的解説 — この概念を完全マスター
📍 学習の3ステップ
- 定義を理解する:この概念は何か? 数式や条件を確認
- 具体例を見る:実データ(SSDSE 等)で計算してみる
- 応用する:自分のデータに適用、 結果を解釈
🔧 Python実装パターン
🎯 解説: statsmodels の summary() 出力から R-squared と Adj. R-squared を同時に確認する。 statsmodels は学術的標準で、 t 値・p 値・AIC・BIC など多角的な情報を提供する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | # 基本パターン
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
# データ読み込み
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
# 基本統計量
df.describe()
# 可視化
sns.pairplot(df[['食料費', '教育費', '住居費']])
plt.show()
|
📥 入力例: data/raw/SSDSE-B-2026.csv
formula = 'C120120 ~ A1101 + A4101 + A6101'
47 都道府県
📤 実行例: R-squared: 0.994
Adj. R-squared: 0.993
F-statistic: 2412.
AIC: 1356.
BIC: 1364.
💬 読み方: F-stat が大きいほどモデル全体が有意。 AIC/BIC は小さいほど良いモデル(モデル比較用)。 調整済み R² と AIC は変数選択の主要な基準。 BIC のほうがパラメータ罰則が強く、 よりシンプルなモデルを好む。
📚 統計概念マップでの位置
このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 関連手法を辿って学習を進めましょう。
🎯 SSDSE-B-2026 で挑戦
統計データ活用コンペティションのSSDSE-B-2026データは、 47都道府県の社会経済データ。 この概念を使って以下のような分析ができます:
- 地域別の特徴抽出
- 家計支出パターンの解析
- 人口動態と社会経済指標の関連
- 気候要因の影響評価
💡 よく使うコマンド集
| 機能 |
Python (pandas) |
Python (scipy) |
| 要約統計 | df.describe() | stats.describe() |
| 平均 | df.mean() | np.mean() |
| 標準偏差 | df.std() | np.std() |
| 相関 | df.corr() | stats.pearsonr() |
| t検定 | — | stats.ttest_ind() |
| 回帰 | — | stats.linregress() |
| 分布フィッティング | — | stats.norm.fit() |
🚧 一般的な落とし穴と対策
- 外れ値の影響:散布図・ 箱ひげ図で確認、 ロバスト手法も検討
- サンプルサイズ不足:power analysis で事前に確認
- 仮定の違反:正規性、 独立性、 等分散性をチェック
- 多重比較問題:補正(Bonferroni、 FDR)を適用
- p-hacking:事前登録(pre-registration)で防ぐ
- 因果と相関の混同:観察データから因果結論を出さない
📊 結果報告の標準フォーマット
- 点推定:得られた値
- 不確実性:信頼区間または標準誤差
- サンプルサイズ:n を明記
- 効果量:実質的な意義
- p値:統計的有意性
- 仮定の確認:診断プロット
🌐 関連分野での応用
- マーケティング:A/Bテスト、 顧客分析
- 医療:臨床試験、 疫学研究
- 金融:リスク管理、 ポートフォリオ
- 製造:品質管理、 工程最適化
- 公共政策:効果評価、 計画立案
- 研究:仮説検証、 探索的解析
🎓 さらに学ぶための文献
- Wasserman "All of Statistics"
- Hastie, Tibshirani & Friedman "The Elements of Statistical Learning"
- Gelman & Hill "Data Analysis Using Regression"
- VanderPlas "Python Data Science Handbook"
🔗 統計用語ネットワーク
この概念は、 他の多くの統計概念と密接に関連しています。 ジャストインタイム型学習では、 必要に応じて関連用語へジャンプしながら全体像を構築します。
主要な関連概念のグループ
| グループ |
主要概念 |
| 記述統計 | 平均、 中央値、 最頻値、 分散、 標準偏差、 共分散、 相関係数 |
| 可視化 | ヒストグラム、 散布図、 箱ひげ図、 ヒートマップ |
| 推測統計 | 標本平均、 標準誤差、 信頼区間、 p値、 有意水準 |
| 確率分布 | 正規分布、 t分布、 χ²分布、 F分布、 二項分布 |
| 仮説検定 | t検定、 F検定、 χ²検定、 ノンパラ検定 |
| 回帰 | 単回帰、 重回帰、 OLS、 Ridge、 LASSO |
| 分類 | ロジスティック回帰、 決定木、 SVM、 k-NN |
| 教師なし学習 | クラスタリング、 PCA、 因子分析 |
| 時系列 | ARIMA、 VAR、 指数平滑法、 自己相関 |
| 因果推論 | DiD、 IV、 傾向スコア、 交絡変数 |
| 前処理 | 標準化、 正規化、 欠損値処理、 多重共線性対策 |
| 評価 | R²、 残差、 CV、 RMSE、 効果量 |
学習順序の推奨
- 記述統計(平均、 分散、 標準偏差)
- 可視化(ヒストグラム、 散布図)
- 確率分布(正規分布)
- 推測統計(標準誤差、 信頼区間、 p値)
- 仮説検定(t検定、 χ²検定)
- 相関と回帰(単回帰、 重回帰)
- 多変量解析(PCA、 クラスタリング)
- 機械学習(決定木、 RF、 NN)
- 時系列・因果推論(応用)
📚 統計学習の総合ガイド
🎯 学習目標
このページの概念をマスターすることで、 以下のスキルが身につきます:
- 定義と公式を正確に理解
- 適切な使用場面を判断
- Python で実装し、 結果を可視化
- 仮定の確認と診断
- 結果の解釈と報告
- 限界と注意点の理解
- 関連手法との使い分け
📊 SSDSE-B-2026 データの構造
このコンペの主要データセット(SSDSE-B-2026)の構造:
- 47都道府県 × 過去複数年(パネル形式)
- 112列の社会経済指標
- 人口、 出生、 死亡、 婚姻、 経済、 教育、 環境、 家計など多次元
- 政府統計を統合した信頼性の高いデータ
🔍 主要な変数群
| カテゴリ |
変数例 |
| 人口 | 総人口、 年齢別人口、 性別人口 |
| 人口動態 | 出生数、 死亡数、 合計特殊出生率、 婚姻数 |
| 気候 | 気温、 降水量、 降水日数 |
| 教育 | 幼小中高校数、 教員数、 生徒数、 大学進学率 |
| 経済 | 求職件数、 求人件数、 旅館数 |
| 医療 | 病院数、 診療所数、 歯科診療所 |
| 家計 | 消費支出、 食料費、 住居費、 教育費等の項目別 |
💡 ジャストインタイム型学習
このガイドは「必要なときに必要な知識」を提供する設計:
- 論文中の用語をクリック → 該当の用語解説へジャンプ(ポップアップ)
- 概念マップで関連用語を辿る
- 包含マップで体系を把握
- ツリーマップで全体を俯瞰
- Python コードをコピーして実行
- SSDSE データで実際に試す
🛠️ Python データサイエンス環境
🎯 解説: 調整済み R² の手計算と statsmodels 出力が一致するかを確認する。 式は 1 - (1-R²)(n-1)/(n-k-1)。 n: サンプル数, k: 説明変数の数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | # 必須ライブラリのインストール
pip install pandas numpy scipy statsmodels scikit-learn matplotlib seaborn
# 標準的なインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error
# 日本語表示の設定(matplotlib)
plt.rcParams['font.family'] = 'Hiragino Sans'
plt.rcParams['axes.unicode_minus'] = False
# データ読み込み(SSDSE は cp932 エンコーディング)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
print(df.shape)
print(df.head())
print(df.describe())
|
📥 入力例: n = 47 (都道府県), k = 3 (説明変数), R² = 0.994
📤 実行例: 1 - (1-0.994)*(47-1)/(47-3-1)
= 1 - 0.006 * 46/43
= 1 - 0.00642
= 0.9936 ≒ 0.993
💬 読み方: n が小さく k が大きいほど補正幅が大。 同じ R² でもサンプルが少ない・変数が多いモデルは調整済み R² が大きく下がる。 競技データでは n=47 と少ないので過学習リスクが高い。
🌟 効果的なEDAテンプレート
🎯 解説: SSDSE-B-2026 の重回帰で説明変数を段階的に追加し、 R² と調整済み R² の差を観察する。 調整済み R² は説明変数数 k に対して罰則を加えるため、 「無駄な変数を追加すると下がる」性質を持つ。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | def quick_eda(df, target=None):
\"\"\"探索的データ分析の基本テンプレート\"\"\"
print(f"Shape: {df.shape}")
print(f"\\nColumn types:\\n{df.dtypes}")
print(f"\\nMissing values:\\n{df.isnull().sum()}")
print(f"\\nBasic stats:\\n{df.describe()}")
# 数値列の可視化
numeric_cols = df.select_dtypes(include=[np.number]).columns
df[numeric_cols].hist(bins=20, figsize=(15, 10))
plt.tight_layout()
plt.show()
# 相関ヒートマップ
if len(numeric_cols) > 1:
plt.figure(figsize=(12, 10))
sns.heatmap(df[numeric_cols].corr(), annot=True, fmt='.2f',
cmap='RdBu_r', center=0)
plt.show()
# ターゲットがあれば散布図行列
if target and target in df.columns:
sns.pairplot(df[numeric_cols[:5]], hue=target if df[target].dtype == 'O' else None)
plt.show()
|
📥 入力例: data/raw/SSDSE-B-2026.csv
X1: A1101(総人口)のみ
X2: A1101 + A4101(出生数)
X3: A1101 + A4101 + ランダム変数
📤 実行例: モデル | R² | 調整済み R²
X1 | 0.991 | 0.991
X2 | 0.994 | 0.993
X3 | 0.994 | 0.992 (低下!)
💬 読み方: ランダム変数を加えても R² は維持されるが、 調整済み R² は下がる。 これが「意味のない変数を見抜く」フィルター機能。 モデル比較・変数選択では必ず調整済み R² を見る。
📈 報告書テンプレート
分析結果を報告する際の標準的な構成:
- 背景・目的:なぜこの分析が必要か
- データ:出所、 サンプルサイズ、 期間
- 方法:使用した統計手法、 仮定
- 結果:図表、 統計量、 検定結果
- 解釈:結果が何を意味するか
- 限界:分析の制約
- 結論:要点まとめ、 今後の課題
🗺️ 統計手法選択フローチャート
Q1: 何を知りたい?
- 記述したい → 平均、 分散、 ヒストグラム
- 比較したい → t検定、 ANOVA、 χ²検定
- 関係を見たい → 相関、 回帰
- 予測したい → 回帰、 機械学習
- 分類したい → ロジスティック回帰、 SVM、 RF
- グループ分けしたい → クラスタリング
- 次元を減らしたい → PCA、 因子分析
- 因果関係を知りたい → RCT、 IV、 DiD、 PSM
Q2: データの種類は?
- 連続値 → t検定、 ANOVA、 線形回帰
- カテゴリ → χ²検定、 ロジスティック回帰
- 順序 → ノンパラ検定、 順位回帰
- カウント → ポアソン回帰、 負の二項回帰
- 時系列 → ARIMA、 VAR、 状態空間
- パネル → 固定効果、 ランダム効果
Q3: サンプルサイズは?
- n < 30:ノンパラ、 ベイズ、 ブートストラップ
- 30 ≤ n < 200:古典的検定、 単純な回帰
- n ≥ 200:複雑なモデル、 機械学習
- n ≥ 10000:深層学習も可能
Q4: 仮定は?
- 正規性:満たす → パラメトリック / 満たさない → ノンパラ
- 独立性:必須 / 違反 → クラスター調整、 時系列モデル
- 等分散性:満たす → OLS / 違反 → WLS、 ロバスト
📏 効果量の参照表
p値だけでなく効果量も併記するのが現代統計の標準。 主要な指標と Cohen の解釈基準:
| 統計量 |
効果量 |
小 |
中 |
大 |
| 2群平均差 | Cohen's d | 0.2 | 0.5 | 0.8 |
| 相関 | r | 0.1 | 0.3 | 0.5 |
| 線形回帰 | R² | 0.02 | 0.13 | 0.26 |
| ANOVA | η² (eta²) | 0.01 | 0.06 | 0.14 |
| χ² | Cramér's V | 0.1 | 0.3 | 0.5 |
| ロジスティック | Odds Ratio | 1.5 | 2.5 | 4.0 |
🗺️ 概念マップ — 3つの視点で体系を理解する
調整済み決定係数 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
📍 体系階層のパス
🌐 体系階層に未登録
① 🔗 関係マップ — 「他の手法とどう繋がっているか」
中心の概念から放射状に、 前提・兄弟・発展形・応用先などの関係性を矢印で結びます。 横の繋がりを見るのに最適。 ノードをドラッグ、 ホイールでズーム、 クリックで遷移。
凡例:現在の用語上位カテゴリ兄弟(並列)前提発展形応用先2階層先
② ⭕ 包含マップ — 「どのカテゴリに含まれているか」
大きな円が小さな円を包含する Circle Packing 図。 「調整済み決定係数」は緑色でハイライト。
- カテゴリ円をクリック:その内部にズームイン
- 白背景クリック:1階層戻る
- 用語円をクリック:詳細ページへ遷移
- マウスホバー:階層パス表示
③ 🌳 ツリーマップ — 「面積で見るボリューム比較」
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「調整済み決定係数」は緑色でハイライト。
- カテゴリ矩形をクリック:その内部にドリルダウン
- パンくず(上のリンク)クリック:その階層に戻る
- 用語矩形をクリック:詳細ページへ遷移
- マウスホバー:階層パスと値を表示
🎯 3つのマップの使い分け
| マップ |
分かること |
こんな時に見る |
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。
🔖 キーワード索引(拡張版 — 自由度調整済み R²)
調整済み R² と他の予測誤差規準を比較できる用語を集めました。
🧮 SSDSE-B-2026 実値計算例 — 変数を増やすと R² と調整 R² はどう変わるか
「持ち家比率」を目的変数として、 説明変数の数を段階的に増やしながら R² と調整 R² を比較します。 R² は単調に増えるが、 調整 R² は変数追加が無意味なら逆に下がるのがポイントです。
| モデル |
k |
R² |
調整 R² |
差分 ΔR̄² |
| M1: 平均所得のみ | 1 | 0.18 | 0.16 | — |
| M2: + 高齢化率 | 2 | 0.42 | 0.39 | +0.23 |
| M3: + 第三次産業比率 | 3 | 0.58 | 0.55 | +0.16 |
| M4: + 無関係なノイズ | 4 | 0.59 | 0.54 | −0.01 |
| M5: 全 20+ 変数 | 20 | 0.87 | 0.69 | 過学習警告 |
🎯 解説: statsmodels の summary() 出力から R-squared と Adj. R-squared を同時に確認する。 statsmodels は学術的標準で、 t 値・p 値・AIC・BIC など多角的な情報を提供する。
| import pandas as pd, statsmodels.api as sm
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
num = df.select_dtypes(include='number').dropna()
y = num['持ち家比率']
for cols in [['平均所得'], ['平均所得','高齢化率'],
['平均所得','高齢化率','第三次産業就業者比率']]:
X = sm.add_constant(num[cols])
r = sm.OLS(y, X).fit()
print(f'k={len(cols)}: R²={r.rsquared:.3f}, '
f'adj R²={r.rsquared_adj:.3f}')
|
📥 入力例: data/raw/SSDSE-B-2026.csv
formula = 'C120120 ~ A1101 + A4101 + A6101'
47 都道府県
📤 実行例: R-squared: 0.994
Adj. R-squared: 0.993
F-statistic: 2412.
AIC: 1356.
BIC: 1364.
💬 読み方: F-stat が大きいほどモデル全体が有意。 AIC/BIC は小さいほど良いモデル(モデル比較用)。 調整済み R² と AIC は変数選択の主要な基準。 BIC のほうがパラメータ罰則が強く、 よりシンプルなモデルを好む。
⚠️ 落とし穴(補強版 — 調整 R² で踏みやすい7つの罠)
① 調整 R² が「予測性能」だと思う
調整 R² はあくまでサンプル内の指標で、 未知データへの予測誤差は別物です。 過学習が深刻な場合、 調整 R² が 0.95 でも CV-R² が 0.3 ということは普通にあります。 予測性能を語るなら必ず CV-R² または PRESS 統計量を併記しましょう。 「調整 R²=0.8 だから良いモデル」は浅い分析の代表例で、 査読でも頻繁に指摘されます。
② 異なる y で計算した調整 R² を比較する
log(y) と y を別々に予測したモデルの調整 R² を比較しても、 単位の比較ができていないので無意味です。 標本標準偏差で割られる R² は y のスケールに依存します。 異なる目的変数(あるいは変換版)のモデルを比較するなら RMSE をオリジナルスケールに戻すか、 AIC を使う方が筋がいい。 「対数変換した方が R² 高かった」は誤り。
③ 調整 R² が負になっても無視する
サンプル数に対して変数が多すぎる、 または完全に無関係な変数しかない場合、 調整 R² は負になり得ます。 「平均で予測する方がマシ」というシグナルなので、 重大な警告として受け取ってください。 マイナスを「ほぼ 0」と丸めて報告するのは隠蔽。 SSDSE-B(n=47)で k>25 のような状況では普通に起きるので注意。
④ 切片なしモデルで通常の R² を計算する
切片を含めないと SST(全平方和)と SSE(残差平方和)の関係が崩れ、 R² の解釈が変わります。 statsmodels では fit() のuncentered オプションに応じて挙動が変わり、 rsquared の意味が違ってきます。 切片なしの R² と切片ありの R² を直接比較しないこと。 必要なら「分散の何割を説明したか」ではなく F 検定や対数尤度で比較すべきです。
⑤ ロジスティック回帰や GLM で調整 R² を語る
調整 R² は OLS の概念。 ロジスティック回帰や GLM では擬似 R²(McFadden, Cox-Snell, Nagelkerke)を使います。 sklearn の LogisticRegression.score は精度(accuracy)であって R² ではありません。 GLM の説明力を語るときは pseudo-R² の種類を明示し、 R² と混同しないように記述しましょう。 「ロジスティック回帰の R² は 0.5 でした」は誤った表現です。
⑥ 調整 R² を「だけ」で変数選択する
変数選択を調整 R² 最大化で行うと、 AIC とは違う結果になり、 ノイズ変数が残りやすい傾向があります。 AIC・BIC・CV-R² と組み合わせ、 複数の規準で頑健に選ばれた変数だけを採用するのが現代的な作法。 「調整 R² が最大だから採用」は古典的アプローチで、 機械学習文脈では不十分です。
⑦ 調整 R² の絶対値だけで「良いモデル」と判定する
分野ごとに R² の「目安」は全く違います。 経済学のクロスセクション分析なら 0.3 でも十分立派、 物理計測なら 0.99 を超えないと不安。 SSDSE-B の社会データなら 0.5〜0.7 が良好な目安。 「調整 R²=0.4 だから悪い」は分野文脈を無視した判断。 過去文献との相対比較や、 ベースラインモデルとの差分(ΔR̄²)で語るのが筋。
🐍 Python 実装バリエーション(statsmodels / scikit-learn / 自前計算)
🅰️ statsmodels — 一番素直
🎯 解説: 調整済み R² の手計算と statsmodels 出力が一致するかを確認する。 式は 1 - (1-R²)(n-1)/(n-k-1)。 n: サンプル数, k: 説明変数の数。
| import pandas as pd, statsmodels.api as sm
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
num = df.select_dtypes(include='number').dropna()
X = sm.add_constant(num[['平均所得','高齢化率','第三次産業就業者比率']])
r = sm.OLS(num['持ち家比率'], X).fit()
print(f'R² = {r.rsquared:.3f}')
print(f'adj R² = {r.rsquared_adj:.3f}')
|
📥 入力例: n = 47 (都道府県), k = 3 (説明変数), R² = 0.994
📤 実行例: 1 - (1-0.994)*(47-1)/(47-3-1)
= 1 - 0.006 * 46/43
= 1 - 0.00642
= 0.9936 ≒ 0.993
💬 読み方: n が小さく k が大きいほど補正幅が大。 同じ R² でもサンプルが少ない・変数が多いモデルは調整済み R² が大きく下がる。 競技データでは n=47 と少ないので過学習リスクが高い。
🅱️ scikit-learn — 自前計算(score は R² だが調整版なし)
🎯 解説: SSDSE-B-2026 の重回帰で説明変数を段階的に追加し、 R² と調整済み R² の差を観察する。 調整済み R² は説明変数数 k に対して罰則を加えるため、 「無駄な変数を追加すると下がる」性質を持つ。
| from sklearn.linear_model import LinearRegression
X = num[['平均所得','高齢化率','第三次産業就業者比率']]
y = num['持ち家比率']
m = LinearRegression().fit(X, y)
r2 = m.score(X, y)
n, k = len(y), X.shape[1]
adj_r2 = 1 - (1 - r2) * (n - 1) / (n - k - 1)
print(f'R² = {r2:.3f}, adj R² = {adj_r2:.3f}')
|
📥 入力例: data/raw/SSDSE-B-2026.csv
X1: A1101(総人口)のみ
X2: A1101 + A4101(出生数)
X3: A1101 + A4101 + ランダム変数
📤 実行例: モデル | R² | 調整済み R²
X1 | 0.991 | 0.991
X2 | 0.994 | 0.993
X3 | 0.994 | 0.992 (低下!)
💬 読み方: ランダム変数を加えても R² は維持されるが、 調整済み R² は下がる。 これが「意味のない変数を見抜く」フィルター機能。 モデル比較・変数選択では必ず調整済み R² を見る。
🅲 scipy.stats.linregress — 単回帰のみ
🎯 解説: statsmodels の summary() 出力から R-squared と Adj. R-squared を同時に確認する。 statsmodels は学術的標準で、 t 値・p 値・AIC・BIC など多角的な情報を提供する。
| from scipy import stats
slope, intercept, r, p, se = stats.linregress(num['平均所得'], num['持ち家比率'])
print(f'R² = {r**2:.3f}') # 単回帰なので調整版は意味が薄い
|
📥 入力例: data/raw/SSDSE-B-2026.csv
formula = 'C120120 ~ A1101 + A4101 + A6101'
47 都道府県
📤 実行例: R-squared: 0.994
Adj. R-squared: 0.993
F-statistic: 2412.
AIC: 1356.
BIC: 1364.
💬 読み方: F-stat が大きいほどモデル全体が有意。 AIC/BIC は小さいほど良いモデル(モデル比較用)。 調整済み R² と AIC は変数選択の主要な基準。 BIC のほうがパラメータ罰則が強く、 よりシンプルなモデルを好む。
🅳 CV-R² で過学習を見抜く
🎯 解説: 調整済み R² の手計算と statsmodels 出力が一致するかを確認する。 式は 1 - (1-R²)(n-1)/(n-k-1)。 n: サンプル数, k: 説明変数の数。
| from sklearn.model_selection import cross_val_score
cv_r2 = cross_val_score(LinearRegression(), X, y, cv=5, scoring='r2').mean()
print(f'CV-R² = {cv_r2:.3f}') # 調整 R² より厳しい
|
📥 入力例: n = 47 (都道府県), k = 3 (説明変数), R² = 0.994
📤 実行例: 1 - (1-0.994)*(47-1)/(47-3-1)
= 1 - 0.006 * 46/43
= 1 - 0.00642
= 0.9936 ≒ 0.993
💬 読み方: n が小さく k が大きいほど補正幅が大。 同じ R² でもサンプルが少ない・変数が多いモデルは調整済み R² が大きく下がる。 競技データでは n=47 と少ないので過学習リスクが高い。
📦 R² 系統指標早見表
| 指標 |
特徴 |
使用場面 |
| R² | 説明分散割合 | 単一モデルの記述 |
| 調整 R² | 変数数で罰則 | 変数数が異なるモデル比較 |
| CV-R² | 未知データ性能 | 予測モデル評価 |
| 予測 R²(PRESS基) | leave-one-out 基 | 小標本での汎化性能 |
| McFadden's pseudo R² | 対数尤度比 | ロジスティック回帰・GLM |
| Nagelkerke R² | 0-1 に標準化 | GLM の解釈 |
🎨 直感で掴む — 自由度調整済み決定係数
Adjusted R² は「説明変数を増やすと自動で上がる R² を、 自由度で罰則を入れて補正したもの」。 モデル比較に使う。 SSDSE-B-2026 で説明変数を A1101 → +A1303 → +B4101 と増やすと、 R² は単調増加するが Adjusted R² は途中で下がりうる。
💡 学習のコツ:直感で全体像を掴んだら、 次の「📐 定義・数式」で正確な意味を押さえ、 最後に「🧮 実値で計算してみる」で SSDSE-B-2026 の都道府県データを使った計算をなぞるのが効率的です。 比喩は厳密ではないので、 必ず数式と並べて確認してください。
自由度調整済み決定係数 は「回帰」カテゴリの中核概念。 初めて触れる読者は、 まずこの「🎨 直感」セクションだけ通読し、 必要になった時点で「📐 数式」「🐍 Python」「⚠️ 落とし穴」へ戻る読み方が定着しやすいです。
🔬 記号読み解き — 数式を「言葉」に翻訳
上の数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 2 倍ほど上がります。
- 左辺(結果側)
- 自由度調整済み決定係数 で定義したい量。 解釈の対象。 単位・スケールを必ず確認する。
- 右辺(構成要素)
- 観測できる入力変数(SSDSE-B-2026 でいえば A1101・L3221 など)と推定対象パラメータ(β, σ 等)の組合せ。
- 添字 i, j, t
- i=サンプル(県)、 j=変数、 t=時点。 SSDSE-B-2026 は i ∈ {1..47} 県、 t ∈ {2008..2023}。
- 和記号 Σ
- 「足し合わせ」を表す。 添字 i が 1 から n まで動く範囲を明示するのが習慣。
- 期待値 E[·]、 分散 Var[·]
- 「ランダム変数の平均」と「ばらつき」。 SSDSE-B-2026 のような集計値でも、 標本誤差・年次変動の文脈で使える。
📚 補足:同じ記号でも分野・教科書によって意味が違うことがあります(例: $\hat{y}$ は予測値だが、 統計の文脈では推定量を意味することも)。 不明確なときは、 必ずその文書の記号定義表を確認しましょう。
🧮 実値で計算してみる — SSDSE-B-2026
数式だけでは「実感」が湧きにくいので、 実データ data/raw/SSDSE-B-2026.csv(47 都道府県 × 16 年)で 1 度手計算してみると理解が定着します。
SSDSE-B-2026 (2023, n=47) で y=L3221 に対して、 X1=A1101 単独で R²=0.16、 X={A1101, A1303} で R²=0.18 とした場合、 Adjusted R² はそれぞれ 0.14 と 0.14 程度で変化なし。 つまり A1303 追加に意味がない可能性が高い。 一方 X={A1101, B4101} を入れて R²=0.30 なら Adjusted R²=0.27 へ実質的に上昇する。
| 都道府県 | A1101 総人口 | A1303 65 歳以上 | L3221 消費支出 |
| 東京都 | 14,086,000 | 3,205,000 | 341,320 |
| 神奈川県 | 9,229,000 | 2,390,000 | 306,565 |
| 大阪府 | 8,763,000 | 2,424,000 | 271,246 |
| 愛知県 | 7,477,000 | 1,923,000 | 300,221 |
| 埼玉県 | 7,331,000 | 2,012,000 | 344,092 |
| 千葉県 | 6,257,000 | 1,756,000 | 306,943 |
上記は SSDSE-B-2026 (2023) からの抜粋。 手計算で確認した値が、 後述の Python 実装で得る値と一致することを確認すると、 「数式とコードの対応関係」がクリアに見えるようになります。
🐍 Python 実装 — 自由度調整済み決定係数
公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで 自由度調整済み決定係数 を動作させます。 まずはこのまま実行してみてください。
# 自由度調整済み決定係数 を SSDSE-B-2026 で実行する最小コード
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023] # 2023 年のみ抽出
print(df.shape) # (47, 112)
print(df[['Prefecture','A1101','A1303','L3221']].head())
from sklearn.linear_model import LinearRegression
import numpy as np
y = df['L3221'].astype(float).values
for cols in [['A1101'], ['A1101','A1303'], ['A1101','A1303','B4101']]:
X = df[cols].astype(float).values
lr = LinearRegression().fit(X, y)
n = len(y); k = X.shape[1]
r2 = lr.score(X, y)
adj = 1 - (1-r2)*(n-1)/(n-k-1)
print(f'{cols}: R^2={r2:.3f} Adj R^2={adj:.3f}')
上のコードで動かない場合は、 ①必要なパッケージがインストール済みか(pip install pandas scikit-learn scipy statsmodels matplotlib)、 ②データファイルが data/raw/SSDSE-B-2026.csv に存在するか、 ③encoding='cp932' になっているかを確認してください。
⚠️ よくある落とし穴 — 自由度調整済み決定係数
自由度調整済み決定係数 を使うときに初学者が踏みやすい失敗パターン。 1 度経験してしまえば次から避けられますが、 先に知っておくに越したことはありません。
❌ Adjusted R² が高ければ良いモデル と誤解
予測誤差(CV)と一致しない。 AIC・BIC・CV を併用する。
❌ 負の Adjusted R²
切片だけのモデルに負ける場合 0 以下になる。 異常ではない。
❌ 非線形モデルに使う
ロジスティック・ポアソンなどでは別の Pseudo R² を使う。
🛡 防御策まとめ:「適用条件を確認する」「結果と前提をセットで記述する」「不確実性を必ず併記する」の 3 点を習慣化すれば、 上記の罠の大半は回避できます。
🌐 補強:調整 R² vs AIC vs BIC — 変数選択 3 大指標を SSDSE-B-2026 で比較
変数選択の指標として、 調整 R²、 AIC、 BIC は併走させて使うのが定石です。 それぞれが何を最大化(最小化)し、 どう違うのかを SSDSE-B-2026 で確認します。
📐 3 指標の数式比較
| 指標 | 数式 | 罰則の強さ | 基本姿勢 |
| 調整 R² | 1 − (1−R²)(n−1)/(n−p−1) | 弱い(p に対し線形) | 変数を残しやすい |
| AIC | 2p − 2 ln L | 中(p に対し 2倍) | 予測重視 |
| BIC | p ln n − 2 ln L | 強い(n が大きいほど) | スパースモデル選好 |
🐍 SSDSE-B-2026 で 3 指標を並列計算
import pandas as pd, numpy as np
import statsmodels.api as sm
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df = df.dropna(subset=['人口(総数)', '一般世帯数', '15歳未満人口', '65歳以上人口', '出生数'])
y = df['人口(総数)']
candidates = [
['一般世帯数'],
['一般世帯数', '15歳未満人口'],
['一般世帯数', '15歳未満人口', '65歳以上人口'],
['一般世帯数', '15歳未満人口', '65歳以上人口', '出生数'],
]
print(f"{'変数数':<6} {'R²':>8} {'調整R²':>8} {'AIC':>10} {'BIC':>10}")
for cols in candidates:
X = sm.add_constant(df[cols])
m = sm.OLS(y, X).fit()
print(f'{len(cols):<6} {m.rsquared:>8.4f} {m.rsquared_adj:>8.4f} {m.aic:>10.1f} {m.bic:>10.1f}')
# 調整 R² は単調増加しがち、 AIC/BIC は最小化したい変数組合せが分かる
💡 使い分けのコツ:予測重視なら AIC、 解釈・スパース重視なら BIC、 報告書には調整 R² を載せる、 が実務的な棲み分け。 3 つを併走させて結論が一致するかを確認するのが堅実です。