「evaluation metrics」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「evaluation metrics」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「evaluation metrics の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
モデルの良さを測る物差しです。
正しく予測できているか知るために使います。
テストの点数で実力を測るのと似ています。
ここでは代表的な指標の種類を学びます。
機械学習・統計モデルの「良さ」を測る指標。 タスクの種類(分類 / 回帰 / ランキング / 生成)とデータの性質(クラス不均衡 / 外れ値)に応じて選びます。 「1指標だけで判断しない」「テストデータで評価する」が鉄則。
| タスク | 代表指標 | 範囲 | 良い値 |
|---|---|---|---|
| 2値分類(バランス) | Accuracy、 AUC | [0, 1] | ↑(1 に近い) |
| 2値分類(不均衡) | F1、 Precision、 Recall、 PR-AUC | [0, 1] | ↑ |
| 多クラス分類 | macro/micro F1、 Top-k Accuracy | [0, 1] | ↑ |
| 確率予測 | Log Loss、 クロスエントロピー、 Brier Score | [0, ∞) | ↓(0 が理想) |
| 回帰 | MSE、 RMSE、 MAE、 R² | [0, ∞) / R² ≤ 1 | MSE↓ / R²↑ |
| ランキング | NDCG、 MAP、 MRR | [0, 1] | ↑ |
分類予測の正解と誤りを表にしたもの。 すべての分類指標の出発点。
| 予測:陽性 | 予測:陰性 | |
|---|---|---|
| 実際:陽性 | TP(真陽性) | FN(偽陰性) |
| 実際:陰性 | FP(偽陽性) | TN(真陰性) |
多クラス分類では k×k の行列に拡張。 対角が正解、 非対角が間違い。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ## scikit-learn の評価指標を一気に使う import pandas as pd import numpy as np from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split, StratifiedKFold, cross_validate from sklearn.metrics import ( accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, average_precision_score, log_loss, confusion_matrix, classification_report, roc_curve, precision_recall_curve ) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026']==2023] ## 「東日本 vs 西日本」を 2 値ターゲットにする east = ['北海道','青森県','岩手県','宮城県','秋田県','山形県','福島県', '茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県', '新潟県','富山県','石川県','福井県','山梨県','長野県'] df['east'] = df['Prefecture'].isin(east).astype(int) X = df[['A1101', 'A4101', 'A1303']].values ## 総人口・出生数・65歳以上人口 y = df['east'].values X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42) model = LogisticRegression(max_iter=1000).fit(X_tr, y_tr) y_pred = model.predict(X_te) y_prob = model.predict_proba(X_te)[:, 1] print(f'Accuracy : {accuracy_score(y_te, y_pred):.3f}') print(f'Precision: {precision_score(y_te, y_pred):.3f}') print(f'Recall : {recall_score(y_te, y_pred):.3f}') print(f'F1 : {f1_score(y_te, y_pred):.3f}') print(f'ROC-AUC : {roc_auc_score(y_te, y_prob):.3f}') print(f'PR-AUC : {average_precision_score(y_te, y_prob):.3f}') print(f'LogLoss : {log_loss(y_te, y_prob):.3f}') print(classification_report(y_te, y_pred)) |
🍰 まずはやさしく
客観的に性能を測る道具です。
データの性質に合わせて使い分けるためです。
スマホアプリの精度を比べるようなものです。
このページで学ぶ指標の全体像を説明します。
論文・記事に 「Accuracy」「Precision」「Recall」「F1」「ROC-AUC」「RMSE」「MAE」「MSE」「クロスエントロピー」「交差検証」「混同行列」 として登場する評価指標群。 「モデルの良さ」を客観的に測る道具。 タスクの種類とデータの性質で選び分けます。
このページが属する大分類:機械学習・統計モデリングの モデル評価 分野。 直近の上位概念は 機械学習基礎 と 仮説検定 (第 I 種・第 II 種誤りが Precision / Recall の祖先)。 兄弟概念に 交差検証・混同行列・ROC 曲線 が並びます。
このページの読み方:まず 💡 30 秒結論 で全体像を掴み、 🎨 直感 でタスク別の物差し選びを理解、 続く 🧮 計算例 で SSDSE-B-2026 を使った具体値、 🐍 Python で sklearn 実装、 最後に ⚠️ 落とし穴 で不均衡データやリークの罠を確認します。
🍰 まずはやさしく
目的によって使い分ける物差しです。
何を重視して測りたいかを決めるためです。
体重や体脂肪率を使い分けるのと似ています。
なぜ指標の使い分けが必要かを見ていきましょう。
あなたが 体重計 を選ぶとき、 「kg」と「lb」だけでなく BMI や 体脂肪率 も気にするはず。 評価指標も同じで、 「何を測りたいか」によって適切な物差しが違う。 分類モデルなら「全体の的中率(Accuracy)」「見逃したくない(Recall)」「誤検知を避けたい(Precision)」「総合的なバランス(F1)」など。 1 つの数字で全部を語ろうとすると、 必ず判断を誤ります。
本ページでは SSDSE-B-2026(47 都道府県 × 12 年の公的データ)で実際に分類モデルを学習し、 主要評価指標を 同じデータ・同じモデル で並べて算出します。 数字を見比べることで、 「なぜこの指標がこの場面で必要か」が腹落ちします。
| タスク種類 | 代表指標 | いつ使う |
|---|---|---|
| 2 値分類(均衡) | Accuracy / F1 / AUC | クラスがほぼ均衡なら Accuracy も使える |
| 2 値分類(不均衡) | F1 / Precision / Recall / PR-AUC | 陽性が稀(不正検知・希少疾患など) |
| 多クラス分類 | macro F1 / weighted F1 / Top-k Accuracy | クラス数 ≥ 3、 各クラスの均等扱いが必要 |
| 回帰 | RMSE / MAE / R² / MAPE | 連続値予測の誤差を測る |
| 確率予測 | Brier score / log loss / 較正曲線 | 出力確率の信頼性が重要 |
| ランキング | nDCG / MAP / MRR | 検索・推薦システム |
プロ野球の打者を「打率」だけで評価しても、 1 番打者と 4 番打者では役割が違う。 1 番打者は「出塁率」が重要 (Recall に相当)、 4 番打者は「打点・本塁打」が重要 (高得点出力に相当)。 同じ「打席に立つ」業務でも、 ポジションごとに「測りたいもの」が違う。 評価指標も同じで、 タスクや業務コストに応じて「何を測るか」を選ぶ必要がある。 もし君が監督なら、 全選手を打率だけで起用判断するだろうか?
| モデル | Accuracy | Precision | Recall | F1 | 結論 |
|---|---|---|---|---|---|
| 常時「減少」予測 | 0.85 | 0.85 | 1.00 | 0.92 | 無駄な対策コスト爆増 |
| ロジスティック回帰 | 0.91 | 0.93 | 0.96 | 0.94 | バランス良好 |
| 厳しい閾値モデル | 0.79 | 0.99 | 0.71 | 0.83 | 見逃し多 (FN 11 件) |
Accuracy だけ見れば「常時減少」モデルが 0.85 で 3 番目より高い。 だが Precision/Recall を見ると、 これは「予測の意味がない」モデルと分かる。 評価指標は 複数並べて初めて見える。
🍰 まずはやさしく
指標を計算するための数式です。
正確な数字で性能を出すために使います。
部活の記録を計算して分析するようなものです。
正答率などの具体的な計算方法を学びます。
2 値分類の混同行列を、 TP(真陽性)・TN(真陰性)・FP(偽陽性)・FN(偽陰性)の 4 セルで定義します。 すべての指標は、 この 4 つの自然数から計算されます。
基本指標を押さえた次のステップは、 「予測確率の信頼性」と「損失関数による評価」です。 ここでは Brier score・log loss・較正曲線の概念を SSDSE-B-2026 で確認します。
予測確率 $\hat{p}_i$ と実ラベル $y_i \in \{0,1\}$ の二乗誤差の平均。 0 が完璧、 0.25 が「常に 0.5 を予測するベースライン」。 確率値そのものの精度を測る。
確率の対数尤度の負平均。 自信を持って外したとき($\hat{p}=0.99$ だが $y=0$)に大きな罰を与える。 ロジスティック回帰・ニューラルネットの学習目的関数そのもの。 0 が完璧、 0.693 が「常に 0.5」のベースライン。
予測確率を 10 分位に分け、 各ビンの「平均予測確率」と「実際の陽性比率」を比較。 対角線に乗っていれば較正されている。 ランダムフォレストや SVM は較正が悪い場合が多く、 CalibratedClassifierCV で補正する。
LogLoss=0.379 はベースライン(常に 0.5 と予測したときの 0.693)を大きく下回り、 確率予測として良好。 ベースライン(常に 0.5)の 0.693 を大きく下回る。
「Accuracy=0.93」だけでは「サンプル 15 件で偶然そうなった」のか「真に良い」のか区別できません。 bootstrap で 1000 回リサンプリングして指標を再計算すると、 95% 信頼区間が得られます。
このコードでやること:先ほどの hold-out 結果に対し、 bootstrap で F1・AUC の信頼区間を計算する。
📥 入力:yte(15 件のラベル)と yprob(予測確率)。 リサンプル回数 1000。
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 # ── この抜粋だけで動くように、47 都道府県・最新年度を読み込む ── _d = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) _d = _d[_d['SSDSE-B-2026'] == 2023] import numpy as np from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import f1_score, roc_auc_score # ── この抜粋だけで動くように、検証用の正解 yte と予測確率 yprob を作る ── _east = ['北海道','青森県','岩手県','宮城県','秋田県','山形県','福島県', '茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県', '新潟県','富山県','石川県','福井県','山梨県','長野県'] _X = _d[['A1101', 'A4101', 'A1303']].astype(float).values _y = _d['Prefecture'].isin(_east).astype(int).values Xtr, Xte, ytr, yte = train_test_split(_X, _y, test_size=0.4, random_state=0, stratify=_y) yprob = LogisticRegression(max_iter=1000).fit(Xtr, ytr).predict_proba(Xte)[:, 1] rng = np.random.default_rng(0) f1s, aucs = [], [] y_arr = np.asarray(yte); p_arr = np.asarray(yprob) for _ in range(1000): idx = rng.integers(0, len(y_arr), len(y_arr)) if len(np.unique(y_arr[idx])) < 2: continue f1s.append(f1_score(y_arr[idx], (p_arr[idx] >= 0.5))) aucs.append(roc_auc_score(y_arr[idx], p_arr[idx])) print(f'F1 95% CI: [{np.percentile(f1s, 2.5):.3f}, {np.percentile(f1s, 97.5):.3f}]') print(f'AUC 95% CI: [{np.percentile(aucs, 2.5):.3f}, {np.percentile(aucs, 97.5):.3f}]') |
📤 実行すると次の出力が得られる(典型例):
💬 結果の読み方:F1 点推定 0.923 に対して 95% CI [0.727, 1.000] と 広い。 これは「テスト 15 件しかない」のサンプル不足が原因。 「F1=0.923」とだけ報告するのは過信で、 「F1=0.92 [0.73-1.00]」と区間を併記するのが誠実。 サンプルを増やせば CI は狭まる。
本物の論文や業務報告では、 これら 3 種類すべてを意識し、 適切な区間を併記します。 数値 1 点だけの報告は 研究の作法 として今や受け入れられない。
「結局どの指標を使うか」を業務シナリオ別に整理します。 自分の問題がどれに該当するかを確認してください。
本ページで扱った主要指標を 1 つの表に集約。 業務での選択時に このページをブックマークして、 都度参照する使い方を想定しています。
| 指標 | タスク | 値域 | 最良 | 不均衡耐性 | 閾値依存 | 主用途 |
|---|---|---|---|---|---|---|
| Accuracy | 分類 | [0,1] | 1 | ✗ 弱い | ○ | 均衡時の総合 |
| Precision | 分類 | [0,1] | 1 | ○ 強い | ○ | 誤検知重視 |
| Recall | 分類 | [0,1] | 1 | ○ 強い | ○ | 見逃し重視 |
| F1 | 分類 | [0,1] | 1 | ○ 強い | ○ | P/R バランス |
| ROC-AUC | 分類 | [0,1] | 1 | △ 弱い場合 | ✗ 非依存 | 順序評価 |
| PR-AUC | 分類 | [0,1] | 1 | ○ 強い | ✗ 非依存 | 不均衡時の総合 |
| log loss | 確率 | [0,∞) | 0 | ○ 強い | ✗ 非依存 | 確率の精度 |
| Brier | 確率 | [0,1] | 0 | ○ 強い | ✗ 非依存 | 較正含む精度 |
| RMSE | 回帰 | [0,∞) | 0 | — | — | 大誤差ペナルティ |
| MAE | 回帰 | [0,∞) | 0 | — | — | 外れ値に頑健 |
| R² | 回帰 | (-∞,1] | 1 | — | — | 分散説明率 |
| MAPE | 回帰 | [0,∞) | 0 | — | — | 相対誤差比較 |
「不均衡耐性」○ = 不均衡データでも信頼できる、 ✗ = 不均衡で誤った印象を与える。 「閾値依存」○ = 閾値 0.5 などで計算される、 ✗ = 閾値非依存(連続スコアから直接計算)。 業務選択時はまず「不均衡耐性」列を確認し、 自分のデータに合うかを判定。
評価指標 (Evaluation Metrics) は分類・回帰・ランキング・クラスタリングといったタスク種別ごとに対応する関数が sklearn.metrics モジュールに集約されている。 分類なら accuracy_score / precision_recall_fscore_support / roc_auc_score / log_loss / matthews_corrcoef、 回帰なら mean_squared_error / mean_absolute_error / r2_score / mean_absolute_percentage_error、 ランキングなら ndcg_score / average_precision_score、 クラスタリングなら silhouette_score / adjusted_rand_score が代表選手。 「どれを使うべきか」はタスクとデータ分布で決まり、 不均衡分類に Accuracy を使うような誤用は実務でも頻発する。
分類指標カタログ: Accuracy = 全体正解率、 Precision = 陽性予測のうち本当の陽性、 Recall = 真の陽性のうち拾えた割合、 F1 = Precision と Recall の調和平均、 ROC-AUC = 閾値非依存の総合力、 PR-AUC = 不均衡時の AUC 代替、 MCC = 完全均衡指標 (-1 〜 1)。 回帰指標カタログ: MSE = 大誤差を重く罰する、 RMSE = MSE の単位戻し、 MAE = 外れ値に頑健、 R² = 分散説明率、 MAPE = 相対誤差で 0 値や負値に注意。 各指標は同じデータでも異なるランキングを出すので、 比較する複数モデルで「同じ指標で」評価することが鉄則。
このコードでやること:SSDSE-B-2026 の data/raw/SSDSE-B-2026.csv(2023 年・47 都道府県)から「総人口(A1101)→ 65 歳以上人口(A1303)」を予測する単回帰モデルを学習し、 sklearn.metrics の主要 4 指標 (MAE, MSE, RMSE, R²) を一気に計算する。 同時に「総人口 100 万人以上を陽性」と二値化したルールベース分類器に対して Accuracy / Precision / Recall / F1 / ROC-AUC を計算する。
📥 入力データ (SSDSE-B-2026 抜粋):
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 | import pandas as pd import numpy as np from sklearn.linear_model import LinearRegression from sklearn.metrics import (mean_absolute_error, mean_squared_error, r2_score, accuracy_score, precision_score, recall_score, f1_score, roc_auc_score) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026']==2023] X = df[['A1101']].values # A1101 総人口 y = df['A1303'].values # A1303 65歳以上人口 # 回帰 model = LinearRegression().fit(X, y) yhat = model.predict(X) print(f'MAE = {mean_absolute_error(y, yhat):.1f}') print(f'MSE = {mean_squared_error(y, yhat):.1f}') print(f'RMSE = {np.sqrt(mean_squared_error(y, yhat)):.1f}') print(f'R^2 = {r2_score(y, yhat):.3f}') # 分類: 総人口 100 万以上=陽性、 65歳以上人口 30 万以上=予測陽性 y_true = (df['A1101'] >= 1_000_000).astype(int) y_pred = (df['A1303'] >= 300_000).astype(int) y_score = df['A1303'].values print(f'Acc = {accuracy_score(y_true, y_pred):.3f}') print(f'Prec = {precision_score(y_true, y_pred):.3f}') print(f'Rec = {recall_score(y_true, y_pred):.3f}') print(f'F1 = {f1_score(y_true, y_pred):.3f}') print(f'AUC = {roc_auc_score(y_true, y_score):.3f}') |
📤 実行すると次の出力が得られる:
💬 R²=0.982 は単回帰として非常に高い説明力。 分類側は Accuracy 0.936 と F1 0.961、 AUC 0.989 と全指標が高水準で、 「総人口 → 65 歳以上人口」がほぼ線形に並ぶデータ特性をよく表している。 業務では同じデータに対して複数指標を並べて報告し、 「Accuracy だけ見せて満足」というアンチパターンを避けることが重要。 不均衡データに切り替えた場合は AUC や F1 がより信頼でき、 Accuracy だけ高くなる現象が頻発する点に注意する。
評価指標は「モデルがどれだけ良いか」を一つの数値に圧縮する道具だが、 圧縮の仕方によって見えるものと見えないものが極端に変わる。 ここでは SSDSE-B-2026 都道府県データ(n=47)を題材に、 回帰系(MAE / MSE / RMSE / R² / 調整済み R²)と分類系(Accuracy / Precision / Recall / F1 / AUC)の指標がそれぞれ「何を測り、 何を見落とすか」を、 式・直感・実値・図で立体的に読み解く。 一見冗長に見える指標群が、 実は 互いに補完しあう 関係にあることを腹落ちさせるのが本節の目的である。
MAE(平均絶対誤差)は誤差の絶対値の平均、 RMSE(二乗平均平方根誤差)は誤差の二乗を平均してから平方根を取った値である。 単位はどちらも目的変数と同じ(65 歳以上人口なら「人」)。 ところが両者は 外れ値への感度 がまったく異なる。 RMSE は二乗を経由するため、 誤差 100 を一件出すと、 誤差 10 を百件出すのと同じだけ罰せられる。 つまり RMSE は「大きく外したくない」という意思表示、 MAE は「平均的に当てたい」という意思表示の指標である。 SSDSE-B-2026 で「65 歳以上人口 = a × 総人口 + b」の単回帰を作ると、 東京都が外れ値となり MAE と RMSE の比が大きく開く(実測で RMSE / MAE ≒ 1.63)。 RMSE / MAE が 1.4 を超えていたら、 「一部の県で大きく外している」と読み、 残差プロットで確認する習慣を持つとよい。
MSE は誤差の二乗の平均、 RMSE はその平方根、 R² は「全分散のうちモデルで説明できた割合」である。 同じ残差から作るので情報量は基本同じだが、 提示する相手によって伝わりやすさが違う。 経営層には R²(0〜1 の説明力)、 現場には RMSE(実単位の誤差)、 機械学習の損失関数としては MSE(微分が綺麗)が好まれる。 一つだけ覚えるなら RMSE。 MSE は二乗のため単位が「(人)²」となり直感に乗りにくいが、 平方根を取って RMSE にすれば「平均してこれくらい外している」と読める。 R² は分子に SSE(残差平方和)、 分母に SST(総平方和)を取り、 1 から比を引く。 SST が小さい(目的変数のばらつきが小さい)データセットでは R² が低く出やすいため、 R² 単独で「悪いモデル」と判断するのは早計である。
R² は説明変数を増やせば必ず増えるか同じ値になる。 つまり「無意味な変数を足しても R² が下がらない」性質を持つ。 これでは「変数を増やせば増やすほど良いモデル」と誤読されかねない。 調整済み R² は「変数を増やしたら、 その分情報を増やしたか?」を問うために、 式に (n-1)/(n-p-1) を掛ける。 ここで n はサンプル数、 p は説明変数の数。 SSDSE-B-2026 のように n=47 と小さいデータで p を 5、 10 と増やすと、 通常 R² はじりじり上がるが、 調整済み R² はある時点で頭打ちになり、 そこから下がる。 調整済み R² がピークを打ったところが、 そのモデル族の「正味の説明力の上限」 と読む。
Accuracy(正解率)は「全予測のうち正解した割合」。 直感的で説明しやすいが、 クラス比率が偏っていると簡単に騙される。 例: 65 歳以上人口が「全国平均以上」かを当てる問題でも、 平均以上は全 47 県中およそ 12 県(約 26%)と偏る。 「全部『平均未満』と答える」ベースラインだけで Accuracy 0.745 が出る。 ここに、 それを数ポイント上回っただけのモデルが出てきても「ベースラインからほとんど上がっていない」ことを Accuracy 単独では伝えにくい。 不均衡データでは Precision・Recall・F1・AUC のいずれかを Accuracy と並べて必ず併記する。
Precision(適合率)は「陽性と予測したうち本当に陽性だった割合」、 Recall(再現率)は「実際に陽性だったうち陽性と予測できた割合」。 両者は基本的にトレードオフ関係にある。 閾値を下げて「少しでも怪しいものは陽性」とすれば Recall は上がるが Precision は下がる。 閾値を上げて「確実なものだけ陽性」とすれば Precision は上がるが Recall は下がる。 ビジネス文脈で先に決めるのはどちらを重視するか。 例: 医療スクリーニングは見逃しが致命的なので Recall 優先、 スパムフィルタは誤検知が致命的なので Precision 優先。 SSDSE-B-2026 でも「人口減少県をスクリーニングする」なら Recall、 「補助金支給対象を判定する」なら Precision を優先する判断が現場で発生する。
F1 は Precision と Recall の調和平均で、 算術平均ではなく 小さい方に強く引っ張られる 性質を持つ。 つまり「片方だけ 1.0 で片方が 0.0」だと F1 は 0 になる。 これは「両方ともそこそこ高い」状態を強く要求する指標である。 業務的には「Precision と Recall を一つの数値に集約して、 モデル選定の意思決定を高速化したい」場面で使う。 ただし F1 は「Precision と Recall を 等しく 重視する」前提なので、 重みを変えたい場合は F-beta(β > 1 で Recall 重視、 β < 1 で Precision 重視)を使う。
Accuracy・Precision・Recall・F1 はいずれも「閾値を 0.5(など特定の値)に固定したときの値」である。 閾値の選び方でこれら指標は大きく動く。 AUC は 閾値をすべて動かしたときの ROC 曲線の下の面積 で、 「ランダムに陽性 1 件と陰性 1 件を取ってきたとき、 陽性のスコアの方が高い確率」と読める。 完全なランダム予測で 0.5、 完全予測で 1.0。 SSDSE-B-2026 の「人口上位 / 下位」二値分類問題では、 単純な「面積一つだけ説明変数」モデルでも AUC 0.97 程度に到達する。 AUC は不均衡データに強く、 閾値選定の前段階で「モデルそのものの良し悪し」を測れる点が便利。
クラスが 3 つ以上ある場合、 Precision・Recall・F1 をクラスごとに計算してから集約する必要がある。 集約方法は三つ。 Macro 平均 はクラスごとの指標を単純平均(少数クラスにも公平)、 Micro 平均 は全予測をプールしてから計算(多数クラスに引っ張られる)、 Weighted 平均 はクラスサイズで重み付け(多数クラス重視)。 SSDSE-B-2026 の地方ブロック(北海道・東北・関東 …)の 8 クラス分類では、 関東が偏って多いので Micro と Weighted は近い値、 Macro だけ低めに出ることが多い。 「全体感は Micro、 公平性は Macro、 業務インパクトは Weighted」と覚えるとよい。
分類の評価指標はすべて混同行列の 4 要素(TP / FP / FN / TN)から導かれる。 Accuracy = (TP + TN) / 全件、 Precision = TP / (TP + FP)、 Recall = TP / (TP + FN)、 Specificity = TN / (TN + FP)。 一度混同行列を作れば、 用途に応じて自由に指標を組み替えられる。 業務上「FP のコスト = 1 万円、 FN のコスト = 100 万円」のように コストが分かっている場合は、 期待損失を直接計算する 方が、 抽象的な F1 を最適化するより実践的である。
学習時に最小化するのが 損失関数、 完成後のモデルを評価するのが 評価指標。 両者は 同じである必要はない。 例: ロジスティック回帰は対数損失(log loss)を最小化するが、 評価指標としては AUC や F1 を使う。 損失関数は「微分可能でなめらか」が要求されるが、 評価指標は人間や業務に響く形であればよい。 ただし両者が乖離しすぎていると、 「損失は下がるのに F1 が上がらない」現象が起きる。 そんなときは閾値最適化(calibration)や F1 を直接最大化するような損失関数(focal loss など)への切り替えを検討する。
評価指標は「テストデータ 1 セット」の値だけで判断すると、 たまたまの良し悪しに振り回される。 K 分割交差検証で K 個の値を出し、 平均と標準偏差を併記 するのが基本。 SSDSE-B-2026 のように n=47 と小さいデータでは、 5 分割すると 1 fold あたり 9-10 件で標準偏差が大きく出る。 「平均 R² = 0.85 ± 0.07」と報告できれば、 「平均 0.85」だけよりはるかに信用される。 標準偏差が大きすぎる場合は「データの分散が不均一」「外れ値が一部 fold にだけ入った」などの可能性を疑う。
「Accuracy 0.90 です」だけでは良いか悪いか判断できない。 必ず ベースラインとの差 で語る。 ベースラインは(a) 多数派クラス予測、(b) ランダム予測、(c) 単純な線形モデル、(d) 既存業務ルール、 など複数用意する。 SSDSE-B-2026 では「47 県の平均値で予測する」ベースラインに対する RMSE 改善率を見れば、 「人口を入れた効果はどれくらいか」が一目で分かる。 評価指標は 絶対値ではなく改善幅で語る ことで、 はじめて意思決定に効く数値になる。
(1) Accuracy だけで不均衡データの結論を出す、 (2) 訓練データで評価指標を測って「過学習」を見落とす、 (3) R² が高いだけで「正しいモデル」と決めつける(残差プロットを見ない)、 (4) AUC が高いから業務で使えると即断する(閾値を決めずに納品する)、 (5) クロスバリデーションせずにテスト 1 回の結果を報告する、 (6) 多クラスで macro / micro / weighted の違いを意識せずに F1 を出す、 (7) 損失関数と評価指標を区別せず「損失が下がっているから良い」と読む。 いずれも頻出の失敗で、 PR レビュー時のチェック項目として定着させたい。
参考までに、 SSDSE-B-2026(2023 年・47 都道府県)を使った実測ベンチマーク。 単回帰(総人口 → 65 歳以上人口): R² = 0.982、 RMSE ≒ 91,993 人、 MAE ≒ 56,477 人、 調整済み R² ≒ 0.982。 二値分類(総人口 100 万人以上を陽性、 65 歳以上人口 30 万人以上を予測陽性): Accuracy = 0.936、 Precision = 0.925、 Recall = 1.000、 F1 = 0.961、 AUC = 0.989。 ここから「総人口は 65 歳以上人口に対し極めて強い予測力を持つ」と読める一方、 東京都の人口が突出することで「規模の大きい県を当てるのは易しいが、 中央付近の県の判別は難しい」という業務示唆も得られる。 すべての評価指標は 業務示唆を得るための道具 であり、 数値を出して終わりではなく、 数値から仮説とアクションへ繋ぐところまで含めて初めて完成する。
評価指標は技術的な数値だが、 最終的にはビジネス KPI に翻訳されなければ意味を持たない。 例えば「F1 が 0.85 から 0.90 になった」だけでは経営層には響かない。 翻訳の基本は 「指標の改善が業務インパクトに換算するといくらか」を見積もる こと。 SSDSE-B-2026 を使った人口減少県スクリーニングの例で言えば、 Recall が 0.80 → 0.90 に上がるとは「見逃していた減少県を 10% 追加で捕捉できる」ということ。 1 県あたりの対策コストが 5 億円で、 捕捉漏れによる将来損失が 30 億円なら、 純便益は 25 億円 × 該当県数。 こうした 金額換算を必ず併記 することで、 評価指標が「技術部門の自己満足」ではなく「経営判断のインプット」になる。
時系列予測では通常の MAE / RMSE に加え、 MAPE(平均絶対パーセント誤差)、 SMAPE(対称版 MAPE)、 MASE(平均絶対スケール誤差)などが使われる。 MAPE は誤差を実値で割るためスケール非依存だが、 実値がゼロ付近で発散する弱点を持つ。 SMAPE は分母を「予測値と実値の平均」とすることでこれを緩和。 MASE は「ナイーブ予測(前期の値をそのまま予測)に対する改善率」で、 1 を下回ればナイーブより優秀。 SSDSE-B-2026 は時系列ではないが、 国勢調査の年次比較データに展開する場合、 これらの指標は必須となる。 さらに 方向一致率(実際の増減方向を当てた割合)も併記すると、 株価予測のように「金額より方向が重要」な業務での判断に効く。
推薦システム・検索エンジン・上位 N 件抽出のような ランキングタスク では、 二値分類とは別系統の指標を使う。 代表的なのは Precision@K(上位 K 件のうち正解の割合)、 Recall@K(全正解のうち上位 K 件に入った割合)、 nDCG(正解の位置と関連度を考慮した順位指標)、 MRR(最初に出た正解の順位の逆数)。 SSDSE-B-2026 で「人口減少リスクが高い順に 5 県をランキング」するタスクなら、 Precision@5 = 0.8 は「上位 5 県のうち 4 県が本当のリスク県」と読める。 nDCG は「最重要県を 1 位に置けば高得点、 後ろに置くと減点」という順位依存の評価で、 単なる集合ベースの F1 では捉えられない情報を抽出する。
教師なしのクラスタリングでは正解ラベルがないため、 評価が難しい。 大別して二系統: 内部指標(クラスタ自身の質を測る)と 外部指標(正解ラベルがある場合のみ使える)。 内部指標の代表は シルエット係数(-1〜1 で 1 に近いほど良い)、 Davies-Bouldin(小さいほど良い)、 Calinski-Harabasz(大きいほど良い)。 外部指標は ARI(調整ランド指標、 偶然一致を補正)、 NMI(正規化相互情報量)など。 SSDSE-B-2026 を地方ブロック 8 区分でクラスタリングする実験では、 シルエット係数 0.5 程度、 ARI(正解と比較) 0.6 程度が目安。 「k-means の k をいくつにすべきか」を決めるエルボー法と組み合わせて使う。
AI 倫理の文脈で重要になっている 公平性指標 も、 評価指標の一種。 代表的なのは Demographic Parity(保護属性によらず予測陽性率が同じ)、 Equal Opportunity(真陽性率が保護属性によらず同じ)、 Equalized Odds(真陽性率・偽陽性率の両方が同じ)。 これらは「全体精度」とトレードオフ関係にあることが多く、 すべて同時には満たせない という不可能性定理が知られる。 SSDSE-B-2026 を地方別に分割した場合、 「関東モデルで全国を予測すると東北での性能が落ちる」現象が起きる。 業務でモデルを納品する際は、 全体性能だけでなく セグメント別性能 を必ず添付し、 不利を被るセグメントが無いかを検証する。
「Accuracy = 0.90」と一点で示すより、 「Accuracy = 0.90 [95% CI: 0.85-0.94]」と区間で示す方が情報量が多い。 SSDSE-B-2026 のように n=47 と少ないデータでは、 1 件分類が当たるか外れるかで指標が大きく動く。 ブートストラップ法(テストデータから復元抽出を 1000 回繰り返し、 1000 個の指標値の 2.5 〜 97.5 パーセンタイルを区間とする)で信頼区間を求めるのが定石。 「区間が狭い = 安定した推定」、 「区間が広い = サンプル数不足や指標のばらつきが大きい」と読む。 業務での意思決定では「下限値が事前合意のしきい値を超えているか」を判断基準にすると、 たまたまの良し悪しに騙されにくくなる。
「FP コストが業務 X では 1 万円、 業務 Y では 100 万円」のように、 FP / FN のコストはユースケースごとに大きく異なる。 評価段階で FP コストと FN コストを変えながら最適閾値を再計算する 感応分析を行うと、 業務側との合意形成が速くなる。 横軸を FP/FN コスト比、 縦軸を最適閾値で描いた図を見れば、 「コスト比が 10:1 なら閾値 0.3、 1:10 なら閾値 0.7」のように業務側がスライダー感覚で意思決定できる。 SSDSE-B-2026 ベースの人口減少県スクリーニングで、 コスト比に応じた閾値マップを納品物に含めるのは強力なベストプラクティス。
Python では sklearn.metrics が最も網羅的で、 上記のほぼすべての指標を提供する。 accuracy_score / precision_score / recall_score / f1_score / roc_auc_score / mean_absolute_error / mean_squared_error / r2_score など。 多クラスの集約方法は average='macro' | 'micro' | 'weighted' 引数で切り替え。 classification_report を呼べば各クラスの Precision / Recall / F1 が表形式で出る。 さらに カスタム指標 はラムダ式で make_scorer に渡せば cross_val_score や GridSearchCV で直接最適化対象にできる。 業務固有のコスト関数(例: 5*FN + FP)を組み込めば、 「業務に直結した最適化」が実現する。
数値だけでなく図で示すと納得感が増す。 推奨される図は: (1) 混同行列のヒートマップ(TP / FP / FN / TN の関係が一目)、 (2) ROC 曲線(閾値ごとの FPR vs TPR)、 (3) Precision-Recall 曲線(不均衡データで ROC より情報量が多い)、 (4) Calibration plot(予測確率と実際の陽性率の対応)、 (5) 残差プロット(回帰では必須)、 (6) Lift chart / Gain chart(マーケティング業務で頻出)。 SSDSE-B-2026 単回帰の残差を都道府県名付きで散布すると、 「東京都だけ特異に大きく外れる」「中央付近の県は誤差が均一」など 業務示唆 が即座に得られる。
同じデータ・同じモデルでも、 ランダムシードや前処理の順序で評価指標は変動する。 再現性 を確保するには: (a) random_state を全箇所で固定、 (b) データ分割の方法を明文化(層化抽出か単純無作為か)、 (c) 前処理パイプラインを sklearn.pipeline.Pipeline でカプセル化、 (d) 環境を requirements.txt や conda env export で固定、 (e) mlflow 等の実験管理ツールで指標を自動記録。 SSDSE-B-2026 のような小データでは、 シードを変えただけで R² が 0.97 → 0.85 に振れることもある。 「再現できない指標は議論の対象にできない」を肝に銘じる。
複数人でモデルを開発する場合、 「どの指標を主指標とするか」をプロジェクト初期に合意する ことが最重要。 主指標を一つに絞らないと、 「私のモデルは F1 で勝った、 私のモデルは AUC で勝った」と議論が発散する。 主指標は業務 KPI と紐づける(例: 「Recall@10 を最大化」「期待損失を最小化」)。 副指標として 3〜5 個を併記し、 主指標が同等の場合の判断材料とする。 ダッシュボードには主指標を上、 副指標を下に並べ、 ベースラインとの比較・信頼区間・セグメント別性能をワンビューに収める。 SSDSE-B-2026 を題材にしたチーム演習でも、 「冒頭に指標合意の MTG を 30 分」を入れるだけで、 後工程の議論が劇的に短縮される。
モデルをデプロイした後も評価は続く。 本番環境での評価指標を時系列でモニタリング し、 性能劣化(drift)を検知する。 入力分布が変わる covariate shift、 入力と出力の関係が変わる concept drift、 ラベル分布が変わる label shift の三種類を区別する。 SSDSE-B-2026 のような国勢調査ベースのデータでも、 数年ごとの調査改定で人口構成が変わると、 過去データで学習したモデルの性能は確実に落ちる。 本番監視ダッシュボードでは、 (a) 推論件数、 (b) 主指標、 (c) 入力分布(KS 検定値等)、 (d) アラート条件(指標が baseline の 95% を切ったら通知)を常時表示する。
(1) テストデータ漏洩: 前処理(標準化など)を学習データ・テストデータまとめて行うと、 テストの情報が学習に漏れて指標が楽観バイアスを持つ。 必ず学習データで fit してからテストに transform を適用する。 (2) 時系列リーク: 時系列データを単純無作為分割すると、 未来の情報で過去を予測する形になり指標が過大評価される。 時間順分割を徹底する。 (3) 選択バイアス: テストセットがランダム抽出でなければ、 「テストでの良い指標」と「本番での良い指標」が乖離する。 (4) Goodhart の法則: 指標を最適化対象にした瞬間、 指標は「測りたいもの」を測らなくなる。 例えば Click-Through Rate を最大化するとクリックベイトばかりになる。 評価指標と業務目標の乖離を常に意識する。
評価指標の多くは 第二次世界大戦中のレーダー検知 研究に起源を持つ。 「敵機をレーダーで検知する」問題は典型的な二値分類で、 見逃し(FN)は致命的、 誤検知(FP)は出撃コストの無駄。 ここから「ROC 曲線(Receiver Operating Characteristic)」という名前が来ている。 戦後、 医学診断(がんスクリーニング、 心電図異常検知など)に応用が広がり、 「感度(Sensitivity = Recall)」「特異度(Specificity)」という用語が定着した。 1990 年代以降、 情報検索(IR: Information Retrieval)の文脈で Precision・Recall が主要指標となり、 機械学習の隆盛とともに F1、 AUC が一般化。 2010 年代以降は深層学習の評価で top-K accuracy(ImageNet)や BLEU(機械翻訳)、 ROUGE(要約)など、 タスク特化指標が爆発的に増えた。 評価指標の歴史を知ることは「なぜこの指標がこのタスクで使われるのか」を腹落ちさせる助けになる。
「モデル A の Accuracy が 0.85、 モデル B の Accuracy が 0.86」のとき、 本当に B が優れていると言えるか? 0.01 の差は 誤差の範囲か、 統計的に有意な差か を検定する必要がある。 同じテストデータで両モデルを評価した場合は McNemar 検定(対応のある二項検定)、 異なるテストデータなら 並べ替え検定 や ブートストラップ法 で差の信頼区間を求める。 SSDSE-B-2026 のように n=47 と少ないデータでは、 0.01 〜 0.03 程度の Accuracy 差はまず有意にならない。 「差が出た」と思っても、 検定で否定されるケースが大半で、 軽率な乗り換えは避けるべき。 統計的有意性 ≠ 業務的有意性 という点も重要で、 「有意だが効果サイズが小さい」場合は、 改善コストに見合うかも併せて判断する。
本節を通じて学んだ通り、 評価指標は単なる「モデルの成績表」ではなく、 業務判断の起点となる情報基盤 である。 経営層・現場・データチームをつなぐ共通言語として機能し、 指標の設計・計測・解釈の質がプロジェクト全体の質を決める。 SSDSE-B-2026 を題材とした演習を通じて、 「指標を出して終わり」ではなく、 「指標から仮説 → 検証 → アクション」 までを一気通貫で実行できる人材が、 これからのデータサイエンス現場で最も求められる。 評価指標を制する者はモデルを制し、 モデルを制する者はビジネスを制す。 本節の内容を実プロジェクトで一度回せば、 評価指標を「義務」ではなく「武器」として使えるようになるはず。
実務でよくあるのが「同じデータに対して、 主要指標を一括で出して比較表を作る」タスク。 SSDSE-B-2026 を使い、 単回帰と二値分類の両モデルを構築し、 主要指標を 10 個以上同時に計算して表形式で並べる演習をすると、 各指標の関係性が体感的に掴める。 表を見れば「R² が高いのに RMSE は意外と大きい」「Accuracy は高いが F1 と AUC は中程度」のような 指標間の不整合 を発見でき、 そこから「外れ値があるのでは」「クラス不均衡では」と 仮説生成 に繋がる。 練習の答え合わせは、 まず自分で表を作り、 講師や Claude AI と「この指標差はどう解釈すべきか」を議論する形式が最も学習効率が高い。
金融(信用スコア、 与信判断): AUC、 KS 統計量、 Precision@K(上位 K% 顧客の不良率)。 医療(診断補助、 創薬): 感度(Recall)、 特異度、 PPV(Positive Predictive Value = Precision)、 ROC AUC。 マーケティング(推薦、 解約予測): Lift、 Gain、 CTR、 Conversion Rate。 製造業(異常検知、 品質予測): F2 スコア(Recall 重視)、 期待損失、 MTBF への寄与。 自然言語処理: BLEU(翻訳)、 ROUGE(要約)、 BERTScore(意味類似度)、 Perplexity(言語モデル)。 画像: top-K accuracy、 IoU(物体検出)、 Dice 係数(セグメンテーション)、 FID(生成画像)。 公共政策(SSDSE-B-2026 的なドメイン): RMSE、 MAPE、 ベースライン改善率、 公平性指標。 業界によって「何を最適化するか」が違うので、 指標選定はドメイン知識と切り離せない。
AutoML(自動機械学習)ツール(H2O AutoML、 Auto-sklearn、 TPOT、 Google AutoML、 Amazon SageMaker Autopilot など)は、 複数モデルを自動で試し、 主指標で最良のものを選ぶ。 ここで 主指標の選定がツール挙動を決定する。 主指標を AUC にすると「ランキング能力の高いモデル」が選ばれ、 F1 にすると「閾値 0.5 でバランス良いモデル」が選ばれる。 デフォルトの指標を盲信せず、 業務に合った指標を主指標として明示的に指定するのがプロの作法。 SSDSE-B-2026 をベースに AutoML を回す演習を行うと、 「主指標を変えるとモデル選定結果が劇的に変わる」現象が観察でき、 評価指標の重要性が体感できる。
「全体 Accuracy 95%」のモデルでも、 特定の少数派グループでは Accuracy 60% かもしれない。 これは 「全体最適が部分悲劇を生む」 典型例で、 倫理的に大きな問題となる。 採用判定 AI で女性応募者の Precision が低い、 融資審査 AI で特定民族の Recall が低い、 などは現実に起きた事例。 解決策は (a) セグメント別性能の必須開示、 (b) 公平性指標の併用、 (c) 影響を受ける当事者を開発プロセスに巻き込む(co-design)。 SSDSE-B-2026 のような公共データを使う場合も、 都道府県別・地方別の性能差を必ず開示し、 「全国平均では良いが地方で悪い」モデルを納品しない倫理観を持つべき。
近年は LLM(大規模言語モデル)の評価で新しい指標が次々登場している。 BERTScore(意味類似度を埋め込みベースで計算)、 BLEURT(学習済み評価モデル)、 G-Eval(GPT-4 等で自動評価)、 HELM(多次元統合評価フレームワーク)など。 これらは「正解との完全一致」を要求しない柔軟な指標で、 オープンエンドな生成タスクに適応している。 一方で 自動評価指標と人間評価の乖離 が問題となる場面も多く、 ハイステークスな業務では人間評価を必ず併用する。 SSDSE-B-2026 の文脈から離れた話題だが、 評価指標の世界が今も拡張中である事実は知っておく価値がある。
評価指標を腹落ちさせる最終ステップは、 三層構造で理解する こと。 第 1 層:技術指標(Accuracy、 F1、 AUC、 R²、 RMSE など)— モデルの数値的性能。 第 2 層:ビジネス指標(売上、 解約率、 補助金支給漏れ件数、 期待損失)— 業務 KPI への翻訳。 第 3 層:社会指標(公平性、 透明性、 説明責任、 倫理)— ステークホルダー全体への影響。 三層を一気通貫で語れることが、 シニアデータサイエンティストの条件。 SSDSE-B-2026 のような公共データを使う演習でも、 「R² = 0.97 だから OK」で止まらず、 「これが補助金配分の意思決定に使われるなら、 地方別に R² がどう違うか必ず確認すべき」まで踏み込めるかが分水嶺。 評価指標を制した先に、 価値あるデータサイエンスがある。
同じデータで複数のモデルを評価し、 そのうち最良の指標を報告するのは 多重比較問題 を生む。 100 モデル試して最良の Accuracy だけ報告すると、 たまたま良かったモデルが選ばれる確率が高い。 これを補正するために nested cross-validation(外側 CV でモデル選択評価、 内側 CV でハイパーパラメータ探索)を使う。 SSDSE-B-2026 のような小データでは特に深刻で、 「数百モデル試した中で最良の F1 を報告」という研究を見たら、 数値を信用せず再現実験を疑う姿勢が必要。 また p-hacking(有意になるまで分析設定を変える行為)の評価指標版もあり、 「閾値を動かしながら最良の F1 を報告」もこれに当たる。 評価プロトコルを 事前登録(pre-registration)する文化が、 学術界・産業界で広がりつつある。
実務で「どの指標を使うべきか迷ったときの 5 ステップ」フレームワーク: (1) タスクの種類を特定(回帰 / 分類 / ランキング / クラスタリング / 生成)。 (2) クラス比率を確認(均衡か不均衡か)。 (3) 誤りのコストを把握(FP と FN どちらが致命的か、 金額換算でいくらか)。 (4) ステークホルダーの目線を確認(経営層なら 1 指標、 現場なら複数指標、 倫理的観点なら公平性指標を追加)。 (5) 主指標 1 個 + 副指標 3〜5 個を確定。 このフレームワークを SSDSE-B-2026 ベースの演習で 3 回繰り返すと、 指標選定の勘所が体に馴染む。 「迷ったら主指標 1 個 + 副指標 3〜5 個」が黄金律。
評価指標は PDCA の中核に位置する。 Plan で主指標と目標値を設定(例: Recall ≥ 0.85)、 Do でモデルを構築、 Check で指標を測定、 Act で改善アクション(特徴量追加、 ハイパーパラメータ調整、 アルゴリズム変更など)。 このサイクルを高速で回すために、 指標ダッシュボード(実験管理ツール、 例: MLflow、 W&B、 Neptune)を最初から整備するのが推奨。 SSDSE-B-2026 のような演習でも、 「最初の 1 時間で MLflow を立てる」だけで、 後の 10 実験の生産性が劇的に上がる。 評価指標を「測定可能・記録可能・比較可能」な状態にするインフラ投資は、 最も ROI の高い初期投資の一つ。
最後に、 評価指標を業務で運用する際の 現場チェックリスト 12 項目: (1) 主指標は業務 KPI と紐づいているか。 (2) 副指標は 3〜5 個揃っているか。 (3) ベースライン(多数派予測、 ランダム、 既存ルール)と比較しているか。 (4) クラス比率を確認したか。 (5) 信頼区間(または標準偏差)を併記したか。 (6) クロスバリデーションで分散を測ったか。 (7) セグメント別性能を確認したか。 (8) 公平性指標を測ったか。 (9) コスト感応分析をしたか。 (10) テストデータ漏洩のチェックをしたか。 (11) 評価プロトコルを文書化したか。 (12) 本番監視の指標と整合しているか。 SSDSE-B-2026 を題材に演習する際、 このチェックリストを毎回回せば、 評価の質が一段階上がる。 「Q3 を Q5 に上げる」ための最短ルートは、 このチェックリストを習慣化すること である。
評価指標を「モデルの正解度を測る道具」と捉えるのは初心者の視点。 中級者は「業務 KPI への翻訳」と捉え、 シニアは 「ステークホルダーとの対話を構造化する共通言語」 と捉える。 数値そのものより、 数値を巡る議論こそが価値を生む。 「なぜこの指標を選んだのか」「なぜこのしきい値か」「なぜこのベースラインと比較するのか」「どの観測値で大きく外しているのか」「セグメント別に見るとどうか」「業務的に許容できる誤差はどこか」 — これらの問いを巡る対話が、 ステークホルダー間の合意を深める。 SSDSE-B-2026 のような演習データを使い、 同じデータ・同じモデルでも対話の質によって意思決定の質が大きく変わる体験ができる。 評価指標は「数字一個」ではなく「議論のプロトコル」なのである。
評価指標を一通り使いこなせるようになったら、 次は 意思決定理論(Decision Theory)や 因果推論(Causal Inference)への展開が推奨される。 意思決定理論では「期待効用最大化」「ベイズ意思決定」など、 評価指標を入力として最適行動を選ぶ枠組みを学ぶ。 因果推論では「予測精度が高いモデル」と「介入効果を正しく推定するモデル」が異なることを学ぶ。 例: SSDSE-B-2026 で「人口減少を予測できるモデル」と「人口減少を抑制する政策効果を推定できるモデル」は別物。 評価指標は前者を測るには十分だが、 後者には RCT や差の差分析(DiD)が必要になる。 評価指標は データサイエンスの入口 であり、 ここから先は意思決定・因果・倫理・経済学が複合的に絡む高次の領域が広がっている。 SSDSE-B-2026 を題材にした演習が、 その入口を開く一歩となれば幸いである。
本節を通じて学んだ内容を 三原則 に圧縮する。 第一原則:単独指標で判断しない。 Accuracy だけ、 R² だけ、 AUC だけで結論を出さず、 必ず複数指標とベースラインを併記する。 第二原則:セグメント別に確認する。 全体性能は良くても、 特定セグメントで劣化していないか必ずチェックする。 第三原則:業務 KPI に翻訳する。 技術指標で終わらず、 必ず金額・件数・時間など業務側が判断できる形に変換する。 この三原則を SSDSE-B-2026 を題材とした演習で 5 回繰り返せば、 評価指標を扱う身体感覚が定着する。 評価指標は道具であり、 道具は使い込まないと馴染まない。 反復演習こそが上達の唯一の道である。
評価指標を最短で身につける学習法は、 (a) 主要 10 指標の式を手書きで導出する、 (b) SSDSE-B-2026 で全指標を一括計算するスクリプトを書く、 (c) チームに指標選定の理由を口頭で説明する、 の三点セット。 これを 2 週間で 3 周回せば、 評価指標は「義務」ではなく「武器」になる。 知識ではなく 身体感覚 として定着するまで反復するのが肝要。
問 1: 「Accuracy = 0.95 のモデル」と聞いて、 安心してよいか判断するために最低限聞くべき情報を 3 つ挙げよ。
解答例: (a) クラス比率(多数派クラスの割合)、 (b) ベースライン Accuracy(多数派予測時の値)、 (c) Precision / Recall / F1 など他指標の同時提示。 これらがなければ Accuracy 0.95 は意味を成さない。
問 2: RMSE が MAE の 1.5 倍以上のとき、 何を疑うべきか。
解答例: 一部のサンプルで大きな誤差を出している可能性(外れ値、 特殊なセグメントでの予測失敗)。 残差プロットを描き、 ID ベースで「どの観測値で大きく外しているか」を確認するのが定石。 SSDSE-B-2026 の単回帰では東京都が代表例。
問 3: 多クラス分類で Macro F1 が Weighted F1 より大きく下回るとき、 何が起きているか。
解答例: 少数クラスでモデル性能が低い状態。 Macro はクラスごとに等重みで平均するため、 少数クラスでの低性能がそのまま反映される。 Weighted はクラスサイズで重み付けされるため、 多数クラスの高性能で隠される。 「公平性」を重視するなら Macro F1 で評価し、 少数クラスのデータ追加やリサンプリングを検討する。
SSDSE-B-2026 の 2023 年 47 都道府県データから、 高齢化率 ≥ 32% を陽性(進行県)とする 2 値分類モデルを学習し、 各評価指標を順に計算します。 タスク設定の詳細は 分類 ページの後半と同じ。 本ページは「指標」に焦点を当てて解説します。
先に hold-out 評価(test_size=0.3, stratify=y, random_state=42)で得られた混同行列を使って、 全指標を電卓で再現してみましょう。
電卓と Python の出力が一致することを必ず確認。 ライブラリの数字を 盲信せず 1 つでも手計算で再現する習慣が、 業務でのバグ発見につながる。
合成回帰の予測誤差で 3 指標を計算する。
| i | y | ŷ | 誤差 | 誤差² |
|---|---|---|---|---|
| 1 | 10 | 8 | 2 | 4 |
| 2 | 15 | 17 | 2 | 4 |
| 3 | 20 | 22 | 2 | 4 |
| 4 | 25 | 20 | 5 | 25 |
| 5 | 30 | 33 | 3 | 9 |
1 2 3 4 5 6 7 | import numpy as np y = np.array([10, 15, 20, 25, 30]) yhat = np.array([8, 17, 22, 20, 33]) e = y - yhat print(f"MAE: {np.abs(e).mean()}") print(f"MSE: {(e**2).mean()}") print(f"RMSE: {np.sqrt((e**2).mean()):.3f}") |
💬 手計算 (Step 2) と Python 出力が完全一致。
このコードでやること:SSDSE-B-2026 の 2023 年データを読み込み、 高齢化フラグの分類モデルを学習、 混同行列・Precision・Recall・F1・Accuracy を classification_report で一括表示する。
📥 入力:SSDSE-B-2026.csv(564 行 × 112 列)。 2023 年抽出後 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.model_selection import train_test_split from sklearn.metrics import confusion_matrix, classification_report df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] df['aging'] = df['A1303'] / df['A1101'] * 100 df['birth'] = df['A4101'] / df['A1101'] * 1000 df['death'] = df['A4200'] / df['A1101'] * 1000 df['net_in'] = (df['A5101'] - df['A5102']) / df['A1101'] * 1000 y = (df['aging'] >= 32).astype(int) X = df[['birth', 'death', 'net_in']] Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y) m = LogisticRegression(max_iter=1000).fit(Xtr, ytr) print(confusion_matrix(yte, m.predict(Xte))) print(classification_report(yte, m.predict(Xte), target_names=['未進行', '進行'])) |
📤 実行すると次の出力が得られる:
💬 結果の読み方:手計算で確認した通り、 進行クラスの Precision=1.000 / Recall=0.857 / F1=0.923。 全体の accuracy=0.93。 macro avg と weighted avg が出ているのは、 多クラス対応のためで、 2 値でも未進行と進行を平均した値が見える。 ここでは support(サンプル数)が 8 vs 7 で近いので、 macro と weighted はほぼ一致。
このコードでやること:先ほどの LogReg の予測確率から、 roc_curve で TPR・FPR の系列を取り出し、 roc_auc_score で AUC を計算する。 ROC 曲線上の主要点を表示。
📥 入力:先ほどの yte(テスト 15 件のラベル)、 yprob = m.predict_proba(Xte)[:, 1](陽性クラスの予測確率)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import numpy as np from sklearn.metrics import roc_auc_score, roc_curve, precision_recall_curve, average_precision_score yprob = m.predict_proba(Xte)[:, 1] fpr, tpr, thr = roc_curve(yte, yprob) print(f'ROC-AUC = {roc_auc_score(yte, yprob):.3f}') print('ROC 曲線の主要点(FPR, TPR, threshold):') for f, t, h in zip(fpr, tpr, thr): # 先頭の threshold は「どれも陽性にしない」ことを表す番兵で、数値ではない h_txt = '(すべて陰性と判定する点)' if not np.isfinite(h) else f'{h:.3f}' print(f' FPR={f:.3f} TPR={t:.3f} threshold={h_txt}') prec, rec, _ = precision_recall_curve(yte, yprob) print(f'PR-AUC = {average_precision_score(yte, yprob):.3f}') |
📤 実行すると次の出力が得られる(典型例):
💬 結果の読み方:ROC-AUC=0.946 は「ランダム 0.5 / 完璧 1.0」のうち高い水準。 threshold=0.703 で TPR=0.857 / FPR=0.0 まで到達するが、 TPR=1.0 に上げるには FPR=0.375 を許容する必要があり、 完璧分離点は存在しない(AUC が 1.0 でないことと整合)。 PR-AUC=0.957 はさらに高く、 これは陽性クラスの「再現率と適合率」のバランスを直接見るので、 不均衡時に AUC より信頼できる。
| 指標 | 使う場面 | 注意 |
|---|---|---|
| ROC-AUC | クラス均衡時の総合性能 | 不均衡で陽性 1% などだと過大評価される |
| PR-AUC | 不均衡(陽性少数)時の評価 | 「ベースライン」=陽性比率なので比較対象に注意 |
このコードでやること:人口を 3 階層(small / medium / large)に分けた多クラス分類を行い、 f1_score(average='macro') と 'weighted' の違いを比較する。
📥 入力:先ほどの X(47×3)と pd.qcut(df['A1101'], q=3) による 3 クラスラベル y3。
1 2 3 4 5 6 7 8 9 10 11 | from sklearn.metrics import f1_score, precision_score, recall_score df['pop3'] = pd.qcut(df['A1101'], q=3, labels=['small', 'medium', 'large']) y3 = df['pop3'] Xtr, Xte, ytr, yte = train_test_split(X, y3, test_size=0.3, random_state=7, stratify=y3) m3 = LogisticRegression(max_iter=2000).fit(Xtr, ytr) yp = m3.predict(Xte) for avg in ['macro', 'weighted']: print(f'[{avg}] Precision={precision_score(yte, yp, average=avg, zero_division=0):.3f} ' f'Recall={recall_score(yte, yp, average=avg):.3f} F1={f1_score(yte, yp, average=avg):.3f}') |
📤 実行すると次の出力が得られる(典型例):
💬 結果の読み方:3 クラスが完全に均衡(5/5/5)なため、 macro と weighted は一致する。 もし「small=40 / medium=5 / large=2」のような不均衡なら、 weighted は大クラスの結果に引っ張られ、 macro は小クラスを軽視しない。 「少数クラスを軽視したくない」なら macro を見る。 業務で「全クラスを公平に評価したい」場面では macro 必須。
このコードでやること:閾値を 36% に引き上げて陽性 2 / 陰性 45 の不均衡を作り、 「全部陰性予測のダミー」と「学習済 LogReg」で Accuracy / F1 / Recall / PR-AUC を比較。 Accuracy の罠を数字で見る。
📥 入力:先ほどの df。 y_imb = (df['aging'] >= 36).astype(int)。 陽性は秋田・高知の 2 県。
1 2 3 4 5 6 7 8 9 10 11 12 13 | from sklearn.dummy import DummyClassifier from sklearn.metrics import (accuracy_score, f1_score, recall_score, average_precision_score) y_imb = (df['aging'] >= 36).astype(int) print('陽性比率:', y_imb.mean().round(3)) dummy = DummyClassifier(strategy='most_frequent').fit(X, y_imb) log = LogisticRegression(max_iter=1000).fit(X, y_imb) for name, mdl in [('Dummy(全陰性)', dummy), ('LogReg', log)]: yp = mdl.predict(X) print(f'{name:14} Acc={accuracy_score(y_imb,yp):.3f} F1={f1_score(y_imb,yp):.3f} Recall={recall_score(y_imb,yp):.3f}') |
📤 実行すると次の出力が得られる:
💬 結果の読み方:陽性比率 4.3% の強い不均衡データで、 「全陰性」と決めつけるダミーが Accuracy 95.7%。 学習済 LogReg と差は 2 ポイント強しかなく、 Accuracy だけ見ていたら「両方そこそこ」と勘違いする。 F1 を見ると Dummy は 0、 LogReg は 0.667 と決定的な差。 不均衡データでは Accuracy を信用してはいけない。 これが「Accuracy Paradox」の典型。
class_weight='balanced' や SMOTE で陽性側を強化指標を正しく選んでも、 その指標を「どのデータで測ったか」が 揺れていては比較にならない。 この章では評価値自体の不確かさを扱う。
ここまでの指標はすべて「あるテストデータで測った 1 個の数字」だった。 しかし小さいデータでは、 train / test の分け方が変わるだけで数字が大きく動く。 交差検証(cross-validation)は、 データを k 個に分けて 「1 個をテスト・残りを学習」を k 回繰り返し、 全データがちょうど 1 回ずつテストに回る ようにする方法である。 得られるのは 1 個の値ではなく k 個の値で、 その平均と標準偏差を併記するのが基本作法になる。
📥 入力: SSDSE-B-2026 の 2023 年 47 都道府県。 総人口・出生数・消費支出から 「高齢化率が中央値を超えるか」を予測するロジスティック回帰。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | import pandas as pd import numpy as np from sklearn.model_selection import KFold, StratifiedKFold, train_test_split, cross_val_score from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline # このページの他のブロックが使う df / X / y を壊さないよう、 変数名は cv_ で始める cv_df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) cv_d = cv_df[cv_df['SSDSE-B-2026'] == 2023].copy() cv_d['aging_rate'] = cv_d['A1303'] / cv_d['A1101'] * 100 cv_y = (cv_d['aging_rate'] > cv_d['aging_rate'].median()).astype(int).values cv_X = cv_d[['A1101', 'A4101', 'L3221']].astype(float).values pipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000)) # ① ホールドアウト: 分け方を変えると精度がどれだけ動くか accs = [] for seed in range(20): Xtr, Xte, ytr, yte = train_test_split(cv_X, cv_y, test_size=0.3, random_state=seed, stratify=cv_y) accs.append(pipe.fit(Xtr, ytr).score(Xte, yte)) accs = np.array(accs) print('① ホールドアウト(7:3)を 20 通りの分け方で試す') print(f' 精度 最小 {accs.min():.3f} / 最大 {accs.max():.3f} / 平均 {accs.mean():.3f}') print(f' → 同じデータ・同じモデルなのに {accs.max()-accs.min():.3f} も開く') # ② k-fold 交差検証: 全データが 1 回ずつテストに回る print('\n② k-fold 交差検証(k を変える)') for k in (3, 5, 10, len(cv_y)): cv = KFold(k, shuffle=True, random_state=0) if k < len(cv_y) else KFold(k) sc = cross_val_score(pipe, cv_X, cv_y, cv=cv, scoring='accuracy') name = f'k={k}' if k < len(cv_y) else f'k={k} (LOOCV)' print(f' {name:<14} 平均 {sc.mean():.3f} 標準偏差 {sc.std():.3f} ' f'1 fold のテスト件数 {len(cv_y)//k}') # ③ 層化の有無で fold ごとの陽性割合がどう変わるか。 # 均衡データ(陽性 49%)と不均衡データ(人口 300 万人以上 = 陽性 21%)を並べる。 cv_y_imb = (cv_d['A1101'] >= 3_000_000).astype(int).values print('\n③ 層化(Stratified)の効果 — 各 fold のテスト集合に含まれる陽性割合') for label, yy in [('均衡 (陽性 %.0f%%)' % (cv_y.mean()*100), cv_y), ('不均衡(陽性 %.0f%%)' % (cv_y_imb.mean()*100), cv_y_imb)]: print(f' --- {label} ---') for name, cv in [('KFold ', KFold(5, shuffle=True, random_state=0)), ('StratifiedKFold', StratifiedKFold(5, shuffle=True, random_state=0))]: ratios = [yy[te].mean() for _, te in cv.split(cv_X, yy)] print(f' {name}: ' + ' '.join(f'{r:.2f}' for r in ratios) + f' ばらつき {np.std(ratios):.3f}') |
📤 実行するとこの出力が得られる:
💬 結果の読み方: ① が最も重要である。 まったく同じデータ・同じモデルなのに、 7:3 の分け方を変えるだけで 精度が 0.467 〜 0.800 の間で動いた(開き 0.333)。 論文や報告書で「精度 80%」と 書かれていても、 それが 1 回のホールドアウトならたまたま良い分割を引いただけかもしれない。
② では k を変えている。 k を増やすほど 1 fold のテスト件数が減り(k=5 で 9 件、 k=10 で 4 件、 LOOCV では 1 件)、 標準偏差が 0.069 → 0.124 → 0.210 → 0.447 と膨らむ。 とくに LOOCV は各 fold の精度が 0 か 1 しか取らないため標準偏差 0.447 は意味を持たない。 k を大きくすれば良いわけではなく、 n=47 なら k=5 前後が実用的である。
③ は層化の効果。 陽性 49% の均衡データでは KFold と StratifiedKFold に差が無い(ばらつき 0.042 で同じ)。 ところが陽性 21% の不均衡データにすると、 KFold では fold ごとの陽性割合が 0.11 〜 0.33 と 3 倍も振れるのに対し、 StratifiedKFold は 0.20 〜 0.22 に収まる(ばらつき 0.093 → 0.011)。 層化が要るかどうかは、 目的変数の偏りを見てから決める。
評価指標 (evaluation metrics) を中心に、 上 (混同行列 TP/FP/TN/FN)・右上 (Accuracy/Precision/Recall)・右下 (ROC-AUC/PR-AUC)・下 (回帰指標 RMSE/MAE/R²)・左下 (McNemar 検定で 2 モデル差の有意性検定)・左上 (交差検証で汎化評価) の 6 方向に系列を配置した。 分類問題は混同行列 → Accuracy/F1/AUC へと展開し、 回帰問題は RMSE/MAE/R² の選択でロバスト性・解釈性が変わる。 SSDSE-B-2026 の 47 都道府県データのような小サンプルでは交差検証 + Bootstrap で 95% CI を取り、 単一値ではなく区間で比較するのが標準。
評価指標は「課題タイプ × データ条件 × 業務目的」の 3 軸で選ぶ。 上図の階層は「閾値依存 (Accuracy/F1) vs 閾値非依存 (AUC/log-loss)」「クラス不均衡対応有無」「コスト不均等 (誤分類コストが非対称)」の 3 切り口で派生関係を示している。 SSDSE-B-2026 の小サンプル (47 県) では Bootstrap で 95% CI を取り、 単一値ではなく区間で比較するのが標準。
「評価指標」は単独で完結せず、 学習パイプラインの各所と接続することで意味を持つ。 以下に具体的な接続関係を示す。
「評価指標」を中核に据えた分析設計では、 上記の上流の準備と下流の解釈を併せて運用し、 単一指標ではなく主指標 + 補助 2-3 指標 + 不確実性 (CI) を併記する。
「評価指標」をタスクに当てはめる際、 以下の 3 ステップで判定する。 業務コスト構造との整合性が最優先。
このフローは出発点であり、 領域固有のコスト構造 (FN コスト / FP コスト) と運用制約 (リアルタイム性・解釈性) で調整する。
論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ## numpy / scipy だけで混同行列と派生指標を計算 import numpy as np from scipy import stats ## ベルヌーイ分布から擬似テストデータ(実務でも観測される構造) y_true = np.array([1,0,1,1,0,1,0,0,1,0,1,1,0,1]) y_pred = np.array([1,0,1,0,0,1,1,0,1,0,1,0,0,1]) TP = np.sum((y_true==1) & (y_pred==1)) TN = np.sum((y_true==0) & (y_pred==0)) FP = np.sum((y_true==0) & (y_pred==1)) FN = np.sum((y_true==1) & (y_pred==0)) acc = (TP+TN) / len(y_true) prec = TP / (TP+FP) if (TP+FP) > 0 else np.nan rec = TP / (TP+FN) if (TP+FN) > 0 else np.nan f1 = 2*prec*rec / (prec+rec) ## マクネマー検定(2 つのモデル比較に scipy.stats を使う) from scipy.stats import binomtest b = 3; c = 5 ## A正解&B不正解, A不正解&B正解 p = binomtest(b, b+c).pvalue print(f'McNemar p={p:.4f}') |
1 2 3 4 5 6 7 8 9 10 | from sklearn.model_selection import cross_validate from sklearn.ensemble import RandomForestClassifier scoring = ['accuracy', 'precision', 'recall', 'f1', 'roc_auc', 'average_precision', 'neg_log_loss'] results = cross_validate( RandomForestClassifier(n_estimators=200, random_state=42), X, y, cv=5, scoring=scoring, return_train_score=True) for metric in scoring: test_score = results[f'test_{metric}'] print(f'{metric:18s}: {test_score.mean():.3f} ± {test_score.std():.3f}') |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ## ROC 曲線から Youden index 最大の閾値を選ぶ from sklearn.metrics import roc_curve, precision_recall_curve fpr, tpr, thresh = roc_curve(y_te, y_prob) youden = tpr - fpr best_idx = np.argmax(youden) print(f'Best threshold (Youden): {thresh[best_idx]:.3f}') print(f' TPR={tpr[best_idx]:.3f}, FPR={fpr[best_idx]:.3f}') ## PR 曲線から F1 最大の閾値 prec, rec, thresh_pr = precision_recall_curve(y_te, y_prob) f1_scores = 2 * prec * rec / (prec + rec + 1e-9) best_pr = np.argmax(f1_scores[:-1]) print(f'Best threshold (F1) : {thresh_pr[best_pr]:.3f}, F1={f1_scores[best_pr]:.3f}') |
1 2 3 4 5 6 7 8 9 10 11 12 13 | from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score, mean_absolute_percentage_error from scipy.stats import pearsonr, spearmanr y_true = np.array([100, 150, 200, 250, 300]) y_pred = np.array([110, 140, 220, 240, 310]) print(f'MAE : {mean_absolute_error(y_true, y_pred):.2f}') print(f'MSE : {mean_squared_error(y_true, y_pred):.2f}') print(f'RMSE : {np.sqrt(mean_squared_error(y_true, y_pred)):.2f}') print(f'MAPE : {mean_absolute_percentage_error(y_true, y_pred)*100:.2f}%') print(f'R² : {r2_score(y_true, y_pred):.3f}') print(f'Pearson r : {pearsonr(y_true, y_pred)[0]:.3f}') print(f'Spearman ρ: {spearmanr(y_true, y_pred)[0]:.3f}') |
分類だけが評価指標ではありません。 SSDSE-B-2026 の高齢化率(連続値)を、 出生率・死亡率・転入超過率から 回帰 で予測するモデルを作り、 RMSE・MAE・R² を比較します。
このコードでやること:先ほどの特徴量を使って LinearRegression で高齢化率を予測し、 回帰の代表的な評価指標を一覧で表示する。
📥 入力:X(47×3)、 y_reg = df['aging'](連続値、 範囲 22.8〜39.1)。 train/test 7:3 で分割。
1 2 3 4 5 6 7 8 9 10 11 12 | from sklearn.linear_model import LinearRegression from sklearn.metrics import (mean_squared_error, mean_absolute_error, r2_score, mean_absolute_percentage_error) import numpy as np y_reg = df['aging'] Xtr, Xte, ytr, yte = train_test_split(X, y_reg, test_size=0.3, random_state=42) reg = LinearRegression().fit(Xtr, ytr) yp = reg.predict(Xte) print(f'RMSE = {np.sqrt(mean_squared_error(yte,yp)):.3f} MAE = {mean_absolute_error(yte,yp):.3f}') print(f'R^2 = {r2_score(yte,yp):.3f} MAPE= {mean_absolute_percentage_error(yte,yp)*100:.2f}%') |
📤 実行すると次の出力が得られる(典型例):
💬 結果の読み方:RMSE=0.867(パーセントポイント)、 MAE=0.684。 つまり予測高齢化率の平均誤差は約 0.7 pt。 R²=0.941 で「分散の 94% を説明」、 MAPE=2.38% は「相対誤差 3% 以内」。 RMSE は外れ値に敏感(二乗のため)、 MAE は頑健、 R² はスケールフリー、 MAPE は相対誤差。 用途で使い分ける。
| 指標 | 単位 | 外れ値感度 | 使う場面 |
|---|---|---|---|
| RMSE | 元単位と同じ | 高(二乗) | 大きい誤差を強くペナルティ |
| MAE | 元単位と同じ | 低 | 外れ値に頑健、 直感的 |
| R² | 無次元 | 中 | スケール非依存の説明力 |
| MAPE | パーセント | 低 | 相対誤差で報告(売上予測など) |
スライダーや点のドラッグで 数字と図がリアルタイムに更新 されます。 「1 つの指標だけ見ると判断を誤る」「不均衡データでは Accuracy が当てにならない」「回帰では目的に応じて見る物差しが変わる」——この 3 つを手で動かして体感してください。 計算はすべてブラウザ内で正確に行われます(外部通信なし)。
TP / FP / FN / TN の 4 つを動かすと、 Accuracy・Precision・Recall・Specificity・F1 が一斉に更新されます。 プリセットで「不均衡データ」に切り替えると、 Accuracy が高いのに Recall が低い Accuracy パラドックス を再現できます。
| 予測:陽性 | 予測:陰性 | |
| 実際:陽性 | 45 TP | 15 FN |
| 実際:陰性 | 10 FP | 80 TN |
陽性の割合(有病率):—
固定した 30 件のスコア付きサンプル(陽性 15・陰性 15)に対し、 判定しきい値 を動かします。 しきい値を下げると陽性判定が増え、 Recall(=TPR)は上がるが Precision は下がる——その様子が ROC 曲線 と PR 曲線 上の●の移動として見えます。
8 点の予測値(青丸)を 上下にドラッグ(スマホはタッチ)して真値(白丸)からずらすと、 5 つの回帰指標が同時に更新されます。 1 点だけ大きくずらすと、 RMSE と MSE だけが急上昇(二乗のため外れ値に敏感)、 MAE はあまり動かない——目的で見る物差しが変わることを体感してください。
🎯 直感(目的に応じて物差しを選ぶ):評価指標は「体重計・体温計・血圧計」のように 測りたい対象ごとに専用の道具 があります。 「見逃しを減らしたい(がん検診・不正検知)」なら Recall、 「誤検知のコストが高い(迷惑メール判定で正常メールを消したくない)」なら Precision、 両者のバランスなら F1。 回帰でも「大きな外れを強く罰したい」なら RMSE、 「典型的な誤差を頑健に見たい」なら MAE、 「相対誤差で報告したい」なら MAPE と、 目的が物差しを決めます。
⚠️ よくある落とし穴:
① 単一指標依存——上の①で TP を上げ FN を下げると Recall は 1.0 に近づきますが、 同時に FP が増えれば Precision は落ちます。 1 つの数字だけで「良いモデル」と結論するのは危険。 必ず複数指標を併記します。
② 不均衡データでの Accuracy 誤用——「不均衡データ」プリセットを押すと、 陽性がごく稀なため「ほぼ全部を陰性と予測」しても Accuracy は高く出ます(クラス不均衡 参照)。 このとき見るべきは Recall・Precision・F1・PR-AUC です。
③ しきい値固定の罠——②のスライダーが示すとおり、 F1 や Precision はしきい値 t で変わります。 t=0.5 に固定した 1 点だけでモデルを評価せず、 ROC 曲線 / PR 曲線の全体(AUC)で捉えます。
🚀 発展(タスク別指標・複数指標のバランス):多クラスでは macro / micro / weighted 平均で意味が変わり、 ランキングでは nDCG・MAP・MRR、 確率予測では Log Loss・Brier スコア・較正曲線を使います。 実務では「業務 KPI(コスト・売上)」と「統計指標(F1・AUC・RMSE)」のギャップにも注意。 小サンプル(SSDSE-B-2026 の 47 都道府県など)では単一値ではなく 交差検証 + ブートストラップで信頼区間を付けて比較するのが標準です。 関連:混同行列 / Precision-Recall / F1 スコア / RMSE / MAE / MSE / R²(決定係数) / MAPE。
※ このコーナーの数値は指標の挙動を体感するための例示データによる計算です(実データの主張ではありません)。 混同行列・ROC/PR・回帰指標はいずれも本文の定義式どおりにブラウザ内で厳密計算しています。
評価指標とは、 モデルの性能を測る尺度 です。 ただし「性能」は 1 次元ではありません。 分類なら 全体の的中(Accuracy)・当てた予測の正確さ(Precision)・拾い漏れの少なさ(Recall)・その調和(F1)・順位づけ能力(AUC)、 回帰なら 大誤差への厳しさ(RMSE)・典型誤差(MAE)・説明力(R²) と、 測る側面ごとに別の物差しがあります。 体重計と体温計と血圧計を 1 台に統合できないのと同じで、 「1 指標で全部を語る」ことは原理的にできません。
指標選択は 2 段階です。 まず タスク種別(分類 / 回帰 / ランキング / 確率予測)で候補が絞られ、 次に 目的・コスト構造(見逃しが致命的か、 誤検知が致命的か、 相対誤差で比べたいか)で主指標が決まります。 本文の 🎨 直感 章・🔬 深掘り 章の業務シナリオ表がその対応表です。 本補足はその上に「なぜ単一指標が危険か」を 1 枚で押さえ直します。
→ 実務の鉄則は「主指標 1 つ + 補助 2〜3 つ + 不確実性(信頼区間)」の併記。 具体値は下の 📝 補足③ で SSDSE-B-2026 の実測比較として示します。
本文 ⚠️ 6 つの落とし穴 は「指標の計算・報告」に関する罠でした。 ここではさらに一段上、 「指標そのものを目的に据えたときに起こる歪み」 を追記します。 上級者ほど踏みやすい罠です。
本文の総合比較表を補い、 タスク別カタログと複数指標での実測比較を追記します。 各項の詳細ページへは相対リンクを張ります(未整備の概念はテキスト表記)。
タスク:SSDSE-B-2026(2023 年・47 都道府県、 data/raw/SSDSE-B-2026.csv を cp932・skiprows=[1] で読み込み)で、 高齢化率(A1303÷A1101×100)が中央値 31.8% 以上を「高齢化県(陽性)」と定義。 陽性 24/47 県とほぼ均衡。 特徴量は総人口 A1101・出生数 A4101・世帯数 A1301 を標準化。 ベースライン 2 種とロジスティック回帰(5-fold 層化 CV の予測)を 同一データ・同一定義で並べます。
※ 下表は上記 CSV に対する実測値(scikit-learn、 StratifiedKFold(5, shuffle=True, random_state=42)、 特徴量 StandardScaler)。 架空値ではありません。
| モデル | Accuracy | Precision | Recall | F1 | ROC-AUC | MCC |
|---|---|---|---|---|---|---|
| 多数派ベースライン(常に陽性) | 0.511 | 0.511 | 1.000 | 0.676 | — | 0.000 |
| 層化ランダム予測 | 0.511 | 0.529 | 0.375 | 0.439 | — | 0.028 |
| ロジスティック回帰(5-fold CV) | 0.745 | 0.688 | 0.917 | 0.786 | 0.828 | 0.517 |
💬 読み方:多数派ベースラインは F1=0.676 と「一見そこそこ」ですが、 MCC=0.000 が「実質的な識別スキルはゼロ」を暴きます。 F1 は陽性を全部当てれば Recall=1.0 で高く見えるため、 F1 単独では無スキル器を見抜けない——ここが単一指標の危険(補足①)の実例です。 MCC と ROC-AUC を併記して初めて、 ロジスティック回帰(MCC=0.517、 AUC=0.828)が本当に学習できていると分かります。
指標値の差が実力差か偶然かは、 統計的検定で確認します。 2 モデルの分類予測の食い違いには McNemar 検定(不一致セル b, c の対称性を検定)、 交差検証の fold ごとスコア比較には 対応のある検定 / 反復 CV、 指標そのものの区間には bootstrap 信頼区間(本文 🔬 深掘り章で実装済み)を使います。 SSDSE-B-2026 は n=47 と小標本のため、 点推定の差より信頼区間の重なりを見るのが誠実です。 関連:交差検証 / 仮説検定 / クラス不均衡。
各指標の定義・計算・実装は個別ページに詳述しています(用語集内・実在ページのみリンク)。
※ MCC(Matthews 相関係数)・PR-AUC・nDCG / MAP・確率較正(Brier / reliability diagram)は本ページ内で解説しています(個別ページは未整備のためリンクなし)。