「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 との「使い分け感」を視覚化する。
正解 y=1 に対して p (=モデル予測確率) を下げるほど損失が急増、 p→0 で発散。 「90% 自信あり」と言って外したら大ペナルティ、 「51% 自信あり」で外したらまだ許される、 という性質を表す。
p=0.2 で外すと loss=1.61、 p=0.9 で外すと loss=2.30 (大きい)。 確信度のキャリブレーションが評価対象に含まれる。
2 つのモデル A・B が同じ Accuracy=80% を出していても、 確信度の出し方が違えば Log Loss は別の値になる。 「ぎりぎり当てた」モデルより「自信を持って当てた」モデルが好まれる。
Log Loss はリスク評価・確率予測 (例: 与信スコア・医療診断確率) において、 単なる正解率では見えない「信頼性」を測る役割を持つ。
陽性クラスがレアな場合 (例: 不正検知 1%)、 sample weight や class weight を Log Loss に組み込むことで、 多数派クラスに引きずられた予測を抑える。
scikit-learn の log_loss(y_true, y_pred, sample_weight=...) や XGBoost の scale_pos_weight がこの考え方を実装している。
Log Loss の核を本当に掴めたかを 6 問で確認する。 すべて 1 分以内で答えられる粒度。 「自分で」答えを口に出して言える状態を目指したい。
−Σᵢ Σ_c y_ic log p_ic。 各サンプルで正解クラスの予測確率に −log を当てて全部足す。 2 クラスの式の自然な拡張。
sample_weight や scale_pos_weight で少数派の重みを上げるのが定石。
これらの問題に詰まった項目があれば、 「−log(p) の発散」「重み付け」のセクションへ戻ろう。 確率予測の評価指標は「正解か否か」ではなく「どれだけ自信を持っているか」を評価する点が肝心。
正解ラベル $y$(0/1)を切り替え、 予測確率 $p$ をスライダーで動かすと、 対数損失 $-[y\log p + (1-y)\log(1-p)]$(自然対数)がリアルタイムに計算され、 損失曲線上に現在点が表示されます。 正解に自信を持てば損失は小さく、 外れた方向に自信を持つほど損失が急増($p\to0$ で $\infty$) する非対称な罰を体感してください。
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」は 確率予測の精度を測る損失関数。確信を持って外すと巨大なペナルティ。 です。 ここでは定義式の各記号、 直感的意味、 SSDSE-B-2026 への当てはめを段階的に解きほぐします。
Log Loss は Shannon エントロピーの負数 $-\log p$ に基づく。 情報量 $-\log p$ は「確率 $p$ の出来事が起きた時の驚き度」を表す。 Log Loss はモデルが正解ラベルを見た時の「平均驚き度」を最小化する。 つまり「外したくないなら高確率を当てよ」というインセンティブ設計。
ベルヌーイ分布 $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 値 | 意味 | 例 |
|---|---|---|
| 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 で「高齢化率 > 30% を予測するロジスティック回帰の Log Loss」。 入力は 都道府県の総人口・出生数・15歳未満人口の比率、 出力は 高齢化率 (65歳以上人口/総人口) > 30% かどうかの 2 値ラベル。 47 都道府県 × 複数年の実データで具体計算を実施します。
| 業界 | 事例 | 役割 | SSDSE-B-2026 との対比 |
|---|---|---|---|
| 広告クリック予測 | Google・Meta の CTR 予測モデル | 確率の精度が収益に直結 | 出生率予測モデルの評価に応用可 |
| 医療診断 AI | X 線画像から肺癌確率を予測 | 確信度の校正が患者説明に必須 | 都道府県別罹患率推定の指標 |
| Kaggle コンペ | 確率予測タスクの標準評価指標 | 順位決定に直接使われる | SSDSE-B の指標予測コンペで利用可 |
| クレジットリスク | 個人の延滞確率予測 | 規制(バーゼル III)でも校正が要求 | 都道府県別経済指標と関連 |
| 天気予報 | 気象庁の降水確率 | Brier Score と並んで採用 | 豪雨件数の確率予測 |
| AI チャットボット | 次トークンの確率分布学習 | 言語モデルの標準損失 | テキスト生成・分類すべて |
| 手法 | 定義 | 特徴 | 用途 |
|---|---|---|---|
| Log Loss | 対数で確率を評価 | 確信ペナルティが無限大 | 確率予測 |
| Brier Score | 二乗誤差で確率を評価 | ペナルティは有界(0-1) | 確率予測 |
| Accuracy | 0/1 正解率 | 確率の質を測れない | 閾値後の判定 |
| AUC-ROC | ランキング能力 | 確率の絶対値は問わない | 陽性陰性の順位 |
| Hinge Loss | SVM 用、マージン重視 | 確率出力ではない | 分類境界 |
| Focal Loss | Log Loss の不均衡対応版 | 簡単な例にペナルティ小 | 物体検出 |
| KL Divergence | 分布間の距離 | 二分布の比較 | 知識蒸留 |
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 |
💬 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 件の重さが目立つ。
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)) |
💬 2023 年度の 47 県のうち高齢化率 30% 超は 35 県で、全県に 35/47 を一律に出すだけの基準の log loss は 0.568。総人口と出生数を使ったモデルは 0.199 まで下げたが、学習に使った 47 県をそのまま評価しているので楽観的な値である。誤分類は宮城県・滋賀県・京都府・広島県の 4 県で、東京都のように人口の大きい県には 2×10⁻¹⁰ のような極端に小さい確率が付いている。こうした自信過剰な予測が 1 件外れるだけで log loss は大きく跳ねるので、交差検証で確かめたい。
4 サンプルで LogLoss 計算:
| y | p̂ | 寄与 |
|---|---|---|
| 1 | 0.9 | −log(0.9) ≈ 0.105 |
| 0 | 0.2 | −log(0.8) ≈ 0.223 |
| 1 | 0.6 | −log(0.6) ≈ 0.511 |
| 1 | 0.1 | −log(0.1) ≈ 2.303 |
平均 = (0.105+0.223+0.511+2.303)/4 ≈ 0.785。 4 つめのサンプルが大幅にスコア悪化に寄与(自信を持って外したため)。
合成 5 サンプルでログロス (交差エントロピー) を計算する。
| i | y | ŷ | 損失 |
|---|---|---|---|
| 1 | 1 | 0.9 | 0.105 |
| 2 | 0 | 0.2 | 0.223 |
| 3 | 1 | 0.7 | 0.357 |
| 4 | 0 | 0.1 | 0.105 |
| 5 | 1 | 0.6 | 0.511 |
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}") |
💬 手計算 (Step 2) 0.260 と 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}') |
💬 −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 のパス・列名を実態に合わせてください。
🎯 このコードでやること:47 都道府県の総人口・出生数から「高齢化率 > 30%」を予測するロジスティック回帰を学習し、 Log Loss を測定。
📥 入力データ:SSDSE-B-2026 の 2023 年データを抽出、 65歳以上人口÷総人口で高齢化率を計算しラベル化。
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}") |
📤 実行結果:
💬 結果の読み方:47 都道府県のうち約 75% が高齢化率 > 30%(既に進行)。 Log Loss 0.20 は良好な水準で、 Accuracy 0.91 と併せて「確率予測の質も分類精度も高い」と判断できる。 ベースライン(全予測 0.745)の Log Loss は約 0.57 なので、 モデルが情報を大きく引き出している。
🎯 このコードでやること:同じモデルの予測について Log Loss と Brier Score を比較し、 評価指標の違いを確認する。
📥 入力データ:上記モデルの予測確率 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}") |
📤 実行結果:
💬 結果の読み方:Brier Score (二乗誤差) は有界(0-1)で穏やか、 Log Loss は外れに敏感。 0.20 vs 0.06 という違いだけでは優劣を語れないが、 「ランダム 0.693 より 0.199 = 約 71% 改善」と読むと意味がはっきりする。
🎯 このコードでやること:予測確率 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]
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.99 で外したら Log Loss は約 4.6 と巨大。 p=0.5 (ランダム) は 0.69。 「自信を持って外す」と平均が指数的に悪化することがわかる。 だからモデルは安易に 0/1 を出さず、 不確実な事例には 0.4-0.6 程度の予測を出すよう学習される。
🎯 このコードでやること:同じ「高齢化率 > 30%」予測タスクで 3 モデルの Log Loss を CV で比較する。
📥 入力データ:X = 総人口・出生数・15歳未満人口、 y = 高齢化フラグ、 47 都道府県データ
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}") |
📤 実行結果:
💬 結果の読み方:RandomForest が最良 (0.175)。 47 都道府県は小さいデータだが、 木系モデルが非線形パターンを捕捉。 ロジスティック回帰は線形仮定でやや劣り、 GBoost は小データで過学習気味 (CV では LogReg と同程度)。 production 採用なら RandomForest か LightGBM が第一候補。
class_weight='balanced' や Focal Loss を検討。 PR-AUC や Recall も併用。log_loss(y_true, y_prob, labels=[0,1,2,...])。 y_prob は (N, C) 形状で各行 sum=1。log_softmax を使うと NumPy の under/overflow を回避できる。 PyTorch では F.cross_entropy がそれを内蔵。Shannon Entropy $H = -\sum p \log p$ の負数。 「確率分布の予測の平均驚き度」を最小化。 これが「真の分布に近づくこと」と等価。
事前分布 + 尤度 → 事後分布。 Log Loss は対数尤度の負数なので、 「事後確率最大」と密接。
ベルヌーイ尤度の対数 = Log Loss。 ロジスティック回帰の重み学習 = Log Loss 最小化。
Sigmoid + BCE の勾配 = p - y、 Softmax + CE の勾配 = p - y_onehot。 数学的に綺麗で、 NN 学習の基本。
確率予測コンペでは LL がほぼ唯一の評価指標。 Stacking + Calibration で 0.001 単位を争う。
SSDSE-B-2026 を使った段階的ハンズオン。 初学者→中級→上級と順に深めるシナリオ構成です。
SSDSE-B-2026.csv を pd.read_csv(encoding='cp932', skiprows=1) で読み込み、 2023 年の 47 都道府県データを抽出する。
「高齢化率 = 65歳以上人口 / 総人口」を計算し、 30% 超なら 1 のフラグを作成。 47 県中 35 県が陽性 (約 74%)。
総人口・出生数・15歳未満人口を選択。 単位を揃えるため StandardScaler で標準化推奨。
LogisticRegression() を学習。 predict_proba() で確率を取得。
log_loss(y, p) で測定。 ベースライン (全予測 0.74) と比較して評価。
calibration_curve で reliability diagram を作成。 直線 y=x に近ければ校正済。
Accuracy・Precision・Recall が望ましい閾値を ROC・PR 曲線から決定。
RandomForest・XGBoost・LightGBM の Log Loss と並べる。 GradientBoosting が通常最良。
cross_val_score(scoring='neg_log_loss', cv=5) で過学習チェック。
学習済モデルを joblib で保存。 推論側で確率予測と Log Loss モニタリング。
実務で頻用するコード・概念・公式を 1 ページにまとめた早見表。 印刷して机に貼っておくと便利です。
| 領域 | 項目 | 説明 |
|---|---|---|
| 基本公式 | -y*log(p)-(1-y)*log(1-p) | 二値 Log Loss の各サンプル寄与 |
| sklearn | from sklearn.metrics import log_loss | 標準実装。 自動クリップ |
| PyTorch (二値) | nn.BCEWithLogitsLoss() | Sigmoid + Log Loss 内蔵で数値安定 |
| PyTorch (多値) | nn.CrossEntropyLoss() | Softmax + Log Loss 内蔵 |
| TensorFlow | tf.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.693 | p=0.5 一定予測の値 |
| 不均衡対応 | class_weight='balanced' | 陰陽サンプル数で重み調整 |
本編のコードに加え、 さらに 4 種の発展的コード例を 4 要素 (🎯/📥/📤/💬) 付きで提示。 段階的に「読む→動かす→改造する」を体験できます。
🎯 このコードでやること:特徴量を標準化したうえでロジスティック回帰の正則化強度 C を 0.001〜1000 の 7 段階で振り、 Log Loss と Accuracy がどう動くかを並べて見る。
📥 入力データ:SSDSE-B-2026 の 2023 年度・47 都道府県。
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・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 が同じ値のまま動かなくなる。
🎯 このコードでやること:同じモデルを 3 つの確率評価指標で測り、 違いを観察。
📥 入力データ:追加コード 1 で作った X, y。
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}") |
📤 実行結果:
💬 結果の読み方: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 県で測った値である。
🎯 このコードでやること:CalibratedClassifierCV で出力確率を再校正し、 Log Loss が下がるか確認。
📥 入力データ:追加コード 1 で作った X, y。
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}") |
📤 実行結果:
💬 結果の読み方:isotonic 回帰で校正すると Log Loss は 0.1992 → 0.1568 と約 21% 下がった。 ただし校正器を作った 47 県と評価した 47 県が同じなので、 この改善幅は楽観的に出ている。 isotonic は階段関数で確率を付け直すため、 47 件程度では階段が粗く、 本当に効くかは交差検証の外側で測った Log Loss で確かめる。
🎯 このコードでやること:Log Loss と Focal Loss を SSDSE-B-2026 で比較。 不均衡なほど Focal が効く。
📥 入力データ:追加コード 1 で作った X, y。
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}") |
📤 実行結果:
💬 結果の読み方:同じ予測確率 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 を実務で扱うとき、 多くの分析者が同じところでつまずきます。 代表的な失敗パターンを先回りで押さえておくと、 後工程のトラブルを大幅に減らせます。
log_e。 教科書は log_2 もあり(bit 単位)。 比較時は注意。※ 上記は文献調査・現場経験で報告される頻度の高い注意点。 ドメインや手法のバージョンによって追加の落とし穴がある場合があります。
初学者を超えた中級者がハマる「2 周目の失敗例」を集めました。 本編の 5 件と合わせて 15 件のチェックリストとして活用してください。
BCEWithLogitsLoss を使うときは logit 直接渡し。 Sigmoid をモデル出力にも掛けると二重適用。本編の 10 語に加え、 さらに専門用語 20 個を整理。 文献を読むときの「分からない単語チェッカー」として使えます。
47 都道府県 × 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}") |
📤 実行結果:
💬 結果の読み方:高齢化率 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)で、 陽性と陰性が半々に近い年ほど境界付近の県が増えて損失が大きくなる。
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%}') |
📤 実行結果:
💬 結果の読み方:正解率は学習データでも 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 では外し方の自信の強さに比例して重く数えられます。
上の京都府(実際は 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}') |
📤 実行結果:
💬 結果の読み方:京都府 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 / 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 段階で適切な選択を行う。
このフローは確率予測モデルの評価指標選択軸。 Log Loss は確率予測の「鋭さと正しさ」両方を測る指標で、 キャリブレーション (Platt/Isotonic) と組み合わせて初めて実務品質に到達する。
log_e。 教科書は log_2 もあり(bit 単位)。 比較時は注意。BCEWithLogitsLoss を使うときは logit 直接渡し。 Sigmoid をモデル出力にも掛けると二重適用。Log Loss は「評価指標」分野の中で発展してきた概念・手法です。 学術的には継続的な研究で精緻化され、 実務的にはツール・ライブラリの普及で誰でも使えるようになってきました。 用語の使い方・意味は時代と分野で少しずつ変わるため、 文脈に応じた解釈が大切です。 入門書だけでなく、 標準的な教科書(例:データサイエンス・統計学の定本)や信頼できるオンライン教材も併用すると、 ぶれない理解に近づけます。
「Log Loss」 はこのページで詳しく扱った概念です。 持ち帰ってほしい 3 つの要点:
さらに学ぶには、 関連用語 や 関連グループ教材 を参照してください。 各用語ページを縦断的に読むことで、 体系的な理解が育ちます。
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)の単独ページは現時点で未作成のためリンクなし。 本ページ上部の「触って理解する」節も参照。)