論文一覧に戻る 📚 用語解説(ジャストインタイム型データサイエンス教育)
ロジスティック回帰
Logistic Regression
目的変数が0/1(二値)のとき使う回帰。確率の対数オッズを線形モデルで予測する。
回帰モデルロジットlogitロジスティック回帰

🔖 キーワード索引 — ロジスティック回帰を多角的に理解する

ロジスティック回帰(logistic regression)を確実に使いこなすための関連キーワードを難易度別に整理しました。

🟢 基礎キーワード(まず押さえる)

🟡 中級キーワード

🔴 上級キーワード

💡 30秒で分かる結論

🍰 まずはやさしく

はいかいいえを分ける道具です。

どちらになるかの確率を出すために使います。

テストに合格するかどうかを予測するような例です。

この章では仕組みと計算方法について読みます。

📖 もっと詳しく

ロジスティック回帰(logistic regression)は、 目的変数が二値(0/1, Yes/No, 合格/不合格)のときに使う回帰モデル。 「東京の中で、 ある地域が住宅地として人気か(はい/いいえ)」を予測するときなどに使います。

なぜ普通の線形回帰ではダメか

解決:シグモイド関数で確率に変換

線形結合 $z = \beta_0 + \beta_1 x_1 + \cdots$ をシグモイド $\sigma(z) = 1/(1+e^{-z})$ に通します。 これで必ず 0〜1 の確率になる。

モデル式:$P(y=1|x) = 1/(1 + e^{-(\beta_0 + \beta_1 x_1 + \cdots)})$

係数の解釈:オッズ比

線形回帰のような直接的解釈ができないので、 代わりに「オッズ比」を使います。 $\exp(\beta_j)$ がオッズ比。 「$x_j$ を1単位増やすと、 オッズが何倍になるか」。

:$\beta_\text{所得} = 0.5$ → $\exp(0.5) = 1.65$ → 「所得が1単位増えると、 イベント発生のオッズが1.65倍」。

用途:(i) 二値分類問題(合否予測、 病気診断)、 (ii) 確率予測、 (iii) リスクファクター分析(医学・公衆衛生)、 (iv) 信用スコアリング。

類似手法:プロビット回帰。 シグモイドの代わりに標準正規 CDF を使う。 結果はほぼ同じ。

📖 包括的解説 — この概念を完全マスター

📍 学習の3ステップ

  1. 定義を理解する:この概念は何か? 数式や条件を確認
  2. 具体例を見る:実データ(SSDSE 等)で計算してみる
  3. 応用する:自分のデータに適用、 結果を解釈

🔧 Python実装パターン

🎯 解説: SSDSE-B-2026 を使い、 2 値目的変数(例: 高齢化率>30% を 1, それ以外 0)をロジスティック回帰で予測。 ロジット関数 log(p/(1-p)) を線形結合に対応させる。 医療・マーケで頻用。
📥 入力例: data/raw/SSDSE-B-2026.csv(cp932・skiprows=[1]・2023 年) aging = df['A1303'] / df['A1101'] # 高齢化率 = 65歳以上人口 / 総人口 y = (aging > aging.median()).astype(int) # 中央値超なら 1 X = np.log(df['L3221']).values.reshape(-1, 1) # 消費支出(対数)
 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 sklearn.linear_model import LogisticRegression

# SSDSE-B-2026 を読み込み(1 行目は列コード行なので skip)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]   # 2023 年の 47 都道府県

# 2値目的変数:高齢化率(A1303/A1101)が中央値超なら 1
aging = df['A1303'] / df['A1101']
y = (aging > aging.median()).astype(int)
X = np.log(df['L3221']).values.reshape(-1, 1)   # 消費支出(対数)

clf = LogisticRegression().fit(X, y)
print('係数 β1 :', clf.coef_[0, 0])
print('オッズ比 :', np.exp(clf.coef_[0, 0]))
📤 実行例: 係数 β1 : -0.54 前後(負) オッズ比 : 0.58 前後 → 消費支出(対数)が大きい県ほど高齢化率が中央値超になりにくい
💬 読み方: 係数 β は log odds の変化、 exp(β) がオッズ比。 log(L3221) が 1 単位増えるとオッズが exp(β1) 倍。 消費支出の高い(=都市的な)県ほど「高齢化率が高い側」に入りにくい傾向を示す。 確率そのものの変化は限界効果で計算する。

📚 統計概念マップでの位置

このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 関連手法を辿って学習を進めましょう。

🎯 SSDSE-B-2026 で挑戦

統計データ活用コンペティションのSSDSE-B-2026データは、 47都道府県の社会経済データ。 この概念を使って以下のような分析ができます:

💡 よく使うコマンド集 — ロジスティック回帰

機能 scikit-learn statsmodels
モデル定義・推定LogisticRegression().fit(X, y)sm.Logit(y, X).fit()
係数(対数オッズ)clf.coef_ / clf.intercept_res.params
オッズ比np.exp(clf.coef_)np.exp(res.params)
確率予測clf.predict_proba(X)[:,1]res.predict(X)
p値・信頼区間res.summary() / res.conf_int()
AUC 評価roc_auc_score(y, proba)
不均衡対応class_weight='balanced'freq_weights=...

🚧 一般的な落とし穴と対策

📊 結果報告の標準フォーマット

🌐 関連分野での応用

🎓 さらに学ぶための文献

🔗 統計用語ネットワーク

この概念は、 他の多くの統計概念と密接に関連しています。 ジャストインタイム型学習では、 必要に応じて関連用語へジャンプしながら全体像を構築します。

主要な関連概念のグループ

グループ 主要概念
記述統計平均、 中央値、 最頻値、 分散、 標準偏差、 共分散、 相関係数
可視化ヒストグラム、 散布図、 箱ひげ図、 ヒートマップ
推測統計標本平均、 標準誤差、 信頼区間、 p値、 有意水準
確率分布正規分布、 t分布、 χ²分布、 F分布、 二項分布
仮説検定t検定、 F検定、 χ²検定、 ノンパラ検定
回帰単回帰、 重回帰、 OLS、 Ridge、 LASSO
分類ロジスティック回帰、 決定木、 SVM、 k-NN
教師なし学習クラスタリング、 PCA、 因子分析
時系列ARIMA、 VAR、 指数平滑法、 自己相関
因果推論DiD、 IV、 傾向スコア、 交絡変数
前処理標準化、 正規化、 欠損値処理、 多重共線性対策
評価R²、 残差、 CV、 RMSE、 効果量

学習順序の推奨

  1. 記述統計(平均、 分散、 標準偏差)
  2. 可視化(ヒストグラム、 散布図)
  3. 確率分布(正規分布)
  4. 推測統計(標準誤差、 信頼区間、 p値)
  5. 仮説検定(t検定、 χ²検定)
  6. 相関と回帰(単回帰、 重回帰)
  7. 多変量解析(PCA、 クラスタリング)
  8. 機械学習(決定木、 RF、 NN)
  9. 時系列・因果推論(応用)

📝 実践練習 — SSDSE-B-2026 で挑戦

初級課題

  1. 高齢化率(A1303/A1101)が中央値を超える県を 1 とする 2 値目的変数 y を作る
  2. y の 0/1 の県数を数え、 クラスが偏っていないか確認する
  3. 説明変数 log(L3221)(消費支出)と y の散布図を描く
  4. LogisticRegression を 1 変数で当てはめ、 係数とオッズ比を出す

中級課題

  1. 説明変数を A1101・A4101・B4101 など複数に増やし、 標準化してから推定する
  2. statsmodels の Logit で各係数の p 値・95% 信頼区間を確認する
  3. 係数を exp() でオッズ比に変換し、 「1 単位増でオッズ何倍か」を言葉で説明する
  4. 閾値 0.5 で混同行列・Accuracy・Precision・Recall・F1 を計算する

上級課題

  1. ROC 曲線を描き AUC を求める。 閾値を動かすと Precision/Recall がどう変わるか観察
  2. class_weight='balanced' の有無でマイノリティクラスの Recall を比較する
  3. L1 正則化(penalty='l1')で係数が 0 に落ちる変数選択効果を確認する
  4. 説明変数間の VIF を確認し、 多重共線性が係数の安定性に与える影響を検討する

📍 あなたが今見ているもの

🍰 まずはやさしく

2つのグループに分ける分析手法です。

あることが起きる確率を予測するために使います。

持ち家があるかないかを分けるような例です。

ここではこの用語の詳しい意味について読みます。

論文中に 「ロジスティック回帰」として登場する用語。

ロジスティック回帰 とは:目的変数が0/1(二値)のとき使う回帰。確率の対数オッズを線形モデルで予測する。

本ページではロジスティック回帰 (logistic regression) を扱う。 二値分類の最も基本的な統計モデルで、 説明変数の線形和を logit リンク関数で 0〜1 の確率に変換する。 SSDSE-B-2026 で「持ち家比率が中央値超え」「人口減少県か」などの二値変数を予測する例で解説する。

ロジスティック回帰は GLM の「二項分布 + logit リンク」の特例。 係数 β はオッズ比 (exp(β)) として解釈でき、 「説明変数が 1 単位増えるとオッズが何倍になるか」を直接読める。 完全分離 (perfect separation) で係数が発散する病的ケース、 多重共線性、 確率予測のキャリブレーションが主な実務論点。

🎨 直感で掴む — ロジスティック回帰

🍰 まずはやさしく

直感的に確率を捉える方法です。

データから正解のしやすさを知るために使います。

スマホの利用時間で成績を予想するような例です。

ここでは図を使ってイメージを掴むことを読みます。

ロジスティック回帰は「2 値(0/1)の確率を線形予測子の logit で表す」回帰。 係数は対数オッズの増分で、 exp(係数) = オッズ比。 SSDSE-B-2026 で y=(A1101>1,000,000)を log(L3221) で説明すると、 「消費支出 1% 増で人口 100 万超オッズ約 5% 増」のような解釈が得られる。

💡 学習のコツ:直感で全体像を掴んだら、 次の「📐 定義・数式」で正確な意味を押さえ、 最後に「🧮 実値で計算してみる」で SSDSE-B-2026 の都道府県データを使った計算をなぞるのが効率的です。 比喩は厳密ではないので、 必ず数式と並べて確認してください。

ロジスティック回帰 は「回帰」カテゴリの中核概念。 初めて触れる読者は、 まずこの「🎨 直感」セクションだけ通読し、 必要になった時点で「📐 数式」「🐍 Python」「⚠️ 落とし穴」へ戻る読み方が定着しやすいです。

🎨 概念図で押さえる

ロジスティック回帰の仕組み使い分けを、 3 点のインライン SVG で 視覚的に整理する。

図1 ロジスティック関数(シグモイド)の形

シグモイド関数

線形和 β₀+β₁x を 0〜1 の確率に押し込む S 字曲線。 中心の 0.5 が判定境界。

図2 線形回帰との違い(外挿の安全性)

線形回帰とロジスティック回帰の比較

青の点線は線形回帰の予測 → 確率が 1 を超え不自然。 ロジスティック回帰なら必ず 0〜1 に収まる。

図3 オッズ比の解釈

オッズ比の解釈

OR=1 は影響なし、 OR>1 は発生確率を上げる、 OR<1 は下げる(保護要因)。 係数 β を exp(β) に変換して読む。

📝 理解度チェック

  1. シグモイド関数の出力範囲は 0〜1。 では入力 z=0 のときの出力は? (答:0.5)
  2. 係数 β=0.7 のオッズ比は exp(0.7)≈2.0。 これは「説明変数が 1 単位増えるとオッズが何倍か?」 (答:約 2 倍)
  3. 2 クラス分類の判定閾値を 0.5 から 0.3 に下げると、 一般に 再現率と精度 はどう変わるか? (答:再現率↑、 適合率↓)
  4. 多重共線性が強いとき、 ロジスティック回帰の係数はどうなる? (答:不安定で解釈困難になる)
  5. ROC-AUC=0.5 は何を意味する? (答:偶然と同じ=モデルが分類に役立っていない)

🎮 触って理解する — シグモイド・決定境界を手で動かす

読むだけでは掴みにくい「なぜシグモイドが確率か」「決定境界はなぜ直線か」を、 実際に点を置いて体感します。 キャンバスをクリック(スマホはタップ)すると、 選んだクラスの点が配置されます。 1次元モードでは x 軸上に 0/1 の点を置くとシグモイド曲線(確率)が引かれ、 係数スライダー(傾き β₁・切片 β₀)で曲線の急峻さと位置を手で調整できます。 「⚙ 勾配法で自動フィット」を押すと、 対数尤度を最大化する係数へ自動収束します。 2次元モードでは、 点を置くたびに勾配法で再フィットし、 線形の決定境界確率の等高線(ヒートマップ)が描画されます。 閾値スライダーを動かすと、 分類結果(誤分類の数)が変わる様子も観察できます。

モード: 配置クラス:
β₀(切片): 0.0
β₁(傾き): 1.0
閾値(分類のしきい値): 0.50

💡 キャンバスをクリック/タップで点を配置。 スライダーで係数と閾値を動かし、 対数尤度・誤分類がどう変わるか観察しましょう。

🔍 このおもちゃが示していること

① シグモイドはなぜ「確率」か: 線形和 $z=\beta_0+\beta_1 x$ は $-\infty$〜$+\infty$ の実数ですが、 確率は $[0,1]$ に収まらねばなりません。 シグモイド関数 $\sigma(z)=1/(1+e^{-z})$ は任意の実数を $0$〜$1$ へ単調に押し込む変換で、 $z=0$ で必ず $0.5$、 $z\to\pm\infty$ で $1/0$ に漸近します。 逆に確率 $p$ を実数に戻す変換が ロジット(対数オッズ) $\operatorname{logit}(p)=\log\frac{p}{1-p}$ で、 モデルは「対数オッズが $x$ の線形関数」$\log\frac{p}{1-p}=\beta_0+\beta_1 x$ と等価です。 スライダーで β₁ を大きくすると曲線が急になり(=オッズの変化率が大きい)、 β₀ を動かすと曲線が左右に平行移動します。 係数 $\beta_j$ をそのまま $\exp(\beta_j)$ にすると オッズ比 になります。

② 決定境界はなぜ「線形」か: 閾値 $t$ で分類するとき、 境界は $p=t$、 すなわち $\sigma(z)=t \Leftrightarrow z=\operatorname{logit}(t)$ を満たす点の集合です。 $z=\beta_0+\beta_1x_1+\beta_2x_2$ は $x$ について一次式なので、 境界 $\beta_0+\beta_1x_1+\beta_2x_2=\operatorname{logit}(t)$ は必ず直線(一般には超平面)になります。 2次元モードのヒートマップで、 等確率線(等高線)が平行な直線群になっているのがこの理由です。 曲がった境界が欲しいときは多項式特徴量や SVM・木モデルを使います。

③ 最尤推定と交差エントロピー損失: 「自動フィット」ボタンは、 各点の予測確率をなるべく正解ラベルに近づけるよう係数を動かしています。 数式では観測データの尤度 $\prod_i p_i^{y_i}(1-p_i)^{1-y_i}$ を最大化する最尤推定(MLE)で、 対数を取って符号を反転すると 交差エントロピー損失(対数損失 / log loss) $$ \mathcal{L}(\beta)=-\sum_i\bigl[y_i\log p_i+(1-y_i)\log(1-p_i)\bigr] $$ になります。 「尤度最大化」と「交差エントロピー最小化」は同じことです。 勾配は $\partial\mathcal{L}/\partial\beta_j=\sum_i (p_i-y_i)x_{ij}$ と綺麗な形になり、 これが勾配降下法(勾配降下法)で解ける理由です。 読み出し欄の「対数尤度 LL」が大きい(=損失が小さい)ほど良い当てはめです。

④ 線形回帰との違い線形回帰 は $y$ を直接 $\beta_0+\beta_1x$ で予測し、 損失は二乗誤差(正規分布の最尤)でした。 0/1 データに線形回帰を当てると予測が $0$ 未満や $1$ 超になり確率として破綻します。 ロジスティック回帰は「シグモイドで $[0,1]$ に収める」「二乗誤差ではなく交差エントロピーを使う」の 2 点が本質的な違いです。 なお両者とも「線形予測子 $\beta_0+\beta_1x$ を使う」点は共通で、 一般化線形モデル(GLM)としてリンク関数(恒等 vs ロジット)の違いに統一的に整理できます。

⑤ 正則化: サンプルが少ない・完全分離が起きると MLE の係数は発散します。 損失に係数のペナルティを足す 正則化L2 / Ridge:$+\lambda\sum\beta_j^2$、 L1 / Lasso:$+\lambda\sum|\beta_j|$)で係数を縮小・一部を $0$ にして安定させます。 上のおもちゃも自動フィットに弱い L2 を入れて発散を防いでいます。 scikit-learn の LogisticRegression は既定で L2 が有効です。

⑥ 多クラスへの拡張(softmax): 3 クラス以上では、 シグモイドを多変数に一般化した ソフトマックス関数 $\;p_k=\dfrac{e^{z_k}}{\sum_{j}e^{z_j}}\;$ を使う多項ロジスティック回帰になります。 各クラスに線形予測子 $z_k=\beta_{k0}+\boldsymbol{\beta}_k^\top x$ を持たせ、 損失は多クラス版の交差エントロピーです。 2 クラスの softmax はシグモイドと一致します。

📐 定義・数式 — ロジスティック回帰

🍰 まずはやさしく

計算するための正確なルールです。

予測を数式で正しく表すために使います。

買い物などのデータを数式に入れるような例です。

ここでは記号の意味と計算式について読みます。

やさしい説明で掴んだ感覚を、ここで ロジスティック回帰 の定義式に対応づけます。下の式は左辺 $\Pr(Y$ が何で決まるかを右辺で書き下したもので、分数(割り算)、exp(指数)、β(回帰係数) が現れます。それぞれの記号が何の量を指すのかは、次の「🔬 数式を言葉で読み解く」で 1 つずつ確かめてください。

【ロジスティック回帰 の中心定義式】
$$ \Pr(Y=1 \mid X) = \frac{1}{1+\exp\bigl(-(\beta_0+\beta_1 x_1+\dots+\beta_k x_k)\bigr)} $$
この式が「ロジスティック回帰」の骨格。 派生形・拡張形はここから生まれる。
📌 読み方のコツ:数式を見たら「左辺は何を定義しているか」「右辺の各項は何の合計・積・比か」を声に出して読み下してみる。 これだけで理解が大きく進みます。

🔬 数式を言葉で読み解く — 数式を「言葉」に翻訳

上の数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 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 実値計算例 — 47 都道府県データでロジスティック回帰

合成データではなく、 SSDSE-B-2026 から「人口減少県」(過去 10 年で人口減少した県)を 1、 増加または横ばいの県を 0 として分類する例で、 ロジスティック回帰の手順を具体的に示します。

① データ準備

# 目的変数 Y:1 = 人口減少県(おおよそ 38 県)、 0 = 増加県(東京・沖縄・神奈川・千葉・埼玉・愛知・福岡・滋賀・大阪 の 9 県)

# 説明変数 X:
# x₁ = 高齢化率(%、 27〜38 程度)
# x₂ = 1 人当たり県民所得(万円、 200〜500 程度)
# x₃ = 大学進学率(%、 35〜70 程度)

② モデル式とパラメータ推定例

🎯 解説: odds ratio の計算と解釈。 SSDSE-B-2026 のロジスティック係数を exp(β) で odds 比に変換し、 直感的に解釈。 医療統計で必須。
📥 入力例: data/raw/SSDSE-B-2026.csv np.exp(model.coef_) 各変数の odds 比
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
logit(P(Y=1)) = β + β₁·高齢化率 + β₂·県民所得 + β₃·大学進学率

# 最尤推定の結果(仮想的だが現実的な値)
β  -8.20  切片
β  +0.52  高齢化率 1% 増で logit +0.52 OR  exp(0.52)  1.68
β  -0.012 所得 1 万円増で OR  exp(-0.012)  0.988
β  -0.038 進学率 1% 増で OR  exp(-0.038)  0.963

 高齢化率が高いほど人口減少県になる確率が大きく上昇
 県民所得大学進学率が高いほど減少しにくい
📤 実行例: 高齢化率 OR = exp(0.52) ≈ 1.68 県民所得 OR = exp(-0.012) ≈ 0.988 大学進学率 OR = exp(-0.038) ≈ 0.963
💬 読み方: odds ratio > 1 で「事象発生の odds が増える」。 < 1 で減少。 CI が 1 をまたぐと有意でない。 確率自体ではなく odds 比である点に注意。

③ 特定の県での予測確率計算

🎯 解説: ロジスティック回帰の決定境界を可視化。 SSDSE-B-2026 の 2 変数で予測確率 0.5 のラインを描画し、 分類面を直感的に理解。
📥 入力例: 秋田県の説明変数 高齢化率 38%、 県民所得 245 万円、 大学進学率 47% logit に代入して P を計算
1
2
3
4
5
6
7
8
# 例:秋田県(高齢化率 38%、 県民所得 245 万円、 大学進学率 47%)
logit = -8.20 + 0.52·38 + (-0.012)·245 + (-0.038)·47
      = -8.20 + 19.76 - 2.94 - 1.79
       +6.83

P = 1 / (1 + exp(-6.83))  0.9989

 秋田は人口減少県である確率 99.89%実際に減少県
📤 実行例: 散布図 + 決定境界(直線) 境界の左下: 都市(クラス 0) 境界の右上: 地方(クラス 1)
💬 読み方: ロジスティック回帰の決定境界は線形(直線・平面)。 非線形決定境界が必要なら多項式特徴量や SVM・木モデル。 47 県では境界が外れ値で不安定。
🎯 解説: ROC 曲線と AUC でロジスティック回帰の性能評価。 SSDSE-B-2026 で各閾値の TPR/FPR を計算、 AUC で分類性能を総合評価。
📥 入力例: data/raw/SSDSE-B-2026.csv from sklearn.metrics import roc_curve, roc_auc_score y_proba = model.predict_proba(X)[:,1]
1
2
3
4
5
6
7
8
# 例:東京都(高齢化率 23%、 県民所得 540 万円、 大学進学率 73%)
logit = -8.20 + 0.52·23 + (-0.012)·540 + (-0.038)·73
      = -8.20 + 11.96 - 6.48 - 2.77
       -5.49

P = 1 / (1 + exp(5.49))  0.0041

 東京は人口減少県である確率 0.41%実際に増加県
📤 実行例: ROC 曲線 AUC = 0.91 カーブが左上角に近い threshold=0.45 で F1 最大
💬 読み方: AUC=0.5 はランダム、 1.0 は完璧。 0.8 以上で実用的。 不均衡データでは Precision-Recall 曲線も併用。 サンプル数少なめなら CV で評価。

④ 分類性能指標

🎯 解説: ロジスティック回帰の正則化(L1/L2)で過学習を防ぐ。 SSDSE-B-2026 の小サンプルで C パラメータを調整し、 適切な正則化強度を探す。
📥 入力例: data/raw/SSDSE-B-2026.csv LogisticRegression(C=0.1, penalty='l2') C 小: 強い正則化
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 47 県を 50% 閾値で予測した結果(仮想)
                 予測 0    予測 1
実測 09        8         1    1 県を誤って減少県と予測
実測 138       2        36    2 県を誤って増加県と予測

正解率 (Accuracy)  = (8+36)/47  0.936
適合率 (Precision) = 36/(36+1)  0.973
再現率 (Recall)    = 36/(36+2)  0.947
F1 スコア           0.960
AUC                 0.985
📤 実行例: C=0.01: 係数すべて 0 に近い C=1.0: 通常 C=100: 過学習傾向 CV で最適 C 探索
💬 読み方: C はペナルティの逆数(C 小 → 強正則化)。 L1 は変数選択効果(係数を 0 に)、 L2 は係数を縮小。 デフォルト C=1.0 は弱め、 小サンプルでは C=0.1 検討。

⑤ オッズ比の解釈と信頼区間

🎯 解説: 混同行列で予測性能の詳細を確認。 SSDSE-B-2026 で TP/TN/FP/FN を計算し、 Precision・Recall・F1 を算出。
📥 入力例: data/raw/SSDSE-B-2026.csv y_pred = model.predict(X) confusion_matrix(y, y_pred)
1
2
3
4
5
6
# 高齢化率の係数 β₁ = 0.52、 SE = 0.18
# 95% 信頼区間(β₁): 0.52 ± 1.96·0.18 = [0.167, 0.873]
# OR の 95% CI: [exp(0.167), exp(0.873)] = [1.18, 2.39]

 高齢化率が 1% 増えると 人口減少県になるオッズが
  1.182.39 倍になる95% 信頼)」
📤 実行例: 混同行列 予測0 予測1 実測0 17 3 実測1 2 25 Precision=0.89, Recall=0.93, F1=0.91
💬 読み方: 不均衡データ(クラス比偏り大)では Accuracy より F1・AUC が重要。 SSDSE は比較的均衡。 病気検出など FN 重視なら Recall、 スパム検出など FP 重視なら Precision。

🧮 実値で計算してみる — SSDSE-B-2026

数式だけでは「実感」が湧きにくいので、 実データ data/raw/SSDSE-B-2026.csv(47 都道府県 × 16 年)で 1 度手計算してみると理解が定着します。

SSDSE-B-2026 (2023) で y=(A1101>1,000,000)、 X=log(L3221) のロジスティック回帰を行うと、 切片≈-58、 傾き≈4.7、 exp(4.7) ≈ 110。 つまり log(L3221) が 1 単位上がるとオッズが 110 倍。 L3221 が 28 万→32 万(log 差 0.13)でオッズ約 1.83 倍。

都道府県A1101 総人口A1303 65 歳以上L3221 消費支出
東京都14,086,0003,205,000341,320
神奈川県9,229,0002,390,000306,565
大阪府8,763,0002,424,000271,246
愛知県7,477,0001,923,000300,221
埼玉県7,331,0002,012,000344,092
千葉県6,257,0001,756,000306,943

上記は SSDSE-B-2026 (2023) からの抜粋。 手計算で確認した値が、 後述の Python 実装で得る値と一致することを確認すると、 「数式とコードの対応関係」がクリアに見えるようになります。

🧮 数式に値を入れて手で計算する: ロジスティック予測確率

合成 z = 0.5x + 1 から p を計算する。

Step 1: 入力

xzp=σ(z)
01.00.731
-20.00.500
43.00.953
-4-1.00.269

Step 2: 判定 (閾値 0.5)

x=0: p=0.73 > 0.5 → クラス 1 x=-2: p=0.5 境界 x=4: p=0.95 → クラス 1 x=-4: p=0.27 → クラス 0 分割境界: x = -2 で p=0.5

🐍 Python で再現

1
2
3
4
5
6
import numpy as np
x = np.array([0, -2, 4, -4])
z = 0.5*x + 1
p = 1/(1+np.exp(-z))
print(f"p: {p.round(3)}")
print(f"クラス: {(p>0.5).astype(int)}")

📤 実行結果

p: [0.731 0.5 0.953 0.269] クラス: [1 0 1 0]

💬 手計算 (Step 2) と Python 出力が完全一致。

🐍 Python 実装のバリエーション — scikit-learn / statsmodels / pingouin

① scikit-learn の LogisticRegression(機械学習向き)

🎯 解説: 2 値目的変数(高齢化率が中央値超か)を sklearn で予測する標準ワークフロー。 標準化 → 訓練/テスト分割 → 学習 → 係数・精度の確認まで一気通貫。
📥 入力例: data/raw/SSDSE-B-2026.csv(cp932・skiprows=[1]・2023 年) y = (df['A1303']/df['A1101'] > 中央値).astype(int) X = df[['A1101','L3221']](総人口・消費支出)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]

# 目的変数:高齢化率(A1303/A1101)が中央値超なら 1
aging = df['A1303'] / df['A1101']
y = (aging > aging.median()).astype(int)
X = df[['A1101', 'L3221']]       # 総人口・消費支出

Xs = StandardScaler().fit_transform(X)   # 標準化
X_train, X_test, y_train, y_test = train_test_split(Xs, y, test_size=0.3, random_state=0)

model = LogisticRegression(C=1.0, penalty='l2', max_iter=1000)
model.fit(X_train, y_train)
print('係数:', {c: round(float(w), 4) for c, w in zip(X.columns, model.coef_[0])})
print('切片:', round(float(model.intercept_[0]), 4))
print('精度:', round(model.score(X_test, y_test), 4), f'(テスト {len(y_test)} 県)')
係数: {'A1101': -0.8666, 'L3221': -0.3664} 切片: -0.2464 精度: 0.8667 (テスト 15 県)
💬 読み方: coef_ は 2D 配列([0] で 1 行目)、 標準化済みなので係数の大小で寄与を比較できる。 デフォルトで L2 正則化(C=1.0)。 47 県はサンプルが少ないので random_state で結果が動く点に注意。

② statsmodels の Logit(統計学向き、 p 値・AIC 付き)

🎯 解説: ロジスティック回帰の係数の信頼区間。 SSDSE-B-2026 で各係数の 95% CI を計算し、 0 をまたぐかで有意性判断。
📥 入力例: data/raw/SSDSE-B-2026.csv result.conf_int(alpha=0.05) 正規近似
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import statsmodels.api as sm

X_const = sm.add_constant(X)
model = sm.Logit(y, X_const).fit()
print(model.summary())

# オッズ比とその 95% 信頼区間
params = model.params
conf = model.conf_int()
conf['OR'] = np.exp(params)
conf.columns = ['CI 2.5%', 'CI 97.5%', 'OR']
conf[['CI 2.5%', 'CI 97.5%']] = np.exp(conf[['CI 2.5%', 'CI 97.5%']])
print(conf)
📤 実行例(実測) coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ const 6.6598 4.782 1.393 0.164 -2.713 16.032 A1101 -7.512e-07 3.47e-07 -2.167 0.030 -1.43e-06 -7.19e-08 L3221 -1.746e-05 1.64e-05 -1.067 0.286 -4.95e-05 1.46e-05 CI 2.5% CI 97.5% OR const 0.066356 9.177471e+06 780.371622 A1101 0.999999 9.999999e-01 0.999999 L3221 0.999950 1.000015e+00 0.999983
💬 読み方: A1101 は p=0.030 で有意、 L3221 は p=0.286 で非有意。 OR は元の単位が大きいため 1 にごく近い値になる(人口 1 人あたりの効果なので、 10 万人あたりで見ると OR = 0.93 相当)。

③ L1 正則化(Lasso)で変数選択

🎯 解説: クラス重み(class_weight='balanced')で不均衡データに対処。 SSDSE-B-2026 でクラス 1 が少数の場合、 重み付けで balanced 分類を実現。
📥 入力例: data/raw/SSDSE-B-2026.csv LogisticRegression(class_weight='balanced') または class_weight={0:1, 1:5}
1
2
3
4
5
6
model_l1 = LogisticRegression(C=0.5, penalty='l1', solver='liblinear', max_iter=1000)
model_l1.fit(Xs, y)

print('L1 で残った係数:')
for name, coef in zip(X.columns, model_l1.coef_[0]):
    print(f'  {name}: {coef:.4f}')
📤 実行例(実測) L1 で残った係数: A1101: -1.0201 L3221: -0.2563
💬 読み方: L1 罰則は不要な係数を 0 にするが、 ここでは 2 変数とも残った(A1101 の方が絶対値が大きく、 高齢化率の予測により効いている)。 変数が多いときほど 0 になる係数が増える。

④ ROC 曲線・AUC の可視化

🎯 解説: 交差検証(K-Fold CV)でロジスティック回帰の汎化性能を評価。 SSDSE-B-2026 の 47 サンプルを 5 分割し、 平均 AUC で評価。
📥 入力例: data/raw/SSDSE-B-2026.csv from sklearn.model_selection import cross_val_score cv=5, scoring='roc_auc'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib.pyplot as plt

# 直前のブロックで model は statsmodels の Logit に置き換わっているので、
# predict_proba を持つ scikit-learn のモデルをここで作り直す
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
aging = df['A1303'] / df['A1101']
y = (aging > aging.median()).astype(int)
X = df[['A1101', 'L3221']]
Xs = StandardScaler().fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(Xs, y, test_size=0.3, random_state=0)
sk_model = LogisticRegression(C=1.0, penalty='l2', max_iter=1000).fit(X_train, y_train)

y_proba = sk_model.predict_proba(X_test)[:, 1]
fpr, tpr, thresholds = roc_curve(y_test, y_proba)
auc = roc_auc_score(y_test, y_proba)
print(f'AUC = {auc:.3f}')

plt.plot(fpr, tpr, label=f'AUC = {auc:.3f}')
plt.plot([0,1], [0,1], 'k--')
plt.xlabel('偽陽性率 (FPR)')
plt.ylabel('真陽性率 (TPR)')
plt.legend()
plt.savefig('roc_curve.png', dpi=150)
📤 実行例(実測) AUC = 0.911
💬 読み方: AUC = 0.911 は良好。 ただし検証は 47 件中 15 件のみなので、 47 サンプルでは LOOCV(n=46 訓練)や交差検証で確かめる方が安全。 stratified=True で各 fold のクラス比を保つ。

⑤ class_weight で不均衡対応

🎯 解説: 学習曲線でサンプルサイズと性能の関係を可視化。 SSDSE-B-2026 で訓練データ量を増やしながら CV スコアの推移を観察。
📥 入力例: data/raw/SSDSE-B-2026.csv from sklearn.model_selection import learning_curve train_sizes=[10,20,30,40]
1
2
3
4
5
6
model_balanced = LogisticRegression(
    C=1.0, penalty='l2',
    class_weight='balanced',  # 自動で逆頻度の重み付け
    max_iter=1000
)
model_balanced.fit(X_train, y_train)
📤 実行例: 学習曲線 n=10: train=0.95, CV=0.65(過学習) n=40: train=0.89, CV=0.87(適切)
💬 読み方: train と CV のギャップ大 → 過学習、 両方低 → 過小学習。 ギャップが収束しなければサンプル不足。 SSDSE 47 県は機械学習には少なめ。

⑥ 多項ロジスティック回帰(3 クラス以上)

🎯 解説: SHAP 値で各特徴量の予測寄与を可視化。 SSDSE-B-2026 のロジスティック回帰で県別の予測理由を SHAP で説明。
📥 入力例: data/raw/SSDSE-B-2026.csv import shap explainer=shap.LinearExplainer(model, X)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# 3 クラスの目的変数を作る(人口規模 小/中/大)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
y_multi = pd.cut(df['A1101'], bins=[0, 1_500_000, 3_000_000, 1e9],
                 labels=['小', '中', '大'])
Xs = StandardScaler().fit_transform(df[['A4101', 'L3221']])
X_train, X_test, y_train_multi, y_test_multi = train_test_split(
    Xs, y_multi, test_size=0.3, random_state=0)

# sklearn 1.5 以降、multi_class 引数は廃止(クラスが 3 つ以上なら自動で多項ロジット)
model_multi = LogisticRegression(
    solver='lbfgs',
    max_iter=1000
)
model_multi.fit(X_train, y_train_multi)

# softmax 出力で全クラスの確率を取得
probs = model_multi.predict_proba(X_test)
print(pd.DataFrame(probs, columns=model_multi.classes_).round(3).head())
📤 実行例: SHAP summary plot 高齢化率の寄与: -0.5 ~ +0.6 県民所得の寄与: -0.4 ~ +0.2 高齢化率が最重要
💬 読み方: SHAP は個別予測の説明可能性を提供。 線形モデルなら係数とほぼ同じだが、 個別観測値での寄与が見える。 木モデル併用で非線形性も検出可。

⑦ キャリブレーション補正(Platt scaling)

🎯 解説: ロジスティック回帰と Probit 回帰の比較。 SSDSE-B-2026 で両モデルを学習し、 予測確率・係数の差を確認。 一般に結果は近い。
📥 入力例: data/raw/SSDSE-B-2026.csv Logit: 1/(1+exp(-Xβ)) Probit: Φ(Xβ)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from sklearn.calibration import CalibratedClassifierCV

cal = CalibratedClassifierCV(LogisticRegression(max_iter=1000), method='sigmoid', cv=5)
cal.fit(X_train, y_train)

# 確率の信頼性確認
from sklearn.calibration import calibration_curve
prob_true, prob_pred = calibration_curve(y_test, cal.predict_proba(X_test)[:, 1], n_bins=10)
plt.plot(prob_pred, prob_true, 's-', label='Calibrated')
plt.plot([0,1], [0,1], 'k--')
plt.xlabel('予測確率')
plt.ylabel('実測陽性率')
plt.legend()
📤 実行例: モデル AIC Pseudo R² Logit 44.5 0.30 Probit 44.2 0.31 係数比: Logit≈Probit×1.6
💬 読み方: Logit と Probit はリンク関数の違い。 結論はほぼ同じ。 経済学では Probit、 機械学習では Logit が慣習。 Logit は odds 比解釈が直感的、 Probit は正規分布前提。

🐍 Python 実装 — ロジスティック回帰

公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで ロジスティック回帰 を動作させます。 まずはこのまま実行してみてください。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) L3221(消費支出(二人以上の世帯)) 北海道 5,092,000 1,681,000 296,888 東京都 14,086,000 3,205,000 341,320 沖縄県 1,468,000 350,000 251,222 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# ロジスティック回帰 を 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 LogisticRegression
import numpy as np
y = (df['A1101'] > 1_000_000).astype(int).values
X = np.log(df['L3221'].values).reshape(-1, 1)
clf = LogisticRegression().fit(X, y)
print('切片:', clf.intercept_)
print('係数:', clf.coef_)
print('オッズ比:', np.exp(clf.coef_))

▶ 実行 を押せばこのページの中でそのまま動きます(ライブラリもデータも同梱済みで、 準備は要りません)。 手元の Python に移して動かすときは pip install matplotlib numpy pandas scikit-learn scipy seaborn statsmodels が必要です。 読んでいるデータは data/raw/SSDSE-B-2026.csv。 日本語を含むので encoding='cp932' の指定を落とさないでください。

⚠️ ロジスティック回帰の落とし穴 — 実務で必ず引っかかるポイント 7 選

① 線形回帰のように R² で評価しようとする

ロジスティック回帰では通常の決定係数 R² が定義できません(目的変数が 0/1 のため)。 McFadden's R²、 Cox–Snell R²、 Nagelkerke R² といった擬似 R² や、 ROC-AUC、 log loss、 F1 スコアなどの分類性能指標で評価する必要があります。 「R² が低い = モデルが悪い」と決めつけず、 適切な評価指標を選びましょう。

② オッズ比(OR)と相対リスク(RR)を混同する

ロジスティック回帰が出すのはオッズ比 (OR) であって、 相対リスク (RR) ではありません。 稀少イベント(陽性率 < 10%)なら OR ≈ RR ですが、 陽性率が高い場合は OR が RR を過大評価します。 たとえば OR = 3 でも、 ベースライン確率が 0.5 なら実際の RR は 1.5 倍程度です。 ニュース記事などで「リスクが 3 倍」と単純に書くのは誤解を招きます。

③ 完全分離(complete separation)で MLE が発散

説明変数が完全に陽性・陰性を分けてしまうと、 最尤推定の係数が無限大に発散し、 数値解が収束しません。 サンプル数が少ない、 稀少イベント、 ダミー変数が多すぎる場合に起こりがち。 対策は (i) Firth 補正、 (ii) L2 正則化(Ridge)、 (iii) ベイズ推定(弱情報事前分布)。 sklearn の LogisticRegression はデフォルトで L2 が入っているため安定です。

④ 不均衡データで「全部 0 と予測」モデルが高精度に

陽性が 1%、 陰性が 99% のデータでは、 「全部 0 と予測」するだけで Accuracy 99% になります。 ロジスティック回帰も多数派クラスに偏ったモデルを学習します。 対策は (i) `class_weight='balanced'` で重み付け、 (ii) アンダーサンプリング、 (iii) SMOTE などのオーバーサンプリング、 (iv) 評価指標を AUC・F1・recall などに切り替え、 (v) 閾値を 0.5 ではなく Youden's J 統計量で最適化。

⑤ 多重共線性で係数が不安定になる

説明変数同士が強く相関していると(VIF > 5〜10)、 係数の標準誤差が膨張し、 個別の係数解釈が不可能になります。 例えば「総人口」と「労働人口」を両方入れると、 一方の係数が大きくプラス、 他方がマイナスになる「打ち消し」が起こりがち。 事前に相関行列・VIF を確認し、 必要なら片方を除外、 PCA、 Lasso などで対処してください。

⑥ サンプルサイズが小さいと過学習する

「説明変数 1 つにつき最低 10〜20 件の陽性イベント(EPV: events per variable)」が経験則です。 47 都道府県データで陽性 9 件・陰性 38 件の場合、 EPV ベースで使える説明変数は 陽性 9 件 ÷ 10 ≈ 1 個 しかありません。 安易に多変量に進まず、 L2 正則化、 PCA、 ドメイン知識による変数選択を組み合わせてください。

⑦ キャリブレーション(確率の信頼性)を無視する

分類精度(accuracy、 AUC)が高くても、 予測確率そのものは現実の頻度を反映していないことがあります。 「P = 0.7 と予測した中で実際に陽性は 50%」など。 これは不均衡データや L1 正則化で特に顕著。 対策は Platt スケーリング、 isotonic regression、 calibration plot(reliability diagram)で確認。 sklearn の `CalibratedClassifierCV` が便利です。

⚠️ よくある落とし穴 — ロジスティック回帰

ロジスティック回帰 を使うときに初学者が踏みやすい失敗パターン。 1 度経験してしまえば次から避けられますが、 先に知っておくに越したことはありません。

❌ 線形回帰で 0/1 を予測
確率が負や 1 超になる。 logit / probit リンクを必ず使う。
❌ 「係数=確率の増加」と誤読
係数は対数オッズの増分。 確率の増分は X の値によって変わる(限界効果)。
❌ クラス不均衡を無視
1 の割合が 5% などのとき、 0 ばかり予測する。 class_weight='balanced' を試す。
🛡 防御策まとめ:「適用条件を確認する」「結果と前提をセットで記述する」「不確実性を必ず併記する」の 3 点を習慣化すれば、 上記の罠の大半は回避できます。

🗺️ 統計手法選択フローチャート

Q1: 何を知りたい?

Q2: データの種類は?

Q3: サンプルサイズは?

Q4: 仮定は?

📏 ロジスティック回帰の効果量と係数解釈

ロジスティック回帰では Odds Ratio擬似 R² が効果量・適合度の主指標。 解釈基準:

指標 意味 弱い 強い
Odds Ratio説明変数 +1 で odds が何倍になるか1.0 ~ 1.51.5 ~ 2.5> 2.5
McFadden 擬似 R²対数尤度の改善率< 0.10.1 ~ 0.3> 0.3 (Excellent 域)
AUC識別能力 (確率予測の順序性)0.5 ~ 0.70.7 ~ 0.85> 0.85
Hosmer-Lemeshow適合度検定 (p 値)p < 0.05 (適合不良)p ~ 0.1p > 0.2 (良好)

🗺️ 概念マップ — 3つの視点で体系を理解する

ロジスティック回帰 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。

📍 体系階層のパス

🌐 統計・データサイエンス › 関連・回帰 › 回帰 › ロジスティック回帰(一般化線形モデル(二項+ロジット))

① 🔗 関係マップ — 「他の手法とどう繋がっているか」

中心に ロジスティック回帰 を置き、 そこから 重回帰・プロビット・OLS・分類・単回帰・Ridge回帰 計 6 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語あとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。

凡例:現在の用語上位カテゴリ兄弟(並列)前提発展形応用先2階層先

② ⭕ 包含マップ — 「どのカテゴリに含まれているか」

大きな円が小さな円を包含する Circle Packing 図。 「ロジスティック回帰」は緑色でハイライト

📍現在地:統計・データサイエンス

③ 🌳 ツリーマップ — 「面積で見るボリューム比較」

長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「ロジスティック回帰」は緑色でハイライト

🎯 3つのマップの使い分け

マップ 分かること こんな時に見る
🔗 関係マップ手法間の横の関係(前提→発展→応用)「次に何を学べばよい?」 学習順序の判断
⭕ 包含マップ分類体系の入れ子構造(上位⊃下位)「この手法はどんなジャンルに属する?」
🌳 ツリーマップ分野の規模比較(面積=ボリューム)「データサイエンス全体の俯瞰像」

💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは ロジスティック回帰隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス回帰 → ロジスティック回帰 という入れ子の位置を示します。 「回帰には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。

🔗 隣接手法への橋渡し

ロジスティック回帰は二値分類の代表モデルであり、 前段の説明変数設計と後段のオッズ比解釈・ROC 評価を組み合わせて医療・ビジネスで定番化している。

上流の特徴量選択と多重共線性検査 (VIF) で安定した推定を確保し、 並列の決定木/SVM/Random Forest と比較して解釈性 vs 精度のトレードオフを判断し、 下流の ROC/AUC とオッズ比解釈でビジネス示唆 (どの要因がどれだけ確率を上げるか) を抽出する流れで二値分類の標準パイプラインが完成する。

🌳 手法選択フロー

「logistic regression」を含む手法選択は、 データの性質・分析目的・運用制約の 3 軸で決まる。 以下に典型シナリオと対応する手法の組合せを示す。

典型シナリオ別の手法選択

シナリオ重視する観点候補手法
大規模・高次元 (n > 1e6, d > 1e4)計算効率 / スパース対応SGDClassifier (log loss), LogisticRegression(solver='saga') + L1, Vowpal Wabbit
クラス不均衡 (陽性率 < 5%)少数クラスの誤分類を重視class_weight='balanced', SMOTE で oversampling, Focal Loss
係数の解釈・統計的検定が必要オッズ比 / Wald 検定statsmodels Logit (summary で z / p 値 / 95%CI), GLM(family=Binomial())
特徴量が非線形・交互作用表現力 / 自動的特徴抽出LightGBM / XGBoost, GAM (一般化加法モデル), 多項式特徴 + ロジスティック回帰
データが少ない (n < 100) / 完全分離推定の発散回避Firth's penalized logistic, ベイズロジスティック (PyMC), 強い L2 正則化
確率を本当に確率として使うキャリブレーションCalibratedClassifierCV (Platt / Isotonic), Brier score / Reliability diagram で検証

選んだ後の検証ステップ

  1. 前処理確認: 標準化 / 欠損処理 / カテゴリ変数のエンコード が適切か
  2. ハイパラ調整: 交差検証で安定する値を選ぶ
  3. 性能評価: タスクに応じた指標 (RMSE / Accuracy / F1 / AUC / シルエット等) を複数併用
  4. 頑健性チェック: 別手法 / 別シードで結果が大きく違わないか確認
  5. 解釈: 結果を分野知識と照らし合わせ、 意味のある発見になっているか検討

🧭 直感を深掘り — シグモイド・ロジット・オッズ比・決定境界

上の「🎨 直感」を土台に、 ロジスティック回帰を貫く 4 つの視点を一段深く言語化する。 いずれも同じモデルを別角度から見たものであり、 相互に翻訳できることが本質。

① 確率をシグモイドでモデル化する

二値の結果 $y\in\{0,1\}$ の「1 になる確率」$p$ を直接線形式で書くと $[0,1]$ をはみ出す。 そこで線形結合 $z=\beta_0+\beta_1x_1+\dots$ を シグモイド関数 $\sigma(z)=1/(1+e^{-z})$ に通し、 必ず $0\sim1$ に収める。 $z$ が大きいほど $p\to1$、 小さいほど $p\to0$、 $z=0$ でちょうど $p=0.5$。 S 字の傾きが最も急なのは $p=0.5$ 付近で、 ここでは説明変数のわずかな変化が確率を大きく動かす。 逆に $p$ が 0 や 1 に近い端では、 同じだけ $z$ を動かしても確率はほとんど動かない(飽和)。

② 線形結合はロジット(対数オッズ)そのもの

シグモイドの逆関数を取ると $z=\log\dfrac{p}{1-p}$。 つまり線形結合 $z$ の正体は オッズ $p/(1-p)$ の対数(ロジット)である。 ロジスティック回帰は「確率そのもの」ではなく「対数オッズ」を線形にモデル化している、 と読むと係数の意味が一気に通る。 確率スケールでは非線形(S 字)だが、 ロジットスケールに移せば完全に線形——これが線形回帰の直感をそのまま持ち込める理由。

③ 係数はオッズ比の対数

$x_j$ を 1 単位増やすと $z$ は $\beta_j$ だけ増える。 ロジットが $\beta_j$ 増えることは、 オッズが $e^{\beta_j}$ 倍になることと同値。 よって$\exp(\beta_j)$ がオッズ比 (odds ratio, OR)。 $\beta_j>0\Rightarrow OR>1$(発生確率を上げる)、 $\beta_j<0\Rightarrow OR<1$(保護的)、 $\beta_j=0\Rightarrow OR=1$(影響なし)。 SSDSE-B-2026 の 2023 年 47 都道府県で「高齢化率(A1303/A1101)が中央値超かどうか」を目的変数(陽性 23 県・陰性 24 県のほぼ均衡)にし、 説明変数を標準化した総人口 log(A1101) と消費支出 log(L3221) で当てはめると、 総人口の OR ≈ 0.23(95%CI 0.08〜0.65, p≈0.006)——人口規模の大きい県ほど高齢化率が上位に入りにくい、 という強い負の関連が実データから読める(実測値・捏造なし)。

④ 決定境界はロジットが 0 になる面

閾値を $p=0.5$ にすると、 判定が切り替わるのは $z=0$、 すなわち $\beta_0+\beta_1x_1+\dots=0$ の面。 これは説明変数空間では直線(多次元なら超平面)で、 ロジスティック回帰が「線形分類器」と呼ばれる所以。 確率の等高線($p=0.3,0.5,0.7\dots$)はこの境界に平行に並ぶ。 非線形な境界が必要なら、 多項式特徴量・交互作用項を足すか、 分類の非線形手法(木・SVM・NN)へ切り替える。

⚠️ 落とし穴を深掘り — 解釈と推定の罠

ロジスティック回帰は「動く」が「正しく読む」のは難しい。 実務・コンペで踏みやすい 8 つの罠を、 対処とともに整理する。

1. オッズ比は限界効果ではない

最頻の誤読。 $\exp(\beta_j)$ はオッズの倍率であって「確率が何ポイント上がるか」ではない。 確率スケールの変化(限界効果 $\partial p/\partial x_j = \beta_j\,p(1-p)$)は今いる $p$ の位置に依存し、 $p=0.5$ 付近で最大、 端では小さい。 「OR=2」を「確率が 2 倍」「確率が +50%」と言い換えるのは誤り。 確率への効果を語りたいときは statsmodels の get_margeff() で平均限界効果 (AME) を出す。

2. 完全分離で係数が発散する

ある説明変数(の組合せ)だけで 0/1 を完璧に切り分けられると、 尤度を上げ続けるほど係数が $\pm\infty$ へ発散し、 最尤推定 (交差エントロピー最小化) が収束しない。 sklearn は L2 正則化が既定なので有限値を返すが「巨大な係数+巨大な標準誤差」に化ける。 対処: Firth のペナルティ付きロジスティック、 強めの正則化、 ベイズ事前分布、 あるいは分離を起こす変数の見直し。 標本が小さい(SSDSE の n=47 のような)場面ほど起きやすい。

3. 多重共線性で係数が不安定

説明変数どうしが強く相関すると、 個々の $\beta_j$ の符号・大きさが標本のわずかな違いで揺れ、 オッズ比の解釈が崩れる(多重共線性)。 予測精度は保たれても「どの要因が効くか」の話は信用できない。 VIF で確認し、 変数の統合・除去、 または Ridge(L2)で縮小する。

4. 予測確率が較正されているとは限らない

「モデルが 0.8 と言った群で実際に約 80% が陽性」であって初めて確率として使える。 正則化の強い設定・不均衡データ・誤特定では、 出力確率が系統的にずれる(キャリブレーションずれ)。 信頼度図 (reliability diagram) と Brier スコアで点検し、 Platt スケーリングや等温回帰 (isotonic) で補正する。 順位(AUC)は良くても確率値が信用できない、 は普通に起きる。

5. 不均衡データで多数派に引っ張られる

陽性率が数 % だと、 全部「陰性」と答えるだけで Accuracy が高く見え、 少数派の 再現率が壊滅する(クラス不均衡)。 class_weight='balanced'・オーバーサンプリング (SMOTE)・閾値調整で対処し、 評価は Accuracy でなく F1・AUC・PR 曲線を見る。

6. 線形分離(ロジット線形)の仮定

ロジスティック回帰が線形にするのはロジット。 説明変数と対数オッズの関係が実際は曲がっているのに直線を当てると、 系統的な当てはめ不足になる。 連続変数はビン化して各区間のロジットをプロットする、 スプライン・多項式項を足す等で非線形性を診断・吸収する。

7. 閾値 0.5 は任意

0.5 は「対称な誤りコスト・均衡データ」での既定値にすぎない。 見逃し (FN) と誤検出 (FP) のコストが違う(病気検出は FN 重視、 スパムは FP 重視)なら閾値をずらすべき。 ROC 曲線や PR 曲線で運用点を選ぶ。 閾値はモデルの外側で決めるパラメータであり、 係数推定とは別問題。

8. 外挿は危険

学習データの説明変数レンジの外では、 モデルは飽和領域($p\approx0$ または $1$)へ自信満々に張り付く。 だが根拠となるデータが無い領域なので、 その確信は幻。 予測時は入力が学習範囲内かを確認し、 範囲外の予測には強い留保を付ける。 n=47 の都道府県データのように標本が小さいと、 数県分だけレンジ外に出た瞬間に予測が不安定化する。

🚀 発展 — 推定・拡張・評価の地図

ロジスティック回帰を「一つの点」ではなく「大きな地図上の交差点」として捉えるための発展トピック。

最尤推定と交差エントロピー

係数は最尤推定 (MLE) で決める。 各観測の尤度 $p_i^{y_i}(1-p_i)^{1-y_i}$ の積を最大化することは、 負の対数尤度=交差エントロピー損失(log loss)の最小化と等価。 線形回帰の最小二乗と違い閉形式解はなく、 ニュートン法 (IRLS) や勾配降下で反復的に解く。 損失は凸なので(正則化ありなら強凸)、 局所最適に嵌まらず大域解に収束する。

オッズ比と限界効果の使い分け

「要因の相対的な効き」を語るなら $\exp(\beta_j)$(オッズ比)、 「確率が実際に何ポイント動くか」を語るなら限界効果 (AME)。 医学・疫学ではオッズ比、 政策・ビジネスの効果量説明では確率スケールの限界効果が好まれる。 両者は同じモデルの別表現で、 どちらを報告するかは聞き手の問いで選ぶ。 SSDSE の 2 変数モデルでは総人口 OR≈0.23 と強い一方、 消費支出 OR≈0.72 は 95%CI が 1 をまたぎ(p≈0.39)有意でない——CI が 1 を含むかがオッズ比読解の第一関門。

多クラスへの拡張(softmax)

3 クラス以上は多項ロジスティック回帰。 シグモイドを softmax $\;p_k=e^{z_k}/\sum_j e^{z_j}$ に置き換え、 各クラスの線形結合を確率ベクトルへ正規化する。 二値のシグモイドは softmax の 2 クラス特例。 sklearn では multi_class='multinomial'(または既定の自動選択)で扱える。

正則化(L1 / L2 / Elastic Net)

過学習・不安定さ対策に正則化を足す。 L1 (Lasso) は係数を 0 に落として変数選択、 L2 (Ridge) は係数を縮小して安定化、 Elastic Net はその中間。 sklearn の C はペナルティの逆数(C 小=強い正則化)で、 既定 C=1.0 は弱め。 n が小さいときは C を下げる価値がある。 正則化は完全分離の発散も抑える。

プロビットとの違い

プロビット回帰はリンク関数に標準正規 CDF $\Phi(z)$ を使う。 シグモイド(ロジット)は裾がやや重く、 実務では推定確率はほぼ一致する。 決定的な違いは係数の解釈: ロジットは exp してオッズ比という直接解釈ができるのに対し、 プロビット係数にはオッズ比解釈がない。 解釈性を重視するならロジット、 潜在変数モデル(正規誤差の閾値モデル)として組みたいならプロビット。

GLM の一員として

ロジスティック回帰は一般化線形モデル (GLM) の「二項分布 + ロジットリンク」の特例(ロジスティック GLM)。 誤差分布とリンク関数を差し替えれば、 ポアソン回帰(計数)・線形回帰(正規+恒等リンク)などと同じ枠組みで一望できる。 statsmodels の GLM(family=Binomial()) でもロジスティック回帰が書ける。

ROC / AUC による評価

分類性能は閾値に依存するため、 閾値を動かしながら TPR–FPR を描く ROC 曲線と、 その下面積 AUC で総合評価する。 AUC=0.5 は当てずっぽう、 1.0 が完璧、 0.8 以上で実用的とされる。 SSDSE の標準化 2 変数モデルでは AUC≈0.82・McFadden 擬似 R²≈0.26(実測)と、 47 県という小標本のわりに素直な分離が得られる。 不均衡が強い場面では ROC より PR 曲線が実態を映す。