論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
Log Loss
Logarithmic Loss
評価指標

🔖 キーワード索引

「Log Loss」を取り巻く中核キーワード群です。 検索やインデックス作成で参照する際の手がかりにしてください。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になります。

LogLossCross-Entropy対数損失確率予測calibrationbinarymulticlassBrier

💡 30秒で分かる結論 — Log Loss

🍰 まずはやさしく

予測の自信を測るものさしです。

確率の正しさを評価するために使います。

テストの正解率だけでなく、確信度を測る例です。

まずは結論から簡単に説明します。

最も忙しい読者のために、 まず結論だけまとめます。 詳細は以下のセクションへ:

📍 文脈 — どこで出会うか

🍰 まずはやさしく

予測の質を詳しく見る道具です。

当たったか外れたか以上の情報を知るために使います。

天気予報の自信がどれくらい正しいか測る例です。

どのような場面で使うのかを解説します。

「天気予報の精度を測る」 「医療診断の確率を評価」 — 単に「当たった/外れた」だけでなく、 確信度 を含めて評価したいときに使う指標。

このページの読み方:まず 30秒結論 と 直感 を読み、 必要に応じて 数式 や 計算例、 落とし穴 に進んでください。

本ページでは対数損失 (Log Loss / Cross Entropy / Negative Log Likelihood) を扱う。 確率予測の評価指標であり、 同時にロジスティック回帰やニューラルネット分類器の損失関数として直接最適化される。 「予測確率と真の確率分布の隔たり」を測る情報理論的指標。

対数損失は精度 (Accuracy) や AUC とは異なり「予測確率そのもの」を評価する。 0.51 と 0.99 はどちらも分類は正解だが、 log loss は確信度の差を区別する。 Kaggle 等の確率予測コンペで標準指標。 完全に外した予測 (確率 0 で実は 1) では対数が -∞ に発散するため、 クリッピング (ε) が必須。

🎨 直感で掴む

🍰 まずはやさしく

自信満々に外すと点数が下がる仕組みです。

慎重に確率を予測させるために使います。

スマホの予測変換がどれだけ自信があるか測る例です。

イメージ図を使って直感的に説明します。

天気予報を例に:

「自信ありで外す」を最も嫌うのが Log Loss の特徴。

🎨 概念図で押さえる

Log Loss (交差エントロピー損失) を 3 枚で。 (1) 正解=1 のときの −log(p) 曲線、 (2) Accuracy だけでは見えない確信度の違い、 (3) クラス不均衡時の重み付け効果。 Accuracy/Precision との「使い分け感」を視覚化する。

図 1: −log(p) の発散 — 自信過剰の予測を強く罰する

正解 y=1 に対して p (=モデル予測確率) を下げるほど損失が急増、 p→0 で発散。 「90% 自信あり」と言って外したら大ペナルティ、 「51% 自信あり」で外したらまだ許される、 という性質を表す。

-log(p) curve diverging as p approaches 0

p=0.2 で外すと loss=1.61、 p=0.9 で外すと loss=2.30 (大きい)。 確信度のキャリブレーションが評価対象に含まれる。

図 2: Accuracy 同じでも Log Loss は異なる

2 つのモデル A・B が同じ Accuracy=80% を出していても、 確信度の出し方が違えば Log Loss は別の値になる。 「ぎりぎり当てた」モデルより「自信を持って当てた」モデルが好まれる。

Two models with same accuracy but different log loss bars

Log Loss はリスク評価・確率予測 (例: 与信スコア・医療診断確率) において、 単なる正解率では見えない「信頼性」を測る役割を持つ。

図 3: クラス不均衡時の重み付け Log Loss

陽性クラスがレアな場合 (例: 不正検知 1%)、 sample weight や class weight を Log Loss に組み込むことで、 多数派クラスに引きずられた予測を抑える。

Class imbalance weighting effect on log loss

scikit-learn の log_loss(y_true, y_pred, sample_weight=...) や XGBoost の scale_pos_weight がこの考え方を実装している。

関連: 交差エントロピー・評価指標・AUC・ROC 曲線。

📝 理解度チェック(練習問題)

Log Loss の核を本当に掴めたかを 6 問で確認する。 すべて 1 分以内で答えられる粒度。 「自分で」答えを口に出して言える状態を目指したい。

Q1. なぜ Accuracy ではなく Log Loss を見るのか

狙い:Accuracy は閾値 0.5 で「当たり/外れ」を 0-1 化するので 確信度を見ていない。 Log Loss は予測確率そのものを評価し、 「90% 自信あり」と「51% 自信あり」を区別できる。

Q2. p=0.9 で正解 (y=1)、 p=0.1 で正解 (y=1)、 どちらが Log Loss は大きいか

狙い:p=0.1 のほうが大きい。 −log(0.1)=2.30、 −log(0.9)=0.11。 確信度が低いまま正解しても、 Log Loss は大きく罰する。

Q3. Log Loss が −∞ に発散するのはいつ

狙い:「正解 y=1 に対し p=0」または「正解 y=0 に対し p=1」と 完全に確信を持って外したとき。 実装では p ∈ [ε, 1−ε] にクリップして安全に。

Q4. 多クラス分類の Log Loss は

狙い:−Σᵢ Σ_c y_ic log p_ic。 各サンプルで正解クラスの予測確率に −log を当てて全部足す。 2 クラスの式の自然な拡張。

Q5. クラス不均衡で Log Loss を使うときの注意

狙い:多数派を全部「陰性」と予測しても Log Loss は低くなりがち。 sample_weight や scale_pos_weight で少数派の重みを上げるのが定石。

Q6. Log Loss と Brier Score の使い分け

狙い:Brier は (p − y)² で外れの距離を 2 乗で測る。 Log Loss は −log で発散項を持つ。 確信度の校正 (calibration) を厳しく測りたいなら Log Loss、 実装簡便さなら Brier。

これらの問題に詰まった項目があれば、 「−log(p) の発散」「重み付け」のセクションへ戻ろう。 確率予測の評価指標は「正解か否か」ではなく「どれだけ自信を持っているか」を評価する点が肝心。

🎮 触って理解する

正解ラベル $y$(0/1)を切り替え、 予測確率 $p$ をスライダーで動かすと、 対数損失 $-[y\log p + (1-y)\log(1-p)]$(自然対数)がリアルタイムに計算され、 損失曲線上に現在点が表示されます。 正解に自信を持てば損失は小さく、 外れた方向に自信を持つほど損失が急増($p\to0$ で $\infty$) する非対称な罰を体感してください。

正解ラベル y

対数損失
0.693
五分五分の予測。
複数サンプルの平均対数損失

4 つの予測それぞれで正解ラベルと確率を動かし、 平均 $\frac{1}{N}\sum_i \ell_i$ がどう変わるか観察しましょう。

平均対数損失 = —

🧠 解説を深める

直感(確率的予測の良さを測る):対数損失は「当たったか外れたか」ではなく「どれだけ正しい確率を割り当てたか」を測る。 正解クラスに割り当てた確率が高いほど $-\log p$ は $0$ に近づき、 低いほど無限大に発散する。 これは 確率で答える誠実さ への報酬・罰と読める。

自信過剰を罰する非対称性:$p=0.9$ で外すと $-\log(0.1)=2.303$、 $p=0.99$ で外すと $-\log(0.01)=4.605$ と、 確信の度合いに応じて罰が跳ね上がる。 一方で正解方向に強い確信を持っても損失はほぼ $0$ 止まり。 この非対称性が「わからないところは無理に $0/1$ に振らず、 正直な確率を出せ」という圧力を生む。

よくある落とし穴:(1)$p=0$ または $p=1$ でのクリップ — 予測が完全に $0$/$1$ だと $\log$ が発散し損失が $\infty$ になる。 実装では $p\in[\varepsilon,\,1-\varepsilon]$(例 $\varepsilon=10^{-15}$)にクリップする。 scikit-learn の log_loss も内部でクリップしている。 (2)確率のキャリブレーション — 対数損失が小さいことは「確率が校正されている($p=0.7$ と言った事象は本当に約 $70\%$ 起きる)」ことと結び付く。 分類精度だけ高くても、 出力確率が歪んでいれば対数損失は悪化する。

発展(クロスエントロピー・最尤との等価):二値の対数損失は真の分布 $y$ と予測分布 $\hat p$ の クロスエントロピー $H(y,\hat p)$ そのものであり、 多クラスへは $-\sum_c y_c\log\hat p_c$ と自然に一般化される。 さらに、 対数損失の最小化は各サンプルの尤度 $\prod_i \hat p_i^{y_i}(1-\hat p_i)^{1-y_i}$ の 負の対数尤度の最小化=最尤推定 と等価。 ロジスティック回帰やニューラルネット分類器が対数損失を標準の損失関数に採る理由はここにある。

関連: 交差エントロピー・ロジスティック回帰・Accuracy・評価指標。 (Brier Score・キャリブレーション・最尤推定の単独ページは現時点で未作成のためリンクなし。)

📐 定義・数式

🍰 まずはやさしく

計算で正しさを出すための式です。

予測のズレを数字にするために使います。

部活の試合結果を確率で計算する例です。

具体的な数式とその意味を解説します。

【二値分類の Log Loss】
$$\text{LogLoss} = -\frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log \hat{p}_i + (1-y_i) \log(1 - \hat{p}_i) \right]$$
【多クラスのクロスエントロピー】
$$\text{CE} = -\frac{1}{N} \sum_{i=1}^{N} \sum_{c=1}^{C} y_{ic} \log \hat{p}_{ic}$$
$y_{ic}$=one-hot ラベル、 $\hat{p}_{ic}$=クラス $c$ の予測確率

🔬 記号・要素の読み解き

$y_i$
真値ラベル(0 or 1)。
$\hat{p}_i$
予測した確率(0 ≤ p ≤ 1)。
$\log \hat{p}_i$
正解クラスに付けた確率の対数。 高確率なら小さい絶対値、 低確率なら大きい絶対値。
負号
$\log$ は負の値になるため、 最小化対象として正値にする。
$\hat{p}_i = 0$ or $1$
$\log 0 = -\infty$。 完全な確信は危険。 一般に $\epsilon$ でクリップ。

🔬 数式を言葉で読み解く(詳細版)

「Log Loss」は 確率予測の精度を測る損失関数。確信を持って外すと巨大なペナルティ。 です。 ここでは定義式の各記号、 直感的意味、 SSDSE-B-2026 への当てはめを段階的に解きほぐします。

① Log Loss の定義式と各記号

二値分類の Log Loss
$$\text{LogLoss} = -\frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log \hat{p}_i + (1-y_i) \log(1 - \hat{p}_i) \right]$$
N はサンプル数、 $y_i \in \{0, 1\}$ は真のラベル、 $\hat{p}_i \in (0, 1)$ は予測確率。
$y_i$
真のラベル。 0 (陰性) or 1 (陽性)。 SSDSE-B-2026 の例:「高齢化率 > 30%」のフラグ。
$\hat{p}_i$
モデルが予測した陽性確率。 ロジスティック回帰なら $\sigma(w^\top x + b)$。
$y_i \log \hat{p}_i$
陽性 (y=1) のとき:予測確率が大なら $\log$ は 0 に近づき、 小なら大きな負値。 ペナルティ大。
$(1-y_i) \log (1-\hat{p}_i)$
陰性 (y=0) のとき:予測「非陽性確率」 $1 - \hat{p}_i$ の対数。 陰性なのに $\hat{p}_i$ を大きく付けると爆発。
負号
$\log$ は (0,1) で負値。 損失は正値にしたいので符号反転。
$\frac{1}{N}$
サンプル平均。 データセットサイズに依らず比較可能。

② 多クラスへの拡張(Categorical Cross-Entropy)

多クラス交差エントロピー
$$\text{CE} = -\frac{1}{N} \sum_{i=1}^{N} \sum_{c=1}^{C} y_{ic} \log \hat{p}_{ic}$$
$y_{ic}$ は one-hot エンコード(正解クラスだけ 1)、 $\hat{p}_{ic}$ は softmax 出力。

③ なぜ「対数」なのか — 情報理論との関係

Log Loss は Shannon エントロピーの負数 $-\log p$ に基づく。 情報量 $-\log p$ は「確率 $p$ の出来事が起きた時の驚き度」を表す。 Log Loss はモデルが正解ラベルを見た時の「平均驚き度」を最小化する。 つまり「外したくないなら高確率を当てよ」というインセンティブ設計。

④ なぜ MLE と等価か

ベルヌーイ分布 $P(y \mid \hat{p}) = \hat{p}^y (1-\hat{p})^{1-y}$ の対数尤度は $y \log \hat{p} + (1-y) \log (1-\hat{p})$。 Log Loss はこの負対数尤度の平均。 ロジスティック回帰の MLE と Log Loss 最小化は数学的に等価。

⑤ Log Loss の値の解釈

Log Loss 値意味例
0完全予測全 $\hat{p}_i = y_i$
0.693$\log 2$、 全予測 0.5 のランダム無情報モデル
1.0かなり不正確正解確率 $\approx 0.37$
$\infty$確信を持って外す$\hat{p}=0$ なのに $y=1$

SSDSE-B-2026 で「Log Loss」を体感する

SSDSE-B-2026 で「高齢化率 > 30% を予測するロジスティック回帰の Log Loss」。 入力は 都道府県の総人口・出生数・15歳未満人口の比率、 出力は 高齢化率 (65歳以上人口/総人口) > 30% かどうかの 2 値ラベル。 47 都道府県 × 複数年の実データで具体計算を実施します。

🏭 産業界での活用事例(6 件)

業界事例役割SSDSE-B-2026 との対比
広告クリック予測Google・Meta の CTR 予測モデル確率の精度が収益に直結出生率予測モデルの評価に応用可
医療診断 AIX 線画像から肺癌確率を予測確信度の校正が患者説明に必須都道府県別罹患率推定の指標
Kaggle コンペ確率予測タスクの標準評価指標順位決定に直接使われるSSDSE-B の指標予測コンペで利用可
クレジットリスク個人の延滞確率予測規制(バーゼル III)でも校正が要求都道府県別経済指標と関連
天気予報気象庁の降水確率Brier Score と並んで採用豪雨件数の確率予測
AI チャットボット次トークンの確率分布学習言語モデルの標準損失テキスト生成・分類すべて

⚖️ 関連手法との比較表

手法定義特徴用途
Log Loss対数で確率を評価確信ペナルティが無限大確率予測
Brier Score二乗誤差で確率を評価ペナルティは有界(0-1)確率予測
Accuracy0/1 正解率確率の質を測れない閾値後の判定
AUC-ROCランキング能力確率の絶対値は問わない陽性陰性の順位
Hinge LossSVM 用、マージン重視確率出力ではない分類境界
Focal LossLog Loss の不均衡対応版簡単な例にペナルティ小物体検出
KL Divergence分布間の距離二分布の比較知識蒸留

💥 失敗例から学ぶ

💥 確率 0 や 1 を出さない
log(0) = -∞ で Log Loss が爆発する。 sklearn は内部で $\epsilon=10^{-15}$ にクリップするが、 自前実装では明示的に `np.clip(p, 1e-15, 1-1e-15)` を入れる。
💥 クラス不均衡で見かけ良好
陽性率 1% のとき全部 $\hat{p}=0.01$ と予測すれば Log Loss は小さい。 PR-AUC や Recall も併用すべき。
💥 Accuracy と混同しない
Log Loss は確率の質、 Accuracy は閾値後の 0/1 判定。 LogLoss 悪化=確信度の校正不足のサインで、 Accuracy 低下とは別問題。
💥 対数の底に注意
scikit-learn は自然対数 (log_e)、 教科書によっては log_2 (情報量を bit で測る)。 比較時は底を統一すること。
💥 calibration を別途確認
Log Loss が良くても「予測 80% のサンプル群で実際に 80% が陽性」とは限らない。 reliability diagram で校正状況を可視化。

📝 演習問題(5 問・解答付き)

  1. 問題 1:y = [1, 0, 1, 1, 0], p = [0.9, 0.1, 0.7, 0.3, 0.4] のとき Log Loss を計算せよ。
    ▼ 解答
    1
    2
    3
    4
    5
    import numpy as np
    y = np.array([1,0,1,1,0])
    p = np.array([0.9,0.1,0.7,0.3,0.4])
    ll = -np.mean(y*np.log(p) + (1-y)*np.log(1-p))
    print(ll)  # 約 0.456
    
    📤 実行例(実測) 0.4564388806692623

    💬 5 件それぞれの −log(正解側に付けた確率)は 0.105・0.105・0.357・1.204・0.511 で、平均が 0.456。4 件目は正解が 1 なのに 0.3 しか付けておらず、これ 1 件で合計 2.28 のうち半分以上(1.204)を占める。確率 0.5 を一律に出すだけのモデルでも log 2≈0.693 になるので、0.456 はそれよりは良いが、外した 1 件の重さが目立つ。

  2. 問題 2:SSDSE-B-2026 で「高齢化率 > 30%」を予測するロジスティック回帰を作り Log Loss を計算せよ。
    ▼ 解答
    📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) A1303(65歳以上人口) A1101(総人口) A4101(出生数) 北海道 2,023 1,681,000 5,092,000 24,430 東京都 2,023 3,205,000 14,086,000 86,348 沖縄県 2,023 350,000 1,468,000 12,549 …(全 47 行)
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    import pandas as pd
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import log_loss
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)   # 日本語の列名で読む(2 行目を見出しにする)
    d = df[df['年度']==2023].copy()
    d['高齢化率'] = d['65歳以上人口']/d['総人口']
    d['ラベル'] = (d['高齢化率']>0.30).astype(int)
    X = d[['総人口','出生数']].values
    y = d['ラベル'].values
    m = LogisticRegression().fit(X,y)
    p = m.predict_proba(X)[:,1]
    print(log_loss(y, p))
    
    📤 実行例(実測) 0.19921313595439344

    💬 2023 年度の 47 県のうち高齢化率 30% 超は 35 県で、全県に 35/47 を一律に出すだけの基準の log loss は 0.568。総人口と出生数を使ったモデルは 0.199 まで下げたが、学習に使った 47 県をそのまま評価しているので楽観的な値である。誤分類は宮城県・滋賀県・京都府・広島県の 4 県で、東京都のように人口の大きい県には 2×10⁻¹⁰ のような極端に小さい確率が付いている。こうした自信過剰な予測が 1 件外れるだけで log loss は大きく跳ねるので、交差検証で確かめたい。

  3. 問題 3:確率 $\hat{p}=0$ で真値 $y=1$ のとき Log Loss は何になるか。 sklearn 実装の場合は?
    ▼ 解答
    理論値は $-\log 0 = +\infty$。 sklearn は内部で $\epsilon = 10^{-15}$ にクリップするため、 約 $-\log(10^{-15}) \approx 34.5$ となる。
  4. 問題 4:Log Loss と Accuracy が逆相関になる例を作れ。
    ▼ 解答
    全サンプルに $\hat{p}=0.51$ と予測すると Accuracy は 100%(真値 1 ならば)だが Log Loss は $-\log 0.51 \approx 0.673$ で悪い。 一方 $\hat{p}=0.99$ なら Log Loss $\approx 0.01$ で大幅改善。
  5. 問題 5:SSDSE-B-2026 で「高齢化フラグ」予測モデルを 3 つ比較し、 Log Loss が最小のものを選べ。
    ▼ 解答
    ロジスティック回帰、 RandomForest、 GradientBoosting を学習し、 `log_loss(y, m.predict_proba(X)[:,1])` で比較。 コード 4 の 5 分割交差検証では RandomForest が 0.175 で最小、 LogisticRegression 0.357、 GradientBoosting 0.375 だった。

📖 関連用語辞典(10 語)

Log Loss
対数損失。 二値・多クラスの確率予測モデルの標準損失関数。
Cross-Entropy
クロスエントロピー。 多クラス Log Loss の別称。
Brier Score
二乗誤差版の確率評価指標。 $(\hat{p} - y)^2$ の平均。
Calibration
校正。 予測確率が実際の頻度と一致する性質。
Negative Log Likelihood (NLL)
負対数尤度。 Log Loss と等価。
Softmax
多クラス確率出力に変換する関数。 NN の最終層で使用。
Sigmoid
二値確率を出力する関数 $\sigma(z) = 1/(1+e^{-z})$。
Focal Loss
Log Loss を不均衡データ向けに改良したもの。
KL Divergence
2 分布間の距離。 知識蒸留・VAE で使う。
Entropy
情報量の期待値 $H(p) = -\sum p_i \log p_i$。

🧮 実値で計算してみる

4 サンプルで LogLoss 計算:

yp̂寄与
10.9−log(0.9) ≈ 0.105
00.2−log(0.8) ≈ 0.223
10.6−log(0.6) ≈ 0.511
10.1−log(0.1) ≈ 2.303

平均 = (0.105+0.223+0.511+2.303)/4 ≈ 0.785。 4 つめのサンプルが大幅にスコア悪化に寄与(自信を持って外したため)。

🧮 数式に値を入れて手で計算する: バイナリログロス

合成 5 サンプルでログロス (交差エントロピー) を計算する。

Step 1: 真値と予測

iyŷ損失
110.90.105
200.20.223
310.70.357
400.10.105
510.60.511

Step 2: 平均ログロス

LL = -(y·log ŷ + (1-y)·log(1-ŷ)) i=1: -log 0.9 ≈ 0.105 i=2: -log 0.8 ≈ 0.223 平均 = (0.105+0.223+0.357+0.105+0.511)/5 = 1.301/5 ≈ 0.260

🐍 Python で再現

1
2
3
4
5
6
import numpy as np
y = np.array([1, 0, 1, 0, 1])
yhat = np.array([0.9, 0.2, 0.7, 0.1, 0.6])
ll = -(y*np.log(yhat) + (1-y)*np.log(1-yhat))
print(f"ログロス: {ll.round(3)}")
print(f"平均: {ll.mean():.3f}")

📤 実行結果

ログロス: [0.105 0.223 0.357 0.105 0.511] 平均: 0.260

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

🐍 Python での扱い

最小再現コード。 SSDSE-B のような実データを前提に、 4〜8 行で動く例です:

1
2
3
4
from sklearn.metrics import log_loss
y_true = [1, 0, 1, 1]
y_prob = [0.9, 0.2, 0.6, 0.1]
print(f'LogLoss = {log_loss(y_true, y_prob):.4f}')
📤 実行例(実測) LogLoss = 0.7855

💬 −log の内訳は 0.105(0.9)・0.223(0.8 で 0 を当てた)・0.511(0.6)・2.303(0.1)で、平均が 0.7855。最後の 1 件、正解 1 に 0.1 しか付けなかったものが合計の 73% を占め、これを除いた 3 件の平均は 0.280 にすぎない。正解率なら 4 件中 3 件正解の 75% だが、log loss は「自信を持って外した」1 件を強く罰する指標である。

補足:ライブラリのバージョンや前処理状態によって出力は変わります。 自分の環境で動かすときは pip list でバージョンを確認し、 入力 CSV のパス・列名を実態に合わせてください。

🐍 Python 完全コード(4 要素ナレーション付き)

コード 1:SSDSE-B-2026 で「高齢化率 > 30%」予測モデルの Log Loss

🎯 このコードでやること:47 都道府県の総人口・出生数から「高齢化率 > 30%」を予測するロジスティック回帰を学習し、 Log Loss を測定。

📥 入力データ:SSDSE-B-2026 の 2023 年データを抽出、 65歳以上人口÷総人口で高齢化率を計算しラベル化。

都道府県 総人口 出生数 高齢化率 ラベル 北海道 5092000 24430 0.33 1 青森県 1184000 5696 0.35 1 東京都 14086000 86348 0.23 0 ...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import log_loss

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
d  = df[df['年度']==2023].copy()
d['高齢化率'] = d['65歳以上人口'] / d['総人口']
d['ラベル']   = (d['高齢化率'] > 0.30).astype(int)

X = d[['総人口', '出生数']].values
y = d['ラベル'].values

m = LogisticRegression(max_iter=1000).fit(X, y)
p = m.predict_proba(X)[:, 1]

print(f"陽性率   : {y.mean():.3f}")
print(f"Log Loss : {log_loss(y, p):.4f}")
print(f"Accuracy : {m.score(X, y):.4f}")

📤 実行結果:

陽性率 : 0.745 Log Loss : 0.1992 Accuracy : 0.9149

💬 結果の読み方:47 都道府県のうち約 75% が高齢化率 > 30%(既に進行)。 Log Loss 0.20 は良好な水準で、 Accuracy 0.91 と併せて「確率予測の質も分類精度も高い」と判断できる。 ベースライン(全予測 0.745)の Log Loss は約 0.57 なので、 モデルが情報を大きく引き出している。

コード 2:Log Loss と Brier Score を同時計算

🎯 このコードでやること:同じモデルの予測について Log Loss と Brier Score を比較し、 評価指標の違いを確認する。

📥 入力データ:上記モデルの予測確率 p と真値 y。

(前のコードで p, y を取得済み)
1
2
3
4
5
from sklearn.metrics import log_loss, brier_score_loss

print(f"Log Loss     : {log_loss(y, p):.4f}")
print(f"Brier Score  : {brier_score_loss(y, p):.4f}")
print(f"Log Loss (random p=0.5) : {log_loss(y, [0.5]*len(y)):.4f}")

📤 実行結果:

Log Loss : 0.1992 Brier Score : 0.0613 Log Loss (random p=0.5) : 0.6931

💬 結果の読み方:Brier Score (二乗誤差) は有界(0-1)で穏やか、 Log Loss は外れに敏感。 0.20 vs 0.06 という違いだけでは優劣を語れないが、 「ランダム 0.693 より 0.199 = 約 71% 改善」と読むと意味がはっきりする。

コード 3:Log Loss の確信ペナルティを実感

🎯 このコードでやること:予測確率 p を 0.01〜0.99 まで変えたとき、 真値 y=1 に対する Log Loss を可視化。

📥 入力データ:y_true = 1, p in [0.01, 0.05, 0.1, 0.3, 0.5, 0.7, 0.9, 0.99]

y = 1, p を範囲で変動
1
2
3
4
5
6
7
import numpy as np

ps = np.array([0.01, 0.05, 0.1, 0.3, 0.5, 0.7, 0.9, 0.99])
losses = -np.log(ps)

for p, l in zip(ps, losses):
    print(f"p={p:.2f}  ->  -log(p) = {l:.4f}")

📤 実行結果:

p=0.01 -> -log(p) = 4.6052 p=0.05 -> -log(p) = 2.9957 p=0.10 -> -log(p) = 2.3026 p=0.30 -> -log(p) = 1.2040 p=0.50 -> -log(p) = 0.6931 p=0.70 -> -log(p) = 0.3567 p=0.90 -> -log(p) = 0.1054 p=0.99 -> -log(p) = 0.0101

💬 結果の読み方:p=0.99 で外したら Log Loss は約 4.6 と巨大。 p=0.5 (ランダム) は 0.69。 「自信を持って外す」と平均が指数的に悪化することがわかる。 だからモデルは安易に 0/1 を出さず、 不確実な事例には 0.4-0.6 程度の予測を出すよう学習される。

コード 4:47 都道府県でモデル比較 (LogReg vs RandomForest vs XGBoost)

🎯 このコードでやること:同じ「高齢化率 > 30%」予測タスクで 3 モデルの Log Loss を CV で比較する。

📥 入力データ:X = 総人口・出生数・15歳未満人口、 y = 高齢化フラグ、 47 都道府県データ

都道府県 総人口 出生数 15歳未満人口 ラベル 北海道 5092000 24430 514000 1 青森県 1184000 5696 118000 1 ...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.model_selection import cross_val_score

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
d  = df[df['年度']==2023].copy()
d['ラベル'] = (d['65歳以上人口']/d['総人口'] > 0.30).astype(int)

X = d[['総人口', '出生数', '15歳未満人口']].values
y = d['ラベル'].values

for name, M in [('LogReg', LogisticRegression(max_iter=1000)),
                ('RandomForest', RandomForestClassifier(n_estimators=100, random_state=0)),
                ('GBoost', GradientBoostingClassifier(n_estimators=100, random_state=0))]:
    s = cross_val_score(M, X, y, scoring='neg_log_loss', cv=5)
    print(f"{name:14s}: {-s.mean():.4f}")

📤 実行結果:

LogReg : 0.3572 RandomForest : 0.1748 GBoost : 0.3748

💬 結果の読み方:RandomForest が最良 (0.175)。 47 都道府県は小さいデータだが、 木系モデルが非線形パターンを捕捉。 ロジスティック回帰は線形仮定でやや劣り、 GBoost は小データで過学習気味 (CV では LogReg と同程度)。 production 採用なら RandomForest か LightGBM が第一候補。

❓ FAQ 20 問

Q1. Log Loss と Cross-Entropy は同じ?
本質的に同じ。 二値の場合「Log Loss」、 多クラスの場合「Cross-Entropy」と呼ぶ慣習。 数学的には負対数尤度の平均。
Q2. 対数の底は?
scikit-learn は自然対数 ($\log_e$)。 情報理論では $\log_2$ (単位はビット)。 比較時は底を統一する。
Q3. Log Loss が無限大になる条件は?
予測確率が 0 で真値が 1、 または 1 で真値が 0。 実装ではクリップで回避。
Q4. Log Loss と Accuracy のどちらを使うべき?
確率の質も重要なら Log Loss、 0/1 判定の正解率なら Accuracy。 両方併用が無難。
Q5. ベースラインの Log Loss は?
全予測 = 陽性率なら、 Log Loss = $-p \log p - (1-p)\log(1-p)$ (= 真の Bernoulli エントロピー)。 これより小ければモデルが情報を引き出している。
Q6. Log Loss が 0.693 を超える状況は?
ランダム予測 (p=0.5) より悪いということ。 モデルが「逆を予測している」可能性大。 ラベル反転バグや特徴量バグを疑う。
Q7. クラス不均衡対応
class_weight='balanced' や Focal Loss を検討。 PR-AUC や Recall も併用。
Q8. Log Loss を最小化したらどんなモデルになる?
校正された確率予測モデル(reliability diagram が y=x に近い)。 これは Brier Score の最小化とも一致。
Q9. ロジスティック回帰の Log Loss と MLE の関係
数学的に同値。 Log Loss 最小化 = MLE = Cross-Entropy 最小化。
Q10. Log Loss は微分可能?
予測確率に対して滑らかで微分可能 (シグモイドと組み合わせると勾配 = $\hat{p} - y$ という綺麗な形)。
Q11. 多クラス Log Loss の計算
log_loss(y_true, y_prob, labels=[0,1,2,...])。 y_prob は (N, C) 形状で各行 sum=1。
Q12. softmax + Log Loss の数値安定化
log_softmax を使うと NumPy の under/overflow を回避できる。 PyTorch では F.cross_entropy がそれを内蔵。
Q13. Log Loss が学習中に振動
学習率が大きすぎる、 バッチサイズが小さすぎる、 ラベルノイズ。 学習率を $10^{-3} \sim 10^{-4}$ に下げる。
Q14. Log Loss が下がらない
モデルが小さすぎる、 特徴量不足、 ラベルが間違っている。 baseline (定数予測) と比較してから判断。
Q15. Log Loss と AUC のどちらが良い?
用途次第。 確率校正なら Log Loss、 ランキング能力なら AUC。 確率を確率として使うなら Log Loss が必須。
Q16. Log Loss は何ビット?
$\log_2$ で見れば情報理論的 bit。 例えば 0.693 nat = 1 bit (Shannon エントロピー)。
Q17. Negative Log Likelihood (NLL) との違い
ほぼ同じ。 NLL は -logL/N、 Log Loss は同じものをサンプル平均で表現。
Q18. Kaggle で Log Loss が重要なコンペは?
クレジットスコア、 病気診断、 ユーザ離脱予測、 CTR 予測などの「確率を直接使う」タスク。
Q19. Log Loss の解釈を顧客に説明する
「平均的にどれくらい確信を間違えているか」と表現。 0 が完璧、 ランダムが 0.69、 数値が小さいほど良い。
Q20. SSDSE-B-2026 で Log Loss を学ぶ最小例
上記コードブロック (高齢化率予測) が代表例。 47 都道府県と小規模だが、 Log Loss の概念は完全に体感できる。

📖 Log Loss の包括ガイド(追補編)

🔍 Log Loss の多角的解釈

情報理論的解釈

Shannon Entropy $H = -\sum p \log p$ の負数。 「確率分布の予測の平均驚き度」を最小化。 これが「真の分布に近づくこと」と等価。

ベイズ統計との関係

事前分布 + 尤度 → 事後分布。 Log Loss は対数尤度の負数なので、 「事後確率最大」と密接。

ロジスティック回帰の MLE

ベルヌーイ尤度の対数 = Log Loss。 ロジスティック回帰の重み学習 = Log Loss 最小化。

NN との接続

Sigmoid + BCE の勾配 = p - y、 Softmax + CE の勾配 = p - y_onehot。 数学的に綺麗で、 NN 学習の基本。

Kaggle での実態

確率予測コンペでは LL がほぼ唯一の評価指標。 Stacking + Calibration で 0.001 単位を争う。

📓 「Log Loss」をさらに深掘り — 実データ実践ノート

SSDSE-B-2026 を使った段階的ハンズオン。 初学者→中級→上級と順に深めるシナリオ構成です。

ステップ 1: データを読む

SSDSE-B-2026.csv を pd.read_csv(encoding='cp932', skiprows=1) で読み込み、 2023 年の 47 都道府県データを抽出する。

ステップ 2: ラベル作成

「高齢化率 = 65歳以上人口 / 総人口」を計算し、 30% 超なら 1 のフラグを作成。 47 県中 35 県が陽性 (約 74%)。

ステップ 3: 特徴量設計

総人口・出生数・15歳未満人口を選択。 単位を揃えるため StandardScaler で標準化推奨。

ステップ 4: ロジスティック回帰

LogisticRegression() を学習。 predict_proba() で確率を取得。

ステップ 5: Log Loss 計算

log_loss(y, p) で測定。 ベースライン (全予測 0.74) と比較して評価。

ステップ 6: 校正診断

calibration_curve で reliability diagram を作成。 直線 y=x に近ければ校正済。

ステップ 7: 閾値最適化

Accuracy・Precision・Recall が望ましい閾値を ROC・PR 曲線から決定。

ステップ 8: モデル比較

RandomForest・XGBoost・LightGBM の Log Loss と並べる。 GradientBoosting が通常最良。

ステップ 9: クロス検証

cross_val_score(scoring='neg_log_loss', cv=5) で過学習チェック。

ステップ 10: 本番デプロイ

学習済モデルを joblib で保存。 推論側で確率予測と Log Loss モニタリング。

📋 Log Loss チートシート

実務で頻用するコード・概念・公式を 1 ページにまとめた早見表。 印刷して机に貼っておくと便利です。

領域項目説明
基本公式-y*log(p)-(1-y)*log(1-p)二値 Log Loss の各サンプル寄与
sklearnfrom sklearn.metrics import log_loss標準実装。 自動クリップ
PyTorch (二値)nn.BCEWithLogitsLoss()Sigmoid + Log Loss 内蔵で数値安定
PyTorch (多値)nn.CrossEntropyLoss()Softmax + Log Loss 内蔵
TensorFlowtf.keras.losses.BinaryCrossentropy()二値 Log Loss Keras 版
確率クリップnp.clip(p, 1e-15, 1-1e-15)log(0) 回避
ベースライン-p*log(p)-(1-p)*log(1-p)全予測=陽性率 (=Bernoulli エントロピー)
校正評価from sklearn.calibration import calibration_curve校正度プロット
Brier 比較from sklearn.metrics import brier_score_loss二乗誤差版確率指標
Focal Loss-(1-p)^γ * log(p)不均衡データ対応
MLE 等価Log Loss = -1/N * 対数尤度ベルヌーイ分布の MLE と同義
勾配∂LogLoss/∂z = p - yシグモイドと合わせると綺麗
AUC との関係両方計算するAUC: ランキング、 LL: 確率校正
ランダム基準log(2) ≈ 0.693p=0.5 一定予測の値
不均衡対応class_weight='balanced'陰陽サンプル数で重み調整

🐍 SSDSE-B-2026 × Log Loss 追加コード集 (4 要素ナレーション)

本編のコードに加え、 さらに 4 種の発展的コード例を 4 要素 (🎯/📥/📤/💬) 付きで提示。 段階的に「読む→動かす→改造する」を体験できます。

追加コード 1:Log Loss と Accuracy の同時グリッドサーチ

🎯 このコードでやること:特徴量を標準化したうえでロジスティック回帰の正則化強度 C を 0.001〜1000 の 7 段階で振り、 Log Loss と Accuracy がどう動くかを並べて見る。

📥 入力データ:SSDSE-B-2026 の 2023 年度・47 都道府県。

X = 総人口・出生数(47 行 × 2 列)、 y = 高齢化率 30% 超なら 1(35 県が 1) コード内で読み込む(追加コード 2〜4 はここで作った X, y をそのまま使う)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import log_loss, accuracy_score

# コード 1 と同じ「高齢化率 > 30%」データ(2023 年度・47 都道府県、総人口と出生数)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
d  = df[df['年度']==2023].copy()
y  = (d['65歳以上人口'] / d['総人口'] > 0.30).astype(int).values
X  = d[['総人口', '出生数']].values

# 総人口(〜10^7)のまま入れると係数が小さくなりすぎて C がほぼ効かないので、標準化してから C を振る
Cs = np.logspace(-3, 3, 7)
for C in Cs:
    m = make_pipeline(StandardScaler(), LogisticRegression(C=C, max_iter=1000)).fit(X, y)
    p = m.predict_proba(X)[:, 1]
    print(f"C={C:8.3f}  LogLoss={log_loss(y,p):.4f}  Acc={accuracy_score(y,m.predict(X)):.4f}")

📤 実行結果:

C= 0.001 LogLoss=0.5594 Acc=0.7447 C= 0.010 LogLoss=0.4991 Acc=0.7447 C= 0.100 LogLoss=0.3564 Acc=0.8723 C= 1.000 LogLoss=0.2854 Acc=0.8936 C= 10.000 LogLoss=0.2565 Acc=0.8936 C= 100.000 LogLoss=0.2113 Acc=0.9362 C=1000.000 LogLoss=0.1997 Acc=0.9149

💬 結果の読み方:C=0.001 では LogLoss 0.5594・Accuracy 0.7447 で、 全県に陽性率 35/47 を当てるだけの予測(基準 0.568)とほとんど変わらない。 正則化を弱めるほど学習データへの当てはまりは良くなり、 C=0.1 で 0.3564、 C=1 で 0.2854、 C=1000 で 0.1997 と、 標準化せずに当てはめたコード 1 の 0.1992 にほぼ追いつく。 Accuracy の最高は C=100 の 0.9362 で、 C=1000 では 0.9149 に下がるので、 LogLoss と Accuracy の最良点は一致しない。 どちらも学習に使った 47 県での値なので、 C を選ぶときは交差検証で測る。 総人口(約 10⁷)を標準化せずに入れると係数がごく小さくなり、 C を 0.001〜1000 のどこに振っても LogLoss が同じ値のまま動かなくなる。

追加コード 2:Brier Score・Log Loss・AUC の 3 軸評価

🎯 このコードでやること:同じモデルを 3 つの確率評価指標で測り、 違いを観察。

📥 入力データ:追加コード 1 で作った X, y。

X = 総人口・出生数(47 行 × 2 列)、 y = 高齢化率 30% 超なら 1(35 県が 1)
1
2
3
4
5
6
from sklearn.metrics import log_loss, brier_score_loss, roc_auc_score
m = LogisticRegression(max_iter=1000).fit(X, y)
p = m.predict_proba(X)[:, 1]
print(f"Log Loss : {log_loss(y, p):.4f}")
print(f"Brier    : {brier_score_loss(y, p):.4f}")
print(f"AUC      : {roc_auc_score(y, p):.4f}")

📤 実行結果:

Log Loss : 0.1992 Brier : 0.0613 AUC : 0.9643

💬 結果の読み方:AUC 0.9643 は「高齢化率 30% 超の県と以下の県を 1 つずつ選ぶと、 96% の組で超の県に高い確率が付く」という意味で、 並べ替えの能力は高い。 Brier 0.0613 は予測確率と 0/1 の差の二乗平均で、 陽性率 0.745 を一律に出す基準(0.745 × 0.255 ≒ 0.190)の約 3 分の 1。 Log Loss 0.1992 も基準 0.568 の約 35% で、 3 指標とも同じ向きを示しているが、 どれも学習に使った 47 県で測った値である。

追加コード 3:Calibrated Classifier で Log Loss を改善

🎯 このコードでやること:CalibratedClassifierCV で出力確率を再校正し、 Log Loss が下がるか確認。

📥 入力データ:追加コード 1 で作った X, y。

X = 総人口・出生数(47 行 × 2 列)、 y = 高齢化率 30% 超なら 1(35 県が 1)
1
2
3
4
5
6
from sklearn.calibration import CalibratedClassifierCV
base = LogisticRegression(max_iter=1000)
cc = CalibratedClassifierCV(base, method='isotonic', cv=5).fit(X, y)
p_cal = cc.predict_proba(X)[:, 1]
print(f"校正前 Log Loss : {log_loss(y, p):.4f}")
print(f"校正後 Log Loss : {log_loss(y, p_cal):.4f}")

📤 実行結果:

校正前 Log Loss : 0.1992 校正後 Log Loss : 0.1568

💬 結果の読み方:isotonic 回帰で校正すると Log Loss は 0.1992 → 0.1568 と約 21% 下がった。 ただし校正器を作った 47 県と評価した 47 県が同じなので、 この改善幅は楽観的に出ている。 isotonic は階段関数で確率を付け直すため、 47 件程度では階段が粗く、 本当に効くかは交差検証の外側で測った Log Loss で確かめる。

追加コード 4:Focal Loss で不均衡対応

🎯 このコードでやること:Log Loss と Focal Loss を SSDSE-B-2026 で比較。 不均衡なほど Focal が効く。

📥 入力データ:追加コード 1 で作った X, y。

X = 総人口・出生数(47 行 × 2 列)、 y = 高齢化率 30% 超なら 1(35 県が 1)
1
2
3
4
5
6
7
8
9
import numpy as np
def focal_loss(y, p, gamma=2.0):
    p = np.clip(p, 1e-15, 1-1e-15)
    return -np.mean((1-p)**gamma * y*np.log(p) + p**gamma * (1-y)*np.log(1-p))

print(f"Log Loss        : {log_loss(y, p):.4f}")
print(f"Focal (g=1)     : {focal_loss(y, p, gamma=1):.4f}")
print(f"Focal (g=2)     : {focal_loss(y, p, gamma=2):.4f}")
print(f"Focal (g=5)     : {focal_loss(y, p, gamma=5):.4f}")

📤 実行結果:

Log Loss : 0.1992 Focal (g=1) : 0.1286 Focal (g=2) : 0.1032 Focal (g=5) : 0.0638

💬 結果の読み方:同じ予測確率 p に対して、 Log Loss 0.1992 に比べ Focal は γ=1 で 0.1286、 γ=2 で 0.1032、 γ=5 で 0.0638 と γ を上げるほど小さくなる。 これは (1−p)^γ の重みで「すでに当たっている県」の損失を削っているからで、 モデルが良くなったわけではない。 γ の違う値どうしや Log Loss と大小を比べても意味はなく、 Focal Loss は学習時の損失として使うもの。 陽性率 74.5% のこのデータは極端な不均衡ではないので、 評価は Log Loss のままでよい。

⚠️ よくある落とし穴

Log Loss を実務で扱うとき、 多くの分析者が同じところでつまずきます。 代表的な失敗パターンを先回りで押さえておくと、 後工程のトラブルを大幅に減らせます。

❌ 確率 0 or 1 の罠
完全な確信は無限大ペナルティ。 sklearn は内部で $\epsilon$ クリップ。
❌ Accuracy と混同
LogLoss が悪くても Accuracy が良いことはある(確信度のみ間違い)。 用途で使い分け。
❌ 不均衡データ
陽性率 1% で全て p=0.01 と予測 → LogLoss は小さいが診断として無用。 PR-AUC と併用を。
❌ Calibration の確認
LogLoss が良くても、 「80% 予測時に実際 80% で陽性」を意味しない場合あり。 calibration plot を。
❌ 対数の底
scikit-learn は log_e。 教科書は log_2 もあり(bit 単位)。 比較時は注意。

※ 上記は文献調査・現場経験で報告される頻度の高い注意点。 ドメインや手法のバージョンによって追加の落とし穴がある場合があります。

⚠️ さらに踏み込んだ失敗パターン 10 連

初学者を超えた中級者がハマる「2 周目の失敗例」を集めました。 本編の 5 件と合わせて 15 件のチェックリストとして活用してください。

⚠️ 学習率を下げすぎて収束しない
ロジスティック回帰の sklearn では問題ないが、 自作 NN で η=10^-6 だと Log Loss が下がらない。 10^-3〜10^-4 から開始。
⚠️ 特徴量の単位混在
総人口 (1e7) と出生率 (1.0) を生のまま入れると重み学習が困難。 StandardScaler 必須。
⚠️ ラベルリーク
未来情報が特徴量に混入。 例えば「翌年の出生数」を含めて翌年の高齢化を予測 → Log Loss が異常に良くなる。 時系列 split で対策。
⚠️ EarlyStopping を Validation Loss で行わない
Train Log Loss で停止すると過学習。 必ず別 validation set で監視。
⚠️ Sigmoid を 2 回適用
PyTorch で BCEWithLogitsLoss を使うときは logit 直接渡し。 Sigmoid をモデル出力にも掛けると二重適用。
⚠️ Class weight と Focal Loss を同時適用
対応する不均衡対策の組み合わせは Log Loss を歪める。 一方ずつ試して評価。
⚠️ バッチサイズ大きすぎ
小データ (47 行) で batch=128 → 1 イテで 1 epoch 終了、 学習が進まない。 batch を 8-16 に。
⚠️ LR scheduler 忘れ
深層モデルで cosine annealing なし → Log Loss が plateau に。 学習率半減や warm restart 検討。
⚠️ Validation Set が小さすぎ
47 県だと train/test 比 0.8/0.2 で test=9 件、 ノイズ支配。 LOOCV か StratifiedKFold(5) 推奨。
⚠️ 評価指標を 1 つだけ見る
Log Loss が良くても Accuracy・AUC・PR-AUC すべて見る癖を。 LL だけだと校正だけ良いモデルを誤選択。

📖 Log Loss 関連語拡張辞典(20 語)

本編の 10 語に加え、 さらに専門用語 20 個を整理。 文献を読むときの「分からない単語チェッカー」として使えます。

Logistic Regression
ロジスティック回帰。 Log Loss 最小化で確率予測。
Binary Classification
二値分類。 Log Loss が標準損失。
Multi-class Classification
多クラス分類。 Cross-Entropy が標準損失。
Sigmoid Function
σ(z) = 1/(1+e^-z)。 二値確率出力。
Softmax Function
exp(z_i)/Σexp(z_j)。 多クラス確率出力。
Logit
log(p/(1-p))。 確率の log odds 変換。
Maximum Likelihood Estimation (MLE)
尤度最大化推定。 Log Loss 最小化と等価。
Bernoulli Distribution
ベルヌーイ分布。 二値変数の確率モデル。
Categorical Distribution
カテゴリカル分布。 多クラス版ベルヌーイ。
Reliability Diagram
校正度プロット。 x=予測確率、 y=実際の陽性率。
Platt Scaling
SVM 出力を確率に校正する手法。
Isotonic Regression
単調回帰。 任意確率を校正。
ECE (Expected Calibration Error)
校正誤差の期待値。 校正度の数値指標。
Cross-Validation
交差検証。 Log Loss を頑健に推定。
Stratified KFold
層別 K 分割。 クラス比保持で偏り防止。
AUROC
ROC 曲線下面積。 ランキング能力。
AUPRC
PR 曲線下面積。 不均衡データで重要。
Confusion Matrix
混同行列。 TP/FP/TN/FN の集計。
Log Likelihood Ratio Test
対数尤度比検定。 モデル比較。
Information Gain
情報利得。 エントロピーの差。

❓ FAQ 追補 20 問(中〜上級者向け)

追補 Q1. Log Loss が学習中に振動する
学習率大、 バッチサイズ小、 不均衡などの可能性。 学習率を 1/10 にしてバッチを増やす。
追補 Q2. 過学習で Train LL << Val LL
正則化 (L1/L2) を強化、 ドロップアウト追加、 学習データ拡張。
追補 Q3. LL が下がっても Accuracy が上がらない
確率の校正は良いが閾値判定が悪い。 閾値を調整、 PR 曲線から最適点を探る。
追補 Q4. クラスター級の極端な不均衡 (1:1000)
Focal Loss、 Class Balanced Loss、 Sampling (SMOTE)。 通常の Log Loss だけでは少数クラスを無視。
追補 Q5. Label Smoothing は Log Loss にどう効く
$\hat{p}=1$ を $\hat{p}=0.9$ にする → 自信過剰防止 → Log Loss 改善&汎化向上。
追補 Q6. Multi-label 分類の Log Loss
各ラベル独立に Sigmoid + Binary Cross-Entropy。 ラベル間相関は別途学習。
追補 Q7. 時系列予測の Log Loss
Time-series CV (split by time) で過去→未来分割。 リーク防止が肝要。
追補 Q8. 不確実性推定
ベイジアン NN や Monte Carlo Dropout で予測の標準偏差を出す。 Log Loss と相補的。
追補 Q9. LL と KL Divergence の関係
Cross-Entropy = Entropy + KL。 LL を最小化 = KL 最小化 (真分布固定の下)。
追補 Q10. 勾配爆発
Log Loss の勾配 = p - y で大きくならないが、 logit 経由で巨大に。 gradient clipping を。
追補 Q11. Boost vs NN で LL 比較
47 件のような小データなら Boost (LightGBM 等) が NN を上回る。 LL 0.4 vs 0.5 程度の差。
追補 Q12. Bagging で LL 改善
Random Forest を 100 → 500 木で LL が低下することが多い。
追補 Q13. Stacking で LL を最小化
ベース層の予測確率を入力に、 メタ層が校正役。 LL 最小化に効く。
追補 Q14. Quantile Loss と LL の違い
Quantile: 回帰の中央値・分位、 LL: 分類の確率。 タスクが違う。
追補 Q15. Entropy Regularization
予測分布のエントロピーを損失に加算。 過信防止、 探索促進 (RL)。
追補 Q16. Negative Sampling
Word2Vec 等で LL の分母 (全クラス) を近似計算する技法。
追補 Q17. Logit Adjustment
クラス不均衡時に logit を事前確率でシフト。 学習なしで LL 改善。
追補 Q18. Knowledge Distillation
Teacher の softmax 分布を Student の Cross-Entropy ターゲットに。 LL 経由で知識転移。
追補 Q19. Mixup と LL
サンプルとラベルを線形補間 → 補間 LL で学習。 汎化向上。
追補 Q20. LL を本番でモニタリング
推論ログから真値ラベルが取れる業務は LL を継続計測。 drift 検知の指標に。

🌟 SSDSE-B-2026 で「Log Loss」の総合演習

47 都道府県 × 12 年分のデータを使い、 Log Loss を多角的に体験する総合演習。 単発の操作ではなく、 一連の分析フローを通して理解を深めます。

ハンズオン 1: 全 12 年分の Log Loss を計算

🎯 このコードでやること:全 12 年分の Log Loss を計算

📥 入力:SSDSE-B-2026.csv の 47 都道府県データ。

前述同様のデータフレーム
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import log_loss

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

for yr in sorted(df['年度'].unique()):
    d = df[df['年度']==yr].copy()
    d['ラベル'] = (d['65歳以上人口']/d['総人口'] > 0.30).astype(int)
    if d['ラベル'].nunique() < 2:
        continue
    X = d[['総人口', '出生数']].values
    y = d['ラベル'].values
    m = LogisticRegression(max_iter=1000).fit(X, y)
    p = m.predict_proba(X)[:, 1]
    print(f"{yr}: 陽性率={y.mean():.2f}  LogLoss={log_loss(y, p):.4f}")

📤 実行結果:

2012: 陽性率=0.04 LogLoss=0.0000 2013: 陽性率=0.09 LogLoss=0.1774 2014: 陽性率=0.13 LogLoss=0.2016 2015: 陽性率=0.23 LogLoss=0.2870 2016: 陽性率=0.40 LogLoss=0.4023 2017: 陽性率=0.49 LogLoss=0.4511 2018: 陽性率=0.53 LogLoss=0.3760 2019: 陽性率=0.60 LogLoss=0.3667 2020: 陽性率=0.57 LogLoss=0.3466 2021: 陽性率=0.70 LogLoss=0.2536 2022: 陽性率=0.70 LogLoss=0.2543 2023: 陽性率=0.74 LogLoss=0.1992

💬 結果の読み方:高齢化率 30% 超の県は 2012 年の 2 県(秋田県・高知県、 陽性率 0.04)から 2023 年の 35 県(0.74)へ増えたが、 2020 年は 27 県(0.57)と前年の 28 県から 1 つ減る(岡山県が 30.2% → 29.6%)。 2012 年の LogLoss 0.0000 は、 陽性 2 県が総人口と出生数だけで完全に切り分けられて確率がほぼ 0/1 に張り付いたためで、 良いモデルという意味ではない。 LogLoss が最大なのは陽性率 0.49 の 2017 年(0.4511)で、 陽性と陰性が半々に近い年ほど境界付近の県が増えて損失が大きくなる。

🧪 実データで確かめる:47 県の Log Loss は「数県の自信過剰な外れ」で決まる

Log Loss は全サンプルの平均ですが、中身は均等ではありません。2023 年度の 47 県について、出生率(人口千人当たり)・社会増減率(転入 − 転出、千人当たり)・人口の対数から「高齢化率 30% 超」を予測するロジスティック回帰を作り、1 県ずつ抜いて予測する(LOO)ことで、各県の予測確率と損失を並べます。

🎯 このコードでやること:2023 年度 47 県で「高齢化率 30% 超」を予測するロジスティック回帰を、学習データそのものと LOO の 2 通りで評価し、LOO での県ごとの損失 −log p の上位 5 県と、上位 3 県が全体に占める割合を出す。

📥 入力データ:SSDSE-B-2026 の 2023 年度 47 行(列: A1101 総人口, A1303 65 歳以上人口, A4101 出生数, A5101 転入者数, A5102 転出者数)。

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
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import LeaveOneOut, cross_val_predict
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import log_loss, accuracy_score

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)
y = (d['A1303'] / d['A1101'] > 0.30).astype(int)                 # 高齢化率 30% 超 = 1
X = pd.DataFrame({'出生率': d['A4101'] / d['A1101'] * 1000,      # 人口千人当たり
                  '社会増減率': (d['A5101'] - d['A5102']) / d['A1101'] * 1000,
                  '対数人口': np.log10(d['A1101'])})
model = make_pipeline(StandardScaler(), LogisticRegression(C=1.0))

p_in = model.fit(X, y).predict_proba(X)[:, 1]                     # 学習に使った県をそのまま予測
p_loo = cross_val_predict(model, X, y, cv=LeaveOneOut(), method='predict_proba')[:, 1]
print(f'陽性 {y.sum()} 県 / 47 県')
print(f'学習データで評価: Log Loss {log_loss(y, p_in):.3f}  Accuracy {accuracy_score(y, p_in > 0.5):.3f}')
print(f'1 県抜き (LOO)  : Log Loss {log_loss(y, p_loo):.3f}  Accuracy {accuracy_score(y, p_loo > 0.5):.3f}')

loss = -(y * np.log(p_loo) + (1 - y) * np.log(1 - p_loo))       # 県ごとの寄与
top = pd.DataFrame({'県': d['Prefecture'], 'y': y, 'p(y=1)': p_loo.round(3), '損失': loss.round(3)})
top = top.sort_values('損失', ascending=False).head(5)
print(top.to_string(index=False))
print(f'上位 3 県の損失が合計に占める割合 {loss.sort_values(ascending=False).head(3).sum() / loss.sum():.1%}')

📤 実行結果:

陽性 35 県 / 47 県 学習データで評価: Log Loss 0.174 Accuracy 0.936 1 県抜き (LOO) : Log Loss 0.206 Accuracy 0.936 県 y p(y=1) 損失 京都府 0 0.868 2.028 宮城県 0 0.804 1.630 滋賀県 0 0.690 1.171 兵庫県 0 0.474 0.643 熊本県 1 0.526 0.642 上位 3 県の損失が合計に占める割合 50.0%

💬 結果の読み方:正解率は学習データでも LOO でも 0.936(47 県中 3 県を外す)で同じですが、Log Loss は 0.174 → 0.206 と LOO で大きくなり、学習データでの評価が楽観的なことが Log Loss には表れます。LOO での損失の上位 3 県(京都府 2.028・宮城県 1.630・滋賀県 1.171)は、いずれも高齢化率 30% 以下なのに 0.69〜0.87 の確率で「30% 超」と予測された県で、この 3 県だけで 47 県の損失合計の 50.0% を占めます。正解率では 3 県の誤りはどれも「1 件」ですが、Log Loss では外し方の自信の強さに比例して重く数えられます。

🧪 実データで確かめる:1 県の確率を 0.9999 にするだけで平均がどれだけ動くか

上の京都府(実際は 30% 以下、予測確率 0.868)の予測だけを、さらに自信過剰な値に書き換えて、47 県の Log Loss がどう変わるかを見ます。逆に、全県の確率を 0.05〜0.95 の範囲に丸めて自信過剰を抑えると改善するかも確かめます。

🎯 このコードでやること:上の LOO 予測のうち京都府の p(y=1) だけを 0.868・0.99・0.9999・0.999999 に変えて 47 県の Log Loss を計算し、さらに全県の確率を [0.05, 0.95] に丸めた場合と比べる。

📥 入力データ:上のコードと同じ 2023 年度 47 県の LOO 予測確率。Log Loss はクリップなしで自分で計算する。

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 numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import LeaveOneOut, cross_val_predict
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)
y = (d['A1303'] / d['A1101'] > 0.30).astype(int).to_numpy()
X = pd.DataFrame({'出生率': d['A4101'] / d['A1101'] * 1000,
                  '社会増減率': (d['A5101'] - d['A5102']) / d['A1101'] * 1000,
                  '対数人口': np.log10(d['A1101'])})
model = make_pipeline(StandardScaler(), LogisticRegression(C=1.0))
p = cross_val_predict(model, X, y, cv=LeaveOneOut(), method='predict_proba')[:, 1]

def ll(y, p):                                    # 自分で書いた Log Loss(クリップなし)
    return -np.mean(y * np.log(p) + (1 - y) * np.log(1 - p))

kyoto = d.index[d['Prefecture'] == '京都府'][0]  # y=0 なのに p=0.868 と外した県
for q in [0.868, 0.99, 0.9999, 0.999999]:
    p2 = p.copy(); p2[kyoto] = q
    print(f'京都府の p(y=1) = {q:<8}: 京都府 1 県の損失 {-np.log(1 - q):6.2f}  47 県の Log Loss {ll(y, p2):.3f}')
p3 = np.clip(p, 0.05, 0.95)                       # 確率を 0.05〜0.95 に丸めて自信過剰を抑える
print(f'全県の確率を [0.05, 0.95] に丸める: Log Loss {ll(y, p):.3f} → {ll(y, p3):.3f}')

📤 実行結果:

京都府の p(y=1) = 0.868 : 京都府 1 県の損失 2.02 47 県の Log Loss 0.205 京都府の p(y=1) = 0.99 : 京都府 1 県の損失 4.61 47 県の Log Loss 0.260 京都府の p(y=1) = 0.9999 : 京都府 1 県の損失 9.21 47 県の Log Loss 0.358 京都府の p(y=1) = 0.999999: 京都府 1 県の損失 13.82 47 県の Log Loss 0.456 全県の確率を [0.05, 0.95] に丸める: Log Loss 0.206 → 0.220

💬 結果の読み方:京都府 1 県の確率を 0.868 → 0.9999 にするだけで、その県の損失は 2.02 → 9.21 になり、47 県の平均は 0.205 → 0.358 と 7 割以上悪化します。0.999999 では 0.456 と、ほかの 46 県の予測が同じでも平均が 2 倍以上になります。一方、全県の確率を [0.05, 0.95] に丸めると 0.206 → 0.220 とかえって悪くなりました。丸めの対象になるのは確率が 0.95 超か 0.05 未満の 24 県で、どれも正しく当てている県です。外れた 3 県の確率(0.69〜0.87)はもともと範囲内なので丸めても損失は減らず、当たっている 24 県の損失だけが増えたのです。自信過剰への対処は一律の丸めではなく、正則化や確率の再校正(キャリブレーション)で行います。

✅ 理解度チェック(上の実測値で答える)

Q1. 正解率が 0.936 で同じなのに、学習データでの Log Loss 0.174 と LOO の 0.206 が違うのはなぜか。
→ 解答:学習に使った県を予測すると、その県に合わせた係数で確率がより正解側に寄るため、損失が小さく出る。正解・不正解の境界(0.5)をまたがない確率の変化は正解率には表れないが、Log Loss には表れる。

Q2. 京都府の損失 2.028 は、予測確率 0.868 からどう計算されるか。
→ 解答:京都府は y=0 なので損失は −log(1 − 0.868) = −log(0.132) ≈ 2.02(表示の 2.028 は丸める前の確率 0.8684 による)。

Q3. 外れた 3 県の確率を下げたいとき、全県の確率を [0.05, 0.95] に丸めるのが逆効果だったのはなぜか。
→ 解答:外れた 3 県の確率は 0.69〜0.87 でもともと [0.05, 0.95] の範囲内なので、丸めても損失は変わらない。変わるのは 0.95 超・0.05 未満の確率を出していた 24 県(すべて正解)で、それぞれ損失が −log(0.95) ≈ 0.051 まで増える。全県の確率を一律に動かす操作は、当たっている県の損失を増やすだけになりうる。

🗺 概念マップ

Log Loss を中心に、 Cross-Entropy (同義)、 Brier Score・Focal Loss (派生指標)、 Calibration・KL ダイバージェンス (関連評価) を並べた分類損失マップ。

log loss Brier Score Cross-Entropy Focal Loss Calibration Negative Log L KL ダイバージェンス

対数損失 (Log Loss / Cross Entropy) は確率予測の質を測る損失関数で、 二値分類では Negative Log Likelihood (NLL) と等価。 概念マップではクロスエントロピー・尤度・KL ダイバージェンス・Brier スコアが並列ノード、 落とし穴は「予測確率 0 / 1 の極端値で発散する」「クラス不均衡で支配される」「キャリブレーション (Platt scaling / isotonic) を併用しないと過信モデルになる」など。

🔗 隣接手法への橋渡し

Log Loss は確率予測の評価指標であり、 前段の確率出力モデル (logistic / softmax) と後段のキャリブレーション診断を組み合わせて信頼性の高い確率推定を実現する。

上流のクラス不均衡対策 (重み付け・SMOTE) が log-loss の感度を整え、 並列の AUC/Brier Score と比較して評価指標の使い分けを判断し、 下流のキャリブレーション (Platt Scaling/Isotonic) で確率予測の信頼性を高める流れで「確率予測モデルの品質保証」が成立する。

🌳 手法選択フロー

Log Loss を実際の課題に当てはめるとき、 用語固有の判断軸に沿って次の 3 段階で適切な選択を行う。

  1. 確率予測の品質を重視するか? Yes → Log Loss 一択、 No → 次へ
  2. クラス不均衡が極端か (1:100 以上)? Yes → AUC / PR-AUC 補完、 No → Log Loss + Accuracy で十分
  3. ランキングタスク (上位 K 件) か? Yes → NDCG / MAP、 No → Log Loss を主評価指標に固定

このフローは確率予測モデルの評価指標選択軸。 Log Loss は確率予測の「鋭さと正しさ」両方を測る指標で、 キャリブレーション (Platt/Isotonic) と組み合わせて初めて実務品質に到達する。

❌ 確率 0 or 1 の罠
完全な確信は無限大ペナルティ。 sklearn は内部で $\epsilon$ クリップ。
❌ Accuracy と混同
LogLoss が悪くても Accuracy が良いことはある(確信度のみ間違い)。 用途で使い分け。
❌ 不均衡データ
陽性率 1% で全て p=0.01 と予測 → LogLoss は小さいが診断として無用。 PR-AUC と併用を。
❌ Calibration の確認
LogLoss が良くても、 「80% 予測時に実際 80% で陽性」を意味しない場合あり。 calibration plot を。
❌ 対数の底
scikit-learn は log_e。 教科書は log_2 もあり(bit 単位)。 比較時は注意。
💥 確率 0 や 1 を出さない
log(0) = -∞ で Log Loss が爆発する。 sklearn は内部で $\epsilon=10^{-15}$ にクリップするが、 自前実装では明示的に `np.clip(p, 1e-15, 1-1e-15)` を入れる。
💥 クラス不均衡で見かけ良好
陽性率 1% のとき全部 $\hat{p}=0.01$ と予測すれば Log Loss は小さい。 PR-AUC や Recall も併用すべき。
💥 Accuracy と混同しない
Log Loss は確率の質、 Accuracy は閾値後の 0/1 判定。 LogLoss 悪化=確信度の校正不足のサインで、 Accuracy 低下とは別問題。
💥 対数の底に注意
scikit-learn は自然対数 (log_e)、 教科書によっては log_2 (情報量を bit で測る)。 比較時は底を統一すること。
💥 calibration を別途確認
Log Loss が良くても「予測 80% のサンプル群で実際に 80% が陽性」とは限らない。 reliability diagram で校正状況を可視化。
⚠️ 学習率を下げすぎて収束しない
ロジスティック回帰の sklearn では問題ないが、 自作 NN で η=10^-6 だと Log Loss が下がらない。 10^-3〜10^-4 から開始。
⚠️ 特徴量の単位混在
総人口 (1e7) と出生率 (1.0) を生のまま入れると重み学習が困難。 StandardScaler 必須。
⚠️ ラベルリーク
未来情報が特徴量に混入。 例えば「翌年の出生数」を含めて翌年の高齢化を予測 → Log Loss が異常に良くなる。 時系列 split で対策。
⚠️ EarlyStopping を Validation Loss で行わない
Train Log Loss で停止すると過学習。 必ず別 validation set で監視。
⚠️ Sigmoid を 2 回適用
PyTorch で BCEWithLogitsLoss を使うときは logit 直接渡し。 Sigmoid をモデル出力にも掛けると二重適用。
⚠️ Class weight と Focal Loss を同時適用
対応する不均衡対策の組み合わせは Log Loss を歪める。 一方ずつ試して評価。
⚠️ バッチサイズ大きすぎ
小データ (47 行) で batch=128 → 1 イテで 1 epoch 終了、 学習が進まない。 batch を 8-16 に。
⚠️ LR scheduler 忘れ
深層モデルで cosine annealing なし → Log Loss が plateau に。 学習率半減や warm restart 検討。
⚠️ Validation Set が小さすぎ
47 県だと train/test 比 0.8/0.2 で test=9 件、 ノイズ支配。 LOOCV か StratifiedKFold(5) 推奨。
⚠️ 評価指標を 1 つだけ見る
Log Loss が良くても Accuracy・AUC・PR-AUC すべて見る癖を。 LL だけだと校正だけ良いモデルを誤選択。

📜 ひとことヒストリー

Log Loss は「評価指標」分野の中で発展してきた概念・手法です。 学術的には継続的な研究で精緻化され、 実務的にはツール・ライブラリの普及で誰でも使えるようになってきました。 用語の使い方・意味は時代と分野で少しずつ変わるため、 文脈に応じた解釈が大切です。 入門書だけでなく、 標準的な教科書(例:データサイエンス・統計学の定本)や信頼できるオンライン教材も併用すると、 ぶれない理解に近づけます。

✅ 実務チェックリスト — Log Loss

  • □ 用語の定義を自分の言葉で説明できるか
  • □ 使うべき場面と使ってはいけない場面を区別できているか
  • □ 数式や指標の前提条件を確認したか
  • □ 入力データの尺度・分布・サンプル数を確認したか
  • □ 結果の不確実性(信頼区間・標準誤差)を把握しているか
  • □ 解釈と限界を区別できているか
  • □ 関連用語・落とし穴を一通り点検したか
  • □ レポートに必要な情報(出典・前提・限界)を含められるか

🎯 まとめ — このページで押さえること

「Log Loss」 はこのページで詳しく扱った概念です。 持ち帰ってほしい 3 つの要点:

  1. Log Loss(対数損失、 クロスエントロピー)=確率予測の精度を測る指標。 確率を当てたモデルほど小さい値。
  2. 公式:$\text{LogLoss} = -\frac{1}{N} \sum_i [y_i \log \hat{p}_i + (1-y_i) \log(1-\hat{p}_i)]$(二値)。
  3. 確信を持って外すと巨大なペナルティ($\log 0 = -\infty$)。 慎重な確率予測を促す。

さらに学ぶには、 関連用語 や 関連グループ教材 を参照してください。 各用語ページを縦断的に読むことで、 体系的な理解が育ちます。

🔎 解説を深める — 「基準線」から Log Loss を読む

Log Loss は単独の値だけ見ても「良いのか悪いのか」が判断できません。 このセクションは、 姉妹ページ(交差エントロピー・確信度の非対称罰)とは別の角度、 すなわち 「何もしない予測(ベースレート)が叩き出す基準線」との差で読む という実務的な視点で深掘りします。 数値はすべて data/raw/SSDSE-B-2026.csv(2023 年・47 都道府県)の実測から算出しています。

🎨 直感 — 「無情報ベースライン」はラベル分布のエントロピー

説明変数を一切見ず、 全サンプルに同じ確率を出す予測器を考えます。 このとき Log Loss を最小にする定数は「陽性の base rate $\bar p$」で、 その値はラベル分布の 2 値エントロピー $H(\bar p)=-\bar p\log\bar p-(1-\bar p)\log(1-\bar p)$ に一致します。 これがモデルが越えるべき床(フロア)です。

実データで確認します。 SSDSE-B-2026(2023 年)の総人口 A1101 から「総人口が 300 万人超の都道府県」という 2 値ラベルを作ると、 47 件中 陽性は 10 件、 base rate $\bar p=10/47=0.2128$。 全都道府県に定数 $\bar p$ を出すだけの無情報予測の Log Loss は次の通りです(natural log、 sklearn.metrics.log_loss 相当)。

予測(全サンプル一律)Log Loss(実測)意味
$p=\bar p=0.2128$(base rate)0.5176無情報ベースライン $=H(\bar p)$。 越えるべき床
$p=0.5$0.6931$=\log 2$。 base rate を無視すると悪化
$p=0.05$0.6778「どこも大きくない」と決めつけた自信過剰
$p=0.01$0.9877さらに強く決めつけ、 $\log 2$ より悪い

つまり「Log Loss = 0.55」という数字は、 このタスクではベースライン 0.5176 をほぼ超えられていない=ほぼ無価値と読めます。 Log Loss は絶対値ではなく、 この床との差で価値を測るのが実務の作法です。

⚠️ 落とし穴(重要)— 「多数派に賭ければ低くなる」の罠

上表の $p=0.05$ の行が示す通り、 不均衡データでは「陰性側に薄く賭ける」だけで Log Loss はそれなりに低く見えます(0.6778)。 陽性が 2 割しかないので、 全部「たぶん陰性」と言えば 8 割は当たり、 損失が小さく見えてしまうのです。 これは Accuracy の「多数派に賭けると高精度」問題の Log Loss 版で、 見落とすと「ベースラインすら超えていないモデル」を良いと誤認します。

さらに危険なのが自信過剰です。 決めつけを強めて $p=0.01$ にすると、 陽性 10 件で毎回 $-\log(0.01)=4.605$ の巨大な罰を受け、 平均 Log Loss は 0.9877 と $\log 2$(無情報コイン投げ)より悪化します。 「確率を極端に振るほど当たれば得だが外すと破滅」という非対称性が、 実データでもそのまま効いています。 対策:(1) 必ず base rate ベースライン $H(\bar p)$ を計算して基準にする、 (2) 予測を $[\varepsilon,\,1-\varepsilon]$ でクリップ、 (3) 不均衡なら sample_weight や層化評価を併用する。

🚀 発展 — 「基準線超え」を情報量ゲインとして測る

ベースライン $H(\bar p)$ とモデルの Log Loss $L$ の差 $H(\bar p)-L$ は、 説明変数がラベルについて説明できた情報量(nat 単位)とみなせます。 これを $H(\bar p)$ で割った $\;1-L/H(\bar p)\;$ は「対数損失版の $R^2$」(McFadden 型の擬似決定係数と同族)で、 0 なら無情報、 1 なら完全予測です。 今回のタスクなら床は $H(\bar p)=0.5176$ なので、 例えば $L=0.30$ を出せたモデルは擬似 $R^2 = 1-0.30/0.5176 \approx 0.42$ と読めます。

この「エントロピー=越えるべき損失の下限」という見方は、 情報理論の クロスエントロピー $\ge$ エントロピー(等号はモデル分布=真の分布のとき)という不等式そのものです。 Log Loss の最小化は、 予測分布を真のラベル分布へ近づけて KL ダイバージェンス $D_{\mathrm{KL}}(\text{真}\,\|\,\text{予測})$ をゼロへ押し下げる操作にほかなりません。 合成デモ(架空):仮に真の陽性確率が本当に 0.2128 の集団で、 校正されたモデルは Log Loss $\to 0.5176$ に収束し、 それ以上は原理的に下げられません(=これがベイズ誤差に対応する床)。

この「床=エントロピー」の視点は次のページと接続します。

(Brier Score・確率校正(calibration)の単独ページは現時点で未作成のためリンクなし。 本ページ上部の「触って理解する」節も参照。)