本ページでは、 ロジスティック回帰と一般化線形モデル (GLM)を統合的に解説します。 ロジット・オッズ比・ポアソン回帰・順序ロジット・リンク関数を一気通貫で扱います。
GLM は線形回帰の一般化で、 応答変数が二値・カウント・順序など、 正規分布以外でも線形モデルを使えるようにしたものです。 SSDSE-B でも「持ち家比率高い/低い」など二値化した検証で頻出します。
論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:
| 章 | 内容 |
|---|---|
| 1. なぜGLM | 線形回帰の拡張 |
| 2. GLMの枠組み | 3つの構成要素 |
| 3. ロジスティック回帰 | 二値分類 |
| 4. オッズと係数解釈 | オッズ比 |
| 5. 最尤推定 | IRLS 法 |
| 6. ポアソン回帰 | カウント応答 |
| 7. 順序・多項ロジット | 順序・多クラス |
| 8. 診断・モデル比較 | 残差・AIC・ROC |
線形回帰 $y = \boldsymbol{\beta}^\top \mathbf{x} + \varepsilon$ は次のような仮定を置く:
しかし現実には二値(買う/買わない)・カウント(事故件数)・順序(5段階評価)といったデータも多い。 これらに OLS を使うと、 確率が 0 未満や 1 超に予測されるなどの問題が起きる。
GLM はリンク関数で線形予測子と平均を結び、 応答分布も指数型族から選べる枠組み。
GLM は次の 3 要素:
| 応答変数 | 分布 | リンク | 逆リンク | モデル名 |
|---|---|---|---|---|
| 連続 | 正規 | 恒等 $\mu$ | $\eta$ | 線形回帰 |
| 二値 | 二項 | ロジット $\log(p/(1-p))$ | シグモイド | ロジスティック |
| 二値 | 二項 | プロビット $\Phi^{-1}$ | $\Phi$ | プロビット |
| カウント | ポアソン | log | $e^\eta$ | ポアソン回帰 |
| 正連続 | ガンマ | 逆数 $1/\mu$ | $1/\eta$ | ガンマ回帰 |
$$f(y; \theta, \phi) = \exp\left(\frac{y\theta - b(\theta)}{\phi} + c(y, \phi)\right)$$
正規・二項・ポアソン・ガンマ・指数分布などはすべて指数型族に属し、 一般的な推定理論で扱える。
二値応答 $y \in \{0, 1\}$ に対し、 確率 $p = P(y=1|\mathbf{x})$ をモデル化:
$$\mathrm{logit}(p) = \log\frac{p}{1-p} = \beta_0 + \beta_1 x_1 + \cdots + \beta_k x_k$$
逆リンク(シグモイド)で確率に戻す:
$$p = \sigma(\boldsymbol{\beta}^\top \mathbf{x}) = \frac{1}{1+\exp(-\boldsymbol{\beta}^\top \mathbf{x})}$$
$\beta_0=-2$、 $\beta_1=0.5$、 $x=5$ のとき:
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 9 10 11 | import pandas as pd import statsmodels.api as sm import statsmodels.formula.api as smf df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1) df['持家高'] = (df['持ち家比率'] >= df['持ち家比率'].median()).astype(int) # statsmodels で詳細な結果(係数のp値・CIなど) model = smf.glm('持家高 ~ 一人当たり県民所得 + 世帯人員 + 高齢化率', data=df, family=sm.families.Binomial()).fit() print(model.summary()) |
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 9 10 | from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline X = df[['一人当たり県民所得', '世帯人員', '高齢化率']] y = df['持家高'] pipe = Pipeline([('scale', StandardScaler()), ('lr', LogisticRegression(C=1.0, max_iter=1000))]) pipe.fit(X, y) print('係数:', dict(zip(X.columns, pipe.named_steps['lr'].coef_[0]))) |
$\beta_j$ は「$x_j$ が 1 単位増加すると、 オッズが $e^{\beta_j}$ 倍になる」と読む。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 | import numpy as np or_table = np.exp(model.params) or_ci = np.exp(model.conf_int()) print('オッズ比:') print(or_table.round(3)) print('95% CI:') print(or_ci.round(3)) |
対数尤度:
$$\ell(\boldsymbol{\beta}) = \sum_{i=1}^{n} \big[y_i \log p_i + (1-y_i)\log(1-p_i)\big]$$
これを最大化する $\boldsymbol{\beta}$ が最尤推定量。 解析解はなく、 IRLS(反復重み付き最小二乗)や Newton–Raphson で数値解を求める。
$D = -2(\ell_{\text{model}} - \ell_{\text{saturated}})$。 線形回帰の RSS に対応。 小さいほどよく当てはまる。
$AIC = -2\ell + 2k$、 $BIC = -2\ell + k\log n$。 モデル比較に使う。
カウントデータ $y \in \{0, 1, 2, \dots\}$ に対し:
$$\log \mu = \boldsymbol{\beta}^\top \mathbf{x}, \quad y \sim \mathrm{Poisson}(\mu)$$
$\beta_j$ の解釈:$x_j$ が 1 単位増えると、 期待カウントが $e^{\beta_j}$ 倍。
「人口当たりの事故件数」のように露出量を考慮するときは、 オフセット項 $\log(\text{人口})$ を線形予測子に固定で入れる。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 9 10 11 | import statsmodels.api as sm import statsmodels.formula.api as smf import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1) # 例:「総人口」あたりの「就業者数」(カウントとみなす) df['log_pop'] = np.log(df['総人口']) model_pois = smf.glm('就業者数 ~ 高齢化率 + 一人当たり県民所得', data=df, family=sm.families.Poisson(), offset=df['log_pop']).fit() print(model_pois.summary()) |
ポアソンは「分散=平均」を仮定。 実データでは分散 > 平均(過分散)が多い。 そのときは負の二項回帰:
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 | model_nb = smf.glm('就業者数 ~ 高齢化率 + 一人当たり県民所得', data=df, family=sm.families.NegativeBinomial(), offset=df['log_pop']).fit() print(model_nb.summary()) |
応答が順序尺度(不満〜満足の 5 段階等)のときに使う。 K カテゴリで K-1 個のしきい値 $\alpha_k$ を推定。
$$\log\frac{P(Y \leq k)}{P(Y > k)} = \alpha_k - \boldsymbol{\beta}^\top \mathbf{x}$$
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 | from statsmodels.miscmodels.ordinal_model import OrderedModel df['持家3群'] = pd.qcut(df['持ち家比率'], q=3, labels=[0, 1, 2]) model_ord = OrderedModel(df['持家3群'].astype(int), df[['一人当たり県民所得', '世帯人員']], distr='logit').fit(method='bfgs') print(model_ord.summary()) |
順序のないカテゴリ K 個の応答(職業・選好等)。 1 カテゴリを基準にし、 他 K-1 個の対基準対数オッズを線形モデル化。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 | from sklearn.linear_model import LogisticRegression df['地域種別'] = pd.qcut(df['人口密度'], q=3, labels=['農村','中規模','都市']) lr_multi = LogisticRegression(multi_class='multinomial', solver='lbfgs', max_iter=1000) lr_multi.fit(df[['一人当たり県民所得','世帯人員']], df['地域種別']) print(lr_multi.classes_) print(lr_multi.coef_.round(3)) |
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 | from statsmodels.stats.outliers_influence import variance_inflation_factor import pandas as pd X_ = df[['一人当たり県民所得', '世帯人員', '高齢化率']] vif = pd.DataFrame({ 'feature': X_.columns, 'VIF': [variance_inflation_factor(X_.values, i) for i in range(X_.shape[1])] }) print(vif) |
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 | from sklearn.metrics import roc_auc_score, roc_curve proba = pipe.predict_proba(X)[:, 1] print('AUC =', roc_auc_score(y, proba)) |
ロジスティック回帰の適合度を確認する標準検定。 期待頻度と観測頻度を 10 グループで χ² 検定。
| 落とし穴 | 対処 |
|---|---|
| 係数を直接「効果量」と読む | 必ず $e^\beta$ をとってオッズ比 / 率比で報告。 |
| 不均衡データに普通に学習 | class_weight='balanced' や閾値調整。 |
| 完全分離(Quasi-Complete Separation) | $\hat{\beta}$ が発散。 正則化(Firth ロジスティックや L2)で対応。 |
| ポアソンで過分散を無視 | 分散/平均を確認、 過分散なら負の二項に切り替え。 |
| オフセット項を忘れる | 「率」をモデル化したいなら必ず log(露出量) をオフセットに。 |
| 順序ロジットの比例オッズ仮定 | Brant検定で確認。 違反なら一般化順序ロジット。 |
| 多項ロジットの IIA 仮定 | 独立な選択肢の仮定。 違反するなら入れ子ロジット等。 |
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 9 10 11 | import pandas as pd, numpy as np import statsmodels.api as sm import statsmodels.formula.api as smf df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1) df['持家高'] = (df['持ち家比率'] >= df['持ち家比率'].median()).astype(int) m = smf.glm('持家高 ~ 一人当たり県民所得 + 世帯人員 + 高齢化率 + 人口密度', data=df, family=sm.families.Binomial()).fit() print(pd.DataFrame({'OR': np.exp(m.params), 'CI_low': np.exp(m.conf_int()[0]), 'CI_high': np.exp(m.conf_int()[1]), 'p': m.pvalues}).round(3)) |
応答の分散/平均比を確認、 1 を大きく超えれば過分散の疑い。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 9 10 11 | from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler X = df[['一人当たり県民所得','世帯人員','高齢化率','人口密度']] y = df['持家高'] for name, m in [('LR', Pipeline([('s',StandardScaler()),('m',LogisticRegression(max_iter=1000))])), ('RF', RandomForestClassifier(n_estimators=200, random_state=42))]: sc = cross_val_score(m, X, y, cv=5, scoring='roc_auc') print(f'{name}: AUC = {sc.mean():.3f} ± {sc.std():.3f}') |
「ロジスティック回帰の結果、 所得が有意でした (p < 0.05)。」
「持ち家高低を二値応答とするロジスティック回帰を実施。 一人当たり県民所得 100 万円増加に対する持ち家高グループ所属オッズ比は 0.83 (95% CI [0.71, 0.97], p = .024)、 すなわち所得が高いほど持ち家高グループに属しにくいことを示した。 世帯人員 1 増のオッズ比は 4.21 (95% CI [2.10, 8.42], p < .001)。 モデル全体の AUC = 0.86 (5-fold CV)、 Hosmer–Lemeshow 検定 p = .31 で適合度に問題なし。」
| モデル | statsmodels | scikit-learn |
|---|---|---|
| ロジスティック | sm.GLM(..., family=Binomial()) | LogisticRegression |
| プロビット | sm.Probit | なし |
| ポアソン | sm.GLM(..., family=Poisson()) | PoissonRegressor |
| 負の二項 | sm.GLM(..., family=NegativeBinomial()) | なし |
| ガンマ | sm.GLM(..., family=Gamma()) | GammaRegressor |
| 順序ロジット | OrderedModel | OrdinalEncoder + LR |
| 多項ロジット | sm.MNLogit | LogisticRegression(multi_class='multinomial') |
| 混合GLM | BinomialBayesMixedGLM | なし |
論文・記事に登場する用語のリンクで該当箇所へジャンプ:
SSDSE-B 2018→2023の人口変化率が負の県(人口減少県)を 1、 そうでない県を 0 として、 家計の3項目(魚介・肉・野菜)でロジスティック回帰します。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import pandas as pd import statsmodels.api as sm df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) p18 = df[df['年度']==2018].set_index('都道府県')['A1101'] p23 = df[df['年度']==2023].set_index('都道府県')['A1101'] y = (p23 p18).astype(int) # 1=減少、 0=非減少 d23 = df[df['年度']==2023].set_index('都道府県') X = d23[['L322101', 'L322102', 'L322108']] / 10000 X = sm.add_constant(X) # Logistic(=GLM with Binomial) res = sm.GLM(y, X, family=sm.families.Binomial()).fit() print(res.summary()) print("OR:", round(float(res.params['L322101']),3)) |
たとえば 魚介消費係数 β = -0.18(OR = exp(-0.18) ≈ 0.84)とすると、 「年間 1 万円魚介消費が増えると、 人口減少県である確率のオッズは約 16% 減少」と読めます。 解釈時は 確率とオッズとオッズ比を混同しない。
| 指標 | 仮想値 | 解釈 |
|---|---|---|
| 逸脱度 Deviance | 52.3 | 残差平方和の GLM 版(小さいほど良い) |
| AIC | 60.3 | 変数選択に使う |
| 疑似 R²(McFadden) | 0.18 | 0.2-0.4 が「良いフィット」(OLS の R² より基準が低い) |
| AUC-ROC | 0.79 | 分類性能の指標、 0.5=ランダム、 1=完璧 |
OLS の係数は「x が 1 単位増えると y が β 増える」と読めるが、 ロジスティックでは β はリンク関数(logit)越し。 直接の確率変化ではなく 対数オッズの変化を表します。 確率での影響を見るには 限界効果(marginal effect)を計算する必要があり、 これは x の値に依存します。 statsmodels の get_margeff() で平均限界効果が出せる。
「ある変数の値だけで y を完全に分類できてしまう」状態を complete separation という。 このとき MLE が発散して係数が無限大になり、 標準誤差も巨大化。 statsmodels なら warning が出る、 sklearn なら正則化のおかげで気づきにくい。 対策:(1) 該当変数を除く / 合算する、 (2) Firth ロジスティック(バイアス補正)、 (3) ベイズ的事前分布、 (4) ペナルティ付き L2 ロジスティック。 サンプル少 + 二値説明変数で頻発します。
ポアソン分布は「平均 = 分散」を仮定します。 現実のカウントデータは平均 < 分散になりがち(過分散)。 過分散を無視すると標準誤差が過小評価され、 偽陽性が増える。 必ず Pearson カイ二乗 / 自由度 を計算し、 1.5 以上なら負の二項回帰かquasi-Poissonに切り替える。 計数 0 が多いならゼロ過剰モデル(ZIP / ZINB)も検討。
陽性率が 1% 未満のような稀な事象では、 通常のロジスティックは係数を過大評価する(特に切片)。 King & Zeng (2001) の稀事象ロジスティック(rare event logistic)や、 Firth ペナルティ、 weight-adjusted logistic を使う。 機械学習では SMOTE などのオーバーサンプリングと組合せる手もありますが、 推定された確率の校正(calibration)が崩れる点に注意。
logit(p) = β₀ + β₁ x の関係は、 「x の対数オッズへの効果が線形」という強い仮定。 実際は U 字や J 字の場合が多い(例:年齢と疾患リスク)。 対策:(1) x を多項式化 (x², x³)、 (2) スプライン、 (3) GAM(一般化加法モデル)、 (4) ビン化してダミー変数化。 Box-Tidwell 検定で線形性をチェックできます。
説明変数同士が強く相関していると、 個々の係数の解釈が「他の変数を一定として」になり、 単独相関と符号が逆になることがある(Simpson's paradox の係数版)。 VIF(分散拡大係数)を計算して 5-10 を超える変数は要警戒。 対策:(1) 相関の強い変数を1つに絞る、 (2) 主成分回帰、 (3) Ridge / LASSO で正則化、 (4) 因子分析。 因果解釈をする際は特にこの問題が致命的になります。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 | import statsmodels.api as sm X = sm.add_constant(X_raw) res = sm.GLM(y, X, family=sm.families.Binomial()).fit() print(res.summary(), res.conf_int().apply(np.exp)) |
注意:LogisticRegression はデフォルトで L2 正則化が入っているので、 純粋な MLE 推定をしたい場合は penalty=None を指定。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 5 | from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_auc_score, classification_report model = LogisticRegression(penalty='l2', C=1.0, max_iter=1000).fit(X, y) p = model.predict_proba(X_test)[:, 1] print(roc_auc_score(y_test, p), classification_report(y_test, model.predict(X_test))) |
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 4 | # 3クラス以上の多項ロジスティック model = LogisticRegression(multi_class='multinomial', solver='lbfgs').fit(X, y) # 順序ロジスティック from statsmodels.miscmodels.ordinal_model import OrderedModel |
scipy では「ロジスティック分布」のCDFが logit の逆関数(sigmoid)として使えます。 確率の理論計算で便利。
data/raw/SSDSE-B-2026.csv。 説明変数:高齢化率(65 歳以上比率)、 教育費。 目的変数:人口減少フラグ。1 2 3 | from scipy.special import expit, logit print(expit([-2, 0, 2])) # sigmoid = [0.119, 0.5, 0.881] print(logit([0.1, 0.5, 0.9])) # logit 関数 |
ロジスティック GLM は「0/1 の確率を線形予測子のロジスティック関数で表す一般化線形モデル」。 リンク関数は logit、 分布は Bernoulli。 SSDSE-B-2026 では「人口 100 万人超え=1」のような 2 値を、 A1303(高齢人口)や L3221(消費)で予測するのが演習に適する。
ロジスティック GLM は「回帰」カテゴリの中核概念。 初めて触れる読者は、 まずこの「🎨 直感」セクションだけ通読し、 必要になった時点で「📐 数式」「🐍 Python」「⚠️ 落とし穴」へ戻る読み方が定着しやすいです。
直感の次は、 厳密な定義を確認します。 数式は言語の一種で、 一度書き慣れれば「言葉より速く伝えられる」便利な道具。 慣れていない方は、 各記号が何を表すかを下の「🔬 記号読み解き」で 1 つずつ確認してください。
上の数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 2 倍ほど上がります。
数式だけでは「実感」が湧きにくいので、 実データ data/raw/SSDSE-B-2026.csv(47 都道府県 × 16 年)で 1 度手計算してみると理解が定着します。
SSDSE-B-2026 (2023) で y = (A1101 > 1,000,000) の 0/1(30 県が 1)、 説明変数を log(L3221) として GLM(Binomial, logit) を当てると、 切片≈-58、 傾き≈4.7 程度になる(実行で確認)。 L3221 が 28 万→32 万に上がると、 県人口 100 万超え確率が約 0.2 → 0.85 へ大きく上昇する。
| 都道府県 | 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 実装で得る値と一致することを確認すると、 「数式とコードの対応関係」がクリアに見えるようになります。
公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで ロジスティック GLM を動作させます。 まずはこのまま実行してみてください。
# ロジスティック GLM を 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())
import statsmodels.api as sm
import numpy as np
y = (df['A1101'] > 1_000_000).astype(int)
X = np.log(df['L3221'])
X = sm.add_constant(X)
model = sm.GLM(y, X, family=sm.families.Binomial()).fit()
print(model.summary())
print('オッズ比:', np.exp(model.params[1]))
上のコードで動かない場合は、 ①必要なパッケージがインストール済みか(pip install pandas scikit-learn scipy statsmodels matplotlib)、 ②データファイルが data/raw/SSDSE-B-2026.csv に存在するか、 ③encoding='cp932' になっているかを確認してください。
ロジスティック GLM を使うときに初学者が踏みやすい失敗パターン。 1 度経験してしまえば次から避けられますが、 先に知っておくに越したことはありません。
この ロジスティック回帰・GLM ページで出てくる主要キーワードを一覧します。チップをクリックすると該当箇所へジャンプできます。
あなたは、回帰モデル の入口で「ロジスティック回帰・GLM(Logistic Regression & GLM)」という用語に出会ったところです。 この用語は 2 値(0/1)の結果や、カウント・比率を、線形予測子 + リンク関数で扱う一般化線形モデル。
本ページでは、まず数式や形式的定義よりも、実データ(SSDSE-B-2026, 47 都道府県)で具体的な値を見ます。 そのあと、数式 → 計算 → Python 実装 → 落とし穴 → 関連用語、という順で「使える知識」に組み立てていきます。
ロジスティック回帰・GLM の本質は、ひとことで言うと「2 値(0/1)の結果や、カウント・比率を、線形予測子 + リンク関数で扱う一般化線形モデル。」です。 数式に踏み込む前に、まずイメージで掴みましょう。
ヒント:直感が掴めたら、次の「数式または定義」セクションで形式化を確認してください。 形式化と直感がつながれば、ロジスティック回帰・GLM はもう武器です。
ロジスティック回帰・GLM を一般化して書くと、観測ペア $(x_1, y_1), \dots, (x_n, y_n)$(ここでは $n = 47$ 都道府県)に対して、次の関係を仮定します。
$$ \boxed{\quad y = f(x_1, x_2, \dots, x_p; \theta) + \varepsilon \quad} $$ここで $\theta$ は推定したいパラメータ、$\varepsilon$ はモデルでは説明しきれない誤差項。 ロジスティック回帰・GLM の流派ごとに、$f$ の形(線形・ロジスティック・木)、$\varepsilon$ の分布(正規・二項・ポアソン)が変わります。
| 記号 | 意味 | SSDSE-B での例 |
|---|---|---|
| $x$ | 説明変数 | A1101(人口 × 家計支出) |
| $y$ | 目的変数 | 死亡率・出生率など |
| $n$ | 標本数 | 47(都道府県数) |
| $\theta$ | パラメータ | 傾き・切片など |
| $\varepsilon$ | 誤差項 | モデルで説明しきれない残り |
上の式 $y = f(x; \theta) + \varepsilon$ を「数学者の声」ではなく、「現場の声」で読み直してみます。
合言葉:「定義は短い、解釈は長い」。ロジスティック回帰・GLM はたった 1 行の式ですが、それを 47 都道府県データに当てると、5 種類のチェックリスト(線形性・独立性・等分散・正規性・外れ値)が芋づる式に出てきます。
数式が読めたら、すぐに 実データ(SSDSE-B-2026, 47 都道府県, 2023 年度)で計算しましょう。 抽象を 47 行の表に落とすと、急に理解できることがあります。
# ロジスティック回帰・GLM の代表値を SSDSE-B-2026 で確認
col = 'A1101'
s = df2023[col].astype(float)
print('n :', len(s)) # 47
print('mean :', round(s.mean(), 2))
print('median :', round(s.median(), 2))
print('std :', round(s.std(), 2))
print('min / max :', s.min(), '/', s.max())
print('Top 3 prefs :')
print(df2023.nlargest(3, col)[['Prefecture', col]])
結果を見ると、47 都道府県のうち上位 3 県が突出しているか、なだらかに分布しているか、すぐ分かります。 この「分布の形」が見えると、ロジスティック回帰・GLM を語る土台ができたことになります。
Python の実装は「読む → 集計 → 描く → 報告」を一直線に書きます。長いコードよりも、各ステップが分離していることが大事です。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# SSDSE-B-2026 を読み込み(人口 × 家計支出)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
# 2023 年度(最新)だけ抽出
df2023 = df[df['SSDSE-B-2026'] == 2023].copy()
print(df2023.shape) # (47, ...)
print(df2023[['Prefecture', 'A1101']].head())
# ロジスティック回帰・GLM を 47 都道府県でビジュアル化
fig, ax = plt.subplots(figsize=(9, 6))
df2023.sort_values(col, ascending=False).plot.bar(
x='Prefecture', y=col, ax=ax, color='#00897B', legend=False)
ax.set_title('人口 × 家計支出(SSDSE-B-2026, 2023)')
ax.set_ylabel(col)
ax.set_xlabel('都道府県')
plt.xticks(rotation=90)
plt.tight_layout()
plt.savefig('figures/logistic-glm.html_r18_bar.png', dpi=120)
plt.show()
レポート文例:「SSDSE-B-2026(2023 年度, n=47)に基づいて ロジスティック回帰・GLM を確認したところ、平均は X、標準偏差は Y、上位 3 県は東京・神奈川・大阪であった。 SSDSE-B-2026 の 47 都道府県を「人口減少県(1)/そうでない(0)」に二分化し、家計支出(食料・教育など)からロジスティック回帰で予測すると、各係数が「オッズ比」として読めます。」
合言葉:レポート提出前に「ゼロ起点で 1 枚描き直す」「外れ値を 1 県外して再計算」「逆方向の因果を 1 行で否定する」を必ずやる。
本ページに登場した Python コードはすべて以下のテンプレートで読み解けます:
覚え方:「Read → Roll up → Render → Read it back」。 最後の「Read it back」は、出力された数字や図を口に出して 1 度言うこと。 これで ロジスティック回帰・GLM の現場運用は十分に回ります。
使います。前処理(特徴量 → 入力ベクトル)、評価(指標の可視化)、解釈(係数の可視化)など、機械学習のあらゆる工程で ロジスティック回帰・GLM は登場します。
記述統計や 1 変量・2 変量の可視化には十分。ただし複数の説明変数を同時に検討するときは、自由度が枯れます。bootstrap や情報量規準(AIC/BIC)で補強しましょう。
独立行政法人統計センター(NSTAC)「SSDSE」サイトから無料でダウンロードできます。本ページの実装はすべて data/raw/SSDSE-B-2026.csv を前提にしています。
SSDSE は教育目的での利用が許諾されています(出典明示、改変記録)。論文公開時は出典欄に「総務省統計局, SSDSE-B-2026」を必ず書きましょう。
① ヒストグラム 1 枚を描く → ② 平均・中央値・標準偏差を読み上げる → ③ 上位 3 県・下位 3 県を暗記する → ④ 2 変量の相関を 1 つ確認する → ⑤ レポート 1 行にまとめる。これを 47 都道府県データで 3 回回せば、用語の地形が掴めます。
本リポジトリの 論文一覧 から「回帰モデル」カテゴリの論文を見ると、ロジスティック回帰・GLM を実際に使った再現コードが付いています。
「目的 → データ → ロジスティック回帰・GLM の選択理由 → 結果(図 + 数値)→ 解釈 → 限界(n=47, 単年)→ 次の一手」の順が王道です。
用語は単独では覚えづらいので、前提・並列・発展の 3 方向で 16 件並べます。
勧め方:1 日 1 リンク。クリックして読んだら、ロジスティック回帰・GLM のページに戻り、「ロジスティック回帰・GLM とこの用語はどう違う?」を 1 行書く。
合言葉:5 STEP のうちどれか 1 段でも飛ばすと、結論が「数字だけ」になり、読者の腑に落ちなくなります。 ロジスティック回帰・GLM は「数字 + 物語」のセットで完成です。
np.random.seed で作って「再現実験しました」と書く(教育用途では SSDSE-B-2026 を使うのが必須)iloc[:, 5] のように位置で参照し、SSDSE のバージョン違いで壊れるコードを書くx1, x2, x3 のように匿名化し、読者が意味を追えないコードにするロジスティック回帰・GLM は、19 世紀末〜 20 世紀初頭の統計学黎明期から発達してきました。回帰モデル の中核として、Galton、Pearson、Fisher、Yule などが基礎を築き、現代では SSDSE のような公的データを使った教育素材で広く扱われています。
ロジスティック回帰・GLM は、観測ペア $(x_i, y_i)_{i=1}^{n}$ から条件付き期待値 $E[y \mid x]$ または分布 $P(y \mid x)$ を推定する道具です。 線形・非線形・パラメトリック・ノンパラメトリックという 4 つの軸の中で、ロジスティック回帰・GLM は「回帰モデル」という棚に並んでいます。
df.dropna() の前に必ず欠損率を df.isna().mean() で測る。ロジスティック回帰・GLM は 記述統計・データサイエンス・機械学習 の交差点に位置します。 どの分野から入っても、いずれは ロジスティック回帰・GLM を通ります。
同じテーマで使い回せる narration を 5 つ並べておきます。コピペして「コード解説」欄に貼ってください。
ロジスティック回帰・GLM を学ぶときに使う SSDSE-B-2026 は、47 都道府県 × 約 110 列 × 複数年度のパネルデータです。 本ページでは「2023 年度の 47 行」を主に使います。 以下に、よく登場する代表的なカラムを示します。
| SSDSE コード | 日本語名 | 単位 | ロジスティック回帰・GLM での主な使い方 |
|---|---|---|---|
| Code | 地域コード | — | JOIN キー |
| Prefecture | 都道府県名 | — | カテゴリ軸・ラベル |
| A1101 | 総人口 | 人 | 説明変数(規模) |
| A1303 | 65 歳以上人口 | 人 | 高齢化率の分子 |
| A4101 | 出生数 | 人 | 人口動態の説明変数 |
| A4200 | 死亡率 | ‰ | 目的変数の代表 |
| B4101 | 年平均気温 | ℃ | 気候系の説明変数 |
| L3221 | 消費支出 | 円 | 家計の目的変数 |
使い方のコツ:列名はすべて A1101 のような英数記号です。SSDSE のコードブックで日本語ラベルを確認しながら使ってください。
本ページの例では A1101, L3221(人口 × 家計支出)を中心に使っています。
解説は最小限。コードは 10 行以内。これで ロジスティック回帰・GLM の最短ルートが手に入ります。
import pandas as pddf = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])df = df[df['SSDSE-B-2026'] == 2023]col = 'A1101'print(df[['Prefecture', col]].sort_values(col, ascending=False).head())import matplotlib.pyplot as pltdf.plot.hist(y=col, bins=20)plt.title('人口 × 家計支出(SSDSE-B-2026, 2023)')plt.savefig('figures/logistic-glm.html_r18_hist.png', dpi=120)plt.show()注意:10 行で動かせる、というだけで、これがゴールではありません。 ロジスティック回帰・GLM の本当の難しさは「描いた図をどう解釈するか」「報告にどう落とすか」にあります。
ロジスティック回帰・GLM の結果を、ゼミ・卒論・社内会議で報告するときの定型文を 3 つ用意しました。 最初は丸ごとコピー、慣れたら差し替えて使ってください。
「本研究では、SSDSE-B-2026(n=47, 2023 年度)を用いて ロジスティック回帰・GLM を確認した。 主たる説明変数は A1101, L3221(人口 × 家計支出)であり、47 都道府県を対象とした分布の確認、相関の評価、ロジスティック回帰・GLM を用いた分析を実施した。 分析の結果、上位 3 県・下位 3 県の特徴と、SSDSE-B-2026 の 47 都道府県を「人口減少県(1)/そうでない(0)」に二分化し、家計支出(食料・教育など)からロジスティック回帰で予測すると、各係数が「オッズ比」として読めます。」
「人口 × 家計支出 を 47 都道府県で比較したところ、東京・神奈川・大阪など大都市圏が突出していることが分かった。 ロジスティック回帰・GLM を用いた分析から、地域差は単に人口規模の違いだけでは説明できず、複数要因の組み合わせで生じていると示唆された。 今後の打ち手は、上位県のベストプラクティスを参考にしつつ、下位県への支援策を検討することである。」
「皆さん、ロジスティック回帰・GLM はひとことで言うと『2 値(0/1)の結果や、カウント・比率を、線形予測子 + リンク関数で扱う一般化線形モデル。』です。 今回は SSDSE-B-2026(総務省統計局, 47 都道府県, 2023 年度)を使って、実際の数字でこの考え方を確かめました。 皆さん自身でも、別の指標(人口、出生率、家計支出など)に置き換えて同じ手順を試してみてください。」
同じ用語でも、見る立場によって意味が変わります。3 つの視点を切り替えて、用語の輪郭を立体的に掴みましょう。
統計学者にとって ロジスティック回帰・GLM は「データから母集団を推定する道具」です。 確率モデル・尤度・不偏性・効率性・一致性などの数学的性質に注目し、漸近理論で性能保証を行います。 47 都道府県データは「小標本(n=47)」と分類され、bootstrap や情報量規準による補強が必要になります。
データサイエンティストにとって ロジスティック回帰・GLM は「ビジネス課題を数字で答えるパイプラインの 1 部品」です。 モデルの理論的性質より、運用性・解釈性・更新コストを重視します。 SSDSE のような公的データを用いるときは「データの出典・更新頻度・ライセンス」を最優先で確認します。
教育の現場では ロジスティック回帰・GLM は「初学者が躓きやすいポイント」を含む単元です。 抽象的な数式よりも、具体的な 47 都道府県データで手を動かし、図を描き、結果を口頭で説明できるようになることが目標になります。 本ページの並び(直感 → 数式 → 計算 → Python → 落とし穴)は、まさにこの教育的アプローチに沿っています。
視点切り替えの効果:1 つの用語を 3 通りに眺めると、自分が今どの立場で議論しているか自覚できます。 論文を読むときは ①、現場で使うときは ②、人に教えるときは ③ ── と意識的に切り替えてください。
ロジスティック回帰・GLM と似た用語を、使い分けの観点から並べます。違いを言語化できれば、迷いが減ります。
| 用語 | 目的 | 入力 | 出力 | 強み | 弱み |
|---|---|---|---|---|---|
| ロジスティック回帰・GLM | 2 値(0/1)の結果や、カウント・比率を、線形予測子 + リンク関数で扱う一般化線形モデル。 | 47 都道府県 × 約 110 変数 | 図 + 表 + 200 字レポート | 直感的、再現容易 | 小標本(n=47)の制約 |
| 相関係数 | 2 変量の同調を 1 数で要約 | x, y の 47 ペア | r ∈ [−1, +1] | シンプル | 非線形は捉えられない |
| 線形回帰 | 条件付き期待値の線形近似 | 説明変数群 | 回帰係数・予測値 | 解釈容易 | 非線形には弱い |
| ロジスティック回帰 | 2 値分類 | 説明変数群 | 確率 + 係数 | 分類問題の標準 | 線形決定境界 |
| ランダムフォレスト | 非線形分類・回帰 | 大量変数 | 予測 + 重要度 | 非線形対応 | 解釈やや難 |
ロジスティック回帰・GLM は 回帰モデル の中で「2 値(0/1)の結果や、カウント・比率を、線形予測子 + リンク関数で扱う一般化線形モデル。」を担う基本道具です。回帰モデル の他のトピックは、この基本の応用または並列の道具にあたります。
使えます。SSDSE-A(市区町村)、SSDSE-C(年次推移)、SSDSE-D・E(個票)など、ロジスティック回帰・GLM の手順はそのまま適用できます。粒度(県・市・個人)に応じて n が変わるので、結果の信頼性も変わります。
SSDSE は年に 1 度更新されます。ロジスティック回帰・GLM のコード自体は変更不要ですが、結果(数値・図)は最新年度のものに置き換えてレポートしましょう。出典欄に「SSDSE-B-2027(仮)」と書き換えるのを忘れずに。
できます。ピボット → グラフ → 関数 で代表値や相関は出ます。ただし、再現性・履歴管理・自動化の面で Python に劣ります。学習用には Python を強く勧めます。
進めます。ロジスティック回帰・GLM は機械学習の「特徴量設計」と「結果解釈」の両端で必須です。AI と聞くと深層学習を連想しがちですが、SSDSE のような表形式データでは線形モデル + ロジスティック回帰・GLM の組み合わせで十分実用になります。
3 つ確認します:①ファイルパス(data/raw/SSDSE-B-2026.csv)が合っているか、②エンコーディングが cp932 か、③ヘッダ 2 行目の日本語ラベルを skiprows で飛ばしたか。これで 9 割解決します。
figures/ ディレクトリが存在しない可能性があります。import os; os.makedirs('figures', exist_ok=True) を先頭に追加してください。
本ページの 12 セクションを順に読み進めるのが最短です。特に「直感 → 数式 → 計算 → Python」の 4 段が腑に落ちれば、用語の 80 % は理解できたとみなせます。
このカードを印刷し、SSDSE-B-2026 で 1 回手を動かせば、用語の「使える形」が定着します。 ロジスティック回帰・GLM はあくまで「2 値(0/1)の結果や、カウント・比率を、線形予測子 + リンク関数で扱う一般化線形モデル。」というシンプルな考え方の道具ですので、迷ったらこの 1 行に戻ってください。