
精度が上がらない原因の多くは「評価設計の誤り」にあります。
評価は「何点取れたか」を競うものではなく、意思決定に耐えうるか を検証する営みです。
本記事は、回帰/分類/ランキングの 指標選定 → 交差検証 → 閾値/コスト設計 → キャリブレーション → 統計的安定性 → KPI接続 を、現場でそのまま使えるコードとチェックリストでまとめ直しました。プログラミング初学者にも読みやすいよう、コードの狙いと出力の読み方を丁寧に解説します。
この記事で身に付く力
-
タスクとデータ状況に沿った主要指標の選び方(AUC・PR-AUC・MAE など)
-
適切なデータ分割/交差検証とリーク対策(StratifiedKFold / TimeSeriesSplit)
-
閾値最適化とコスト最小化(Youden J・Top-k・損失関数)
-
予測確率のキャリブレーション(Brier・信頼度曲線)
-
ブートストラップで信頼区間(CI)を提示し、差が偶然かを説明できる
-
予測指標をビジネスKPI(Precision@k / Recall@k / コスト)へ橋渡し
モデル評価でやりがちな落とし穴
まずは“事故”の典型パターンを押さえておきましょう。ここを外すと、どれだけ学習を回しても実務で使えません。
- 指標ミスマッチ:不均衡データなのに Accuracy、コストが非対称なのに F1 のみを見る。
- 前処理リーク:標準化やエンコードを全データで
fit→ CV が過大評価。 - テスト濫用:ハイパラ探索にテストを使い回し → 選択バイアス。
- ビジネス非接続:AUC↑ = 利益↑ ではない。意思決定に繋がらない評価。
解決策は「指標の設計 → CV → 閾値/コスト → KPI接続」を型として固定すること。以下で実装と一緒に落とし込みます。
用語メモ(最短で読み解くために)
- Positive / Negative:関心事象(例:離反 = 1)/ 非該当
- TP / FP / FN / TN:混同行列の4要素
- Precision / Recall / F1:適合率 / 再現率 / 調和平均
- ROC-AUC / PR-AUC:しきい値に依存しないランキング力
指標の選び方:タスク別の“最短表”
指標は ビジネスKPIの代理指標 です。迷ったらまずこれで決め打ちし、あとから補助指標で補強します。
| タスク | データ状況 | 推奨主要指標 | 補助指標/補足 |
|---|---|---|---|
| 回帰 | 外れ値あり | MAE | RMSE(外れ値に敏感)、R²(参考) |
| 二値分類(均衡) | バランス良い | AUC + F1 | Accuracyは補助、閾値最適化で業務接続 |
| 二値分類(不均衡) | Positive稀少 | PR-AUC + Recall@k/Precision@k | ROCは楽観的になることあり |
| 多クラス | — | macro-F1 | 混同行列・class-weight |
| ランキング/推薦 | Top-k重要 | MAP@k / nDCG@k | HitRate@k、Coverage |
| 時系列 | 漏洩注意 | MAE/RMSE + TimeSeriesCV | 期間固定の外挿に注意 |
判断基準:KPIとの橋渡し(例:Recall@k ≒ 架電件数の上限、MAE ≒ 平均誤差コスト)。
データ分割と交差検証:正しい比較の土台
「良いモデル」かどうかは分割設計で決まります。特に shuffle/層化 と 未来を覗かない時系列CV は鉄則です。
from sklearn.model_selection import train_test_split, KFold, StratifiedKFold, TimeSeriesSplit
# ホールドアウト(最終報告用のテストは最後に1回)
X\_tr, X\_te, y\_tr, y\_te = train\_test\_split(X, y, test\_size=0.2, stratify=y, random\_state=42)
# KFold(回帰)/ StratifiedKFold(分類)
cv\_cls = StratifiedKFold(n\_splits=5, shuffle=True, random\_state=42)
cv\_reg = KFold(n\_splits=5, shuffle=True, random\_state=42)
# 時系列CV
cv\_ts = TimeSeriesSplit(n\_splits=5)
このコードで何をしている?
- 最終評価用の テスト を先に切り出し固定します(後から一切触らない)。
- 学習と検証は CV(交差検証) で行い、分類ではクラス比を保つため
StratifiedKFoldを使います。 - 時系列では
TimeSeriesSplitを使い、未来の情報が訓練に混ざらない ようにします。
判断基準
-
shuffle=Trueで偶然差を均す -
分類は 層化、時系列は 未来を覗かない
基本評価(分類):混同行列・ROC/PR・レポート
固定閾値 0.5 に縛られず、確率出力 を基準に評価します。
import numpy as np, pandas as pd
from sklearn.metrics import (confusion_matrix, classification_report,
roc_auc_score, roc_curve, precision_recall_curve,
average_precision_score)
proba = model.predict\_proba(X\_te)\[:,1]
pred = (proba >= 0.5).astype(int)
cm = confusion\_matrix(y\_te, pred)
print(pd.DataFrame(cm, index=\["TrueNeg","TruePos"], columns=\["PredNeg","PredPos"]))
print(classification\_report(y\_te, pred, digits=3))
print("ROC-AUC=", roc\_auc\_score(y\_te, proba))
fpr, tpr, thr = roc\_curve(y\_te, proba)
prec, rec, thr2 = precision\_recall\_curve(y\_te, proba)
print("PR-AUC=", average\_precision\_score(y\_te, proba))
このコードで何をしている?
- まず確率
probaを計算し、AUC(ROC/PR) でモデルの並べ替え能力を評価します。 - 参考として 0.5 で二値化し、混同行列 や
classification_reportで誤りの内訳を確認します。
判断基準
- 確率出力 を使い、ROC/PR と 混同行列 を両面チェック。
閾値最適化:Youden J・コスト最小・Top-k
実務では「何件まで架電できるか」「FN は極力避けたい」など、制約と損失が非対称 です。
閾値は業務前提から決める のが正解です。
from sklearn.metrics import roc_curve, confusion_matrix
import numpy as np
proba = model.predict\_proba(X\_te)\[:,1]
fpr, tpr, thr = roc\_curve(y\_te, proba)
# Youden J(tpr - fpr)最大
j = tpr - fpr
thr\_opt = thr\[j.argmax()]
print("Youden best threshold=", float(thr\_opt))
# コスト最適化(例:FPコスト=1, FNコスト=10)
cost\_fp, cost\_fn = 1.0, 10.0
best = (np.inf, 0.5)
for t in np.linspace(0,1,101):
p = (proba >= t).astype(int)
tn, fp, fn, tp = confusion\_matrix(y\_te, p).ravel()
cost = cost\_fp*fp + cost\_fn*fn
best = min(best, (cost, t))
print("Cost-min threshold=", best\[1])
このコードで何をしている?
- Youden J は感度と偽陽性率のバランスをとる基準です。
- コスト最適化 は、FP と FN に価格をつけて 総損失が最小 になる閾値を探します。
Top-k の考え方:リソース上限(例:上位 5% の顧客だけ架電)なら、Precision@k / Recall@k で直接評価・選定します。
キャリブレーション:確率の“当たり”を良くする
ツリー系モデルは確率が歪みがちです(在庫/リスクの見積もりで致命的)。
Brier スコアや 信頼度曲線 を見て、必要なら補正します。
from sklearn.calibration import CalibratedClassifierCV
from sklearn.metrics import brier_score_loss
# 例:確率が偏りがちなツリーモデルをPlattスケーリング
cal\_model = CalibratedClassifierCV(model, method="sigmoid", cv=5).fit(X\_tr, y\_tr)
proba\_cal = cal\_model.predict\_proba(X\_te)\[:,1]
print("Brier(before)", brier\_score\_loss(y\_te, model.predict\_proba(X\_te)\[:,1]))
print("Brier(after) ", brier\_score\_loss(y\_te, proba\_cal))
このコードで何をしている?
- 学習済みモデルを
CalibratedClassifierCVで 後付け校正 し、確率の当たり(Brier の低下)を確認します。
不均衡データ:PR-AUCとTop-k評価
資源が限られる現場では「上位何%に当てるか」が要諦。PR-AUC と Top-k で評価しましょう。
from sklearn.metrics import average_precision_score
import numpy as np
proba = model.predict\_proba(X\_te)\[:,1]
print("PR-AUC=", average\_precision\_score(y\_te, proba))
# Top-k(例:上位5%を営業対象にする)
k = int(len(proba) \* 0.05)
idx = np.argsort(-proba)\[:k]
recall\_at\_k = y\_te.iloc\[idx].mean() # Positive率
print("Recall\@5%:", float(recall\_at\_k))
このコードで何をしている?
- 上位スコア群だけを抽出し、その中にどれだけ Positive を含められたか を確認します(= Recall@k)。
回帰評価:MAE/RMSE/R²とビジネス解釈
回帰では MAE を主役(コスト直結)に据え、RMSE は外れ値感度、R² は参考値として扱います。
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
pred = reg\_model.predict(X\_te)
mae = mean\_absolute\_error(y\_te, pred)
rmse = mean\_squared\_error(y\_te, pred, squared=False)
r2 = r2\_score(y\_te, pred)
print({"MAE": mae, "RMSE": rmse, "R2": r2})
このコードで何をしている?
- MAE は「平均していくら外すか」=金額換算がしやすい。
- RMSE は外れ値の影響を強く受けるため、品質のばらつき を把握できます。
統計的安定性:ブートストラップで信頼区間
「その差は偶然では?」に備えて、信頼区間(CI) を示します。
最短の実装はブートストラップです。
import numpy as np
from sklearn.utils import resample
from sklearn.metrics import roc_auc_score
proba = model.predict\_proba(X\_te)\[:,1]
auc = roc\_auc\_score(y\_te, proba)
aucs = \[]
for \_ in range(500):
idx = resample(np.arange(len(y\_te)), replace=True, random\_state=\_)
aucs.append(roc\_auc\_score(y\_te.iloc\[idx], proba\[idx]))
lo, hi = np.percentile(aucs, \[2.5, 97.5])
print(f"AUC={auc:.3f} (95% CI: {lo:.3f}-{hi:.3f})")
このコードで何をしている?
- 検証セットを復元抽出して AUC を 500 回計算し、ばらつきの幅(95% CI)を示しています。会議で突っ込まれがちな「偶然では?」に正面から答えられます。
モデル比較の検定(考え方)
- McNemar 検定:2 つの分類器で 誤分類の非対称性 を検定(同一サンプルの 0/1 予測を比較)。
- DeLong 検定:AUC の 差の有意性 を検定。
実装はライブラリ依存のため省略。
重要なのは、差が偶然かどうか を「言葉で」添えることです(例:p 値、CI を本文に明記)。
ビジネス接続:KPI・コスト・意思決定
目的はスコアを上げることではなく、KPI を上げること。評価指標を意思決定に翻訳します。
- 営業リソース上限がある:
Recall@kを直接 KPI に。k は架電/配布可能件数。 - 偽陽性が高コスト:コスト曲線または最適閾値(FP:FN の単価設定)で最小化。
- 需要予測/在庫:確率の当たり(キャリブレーション)を重視し、Brier や信頼度曲線を運用ダッシュボードに。
- レポートの型:平均値だけでなく CI と Top-k の数値(例:上位 5% で Recall=0.43, Precision=0.18)を必ず添える。
評価設計から“面接に耐える”ポートフォリオへ
評価が語れるポートフォリオは説得力が段違い。交差検証→閾値→Top-k→CIまで組み込んだ例を、10分LTテンプレで話せるように仕上げましょう。独学で難しい場合はレビュー/質問対応のあるスクール活用も近道です。
・株式会社キカガク:実務再現型の課題設計と出口支援が強い。転職直結に◎
・Tech Academy:質問の速さ×短時間運用で継続しやすい。副業/在宅に◎
TechAcademy データサイエンスコース(受講料:174,600円~ ※更に割引あり)

株式会社キカガク AI人材長期育成コース(受講料:237,600円~)

ミニプロジェクト(提出推奨)
課題:「不均衡データの二値分類で、PR-AUCとRecall@5%を改善し、最小コスト閾値で運用案を提示する」
- CVでベースライン(ロジスティック/ツリーモデル)を比較
- PR-AUC/ROC-AUC、Top-k(5%)を計測
- 閾値最適化(Youden/コスト最小)を実施し、混同行列とコストを報告
- ブートストラップCIで安定性を提示
- READMEにKPI接続(例:架電当たり成約率/人件費)を3行で記載
レビュー観点チェックリスト(コピペ可)
- 指標がタスク/データ状況に合っている
- CVでモデル選択、テスト1回の原則を守っている
- 閾値/コストの設計が明示されている
- CIで安定性を示している
- KPI接続(意思決定への示唆)が書かれている
付録A:ランキング評価(MAP@k / nDCG@k)最短コード
import numpy as np
def apk(actual, pred, k=10):
pred = pred\[:k]
score, hits = 0.0, 0
for i, p in enumerate(pred, start=1):
if p in actual and p not in pred\[:i-1]:
hits += 1
score += hits / i
return score / min(len(actual), k) if actual else 0.0
def mapk(actual\_list, pred\_list, k=10):
return np.mean(\[apk(a, p, k) for a, p in zip(actual\_list, pred\_list)])
付録B:評価レポート1枚の型(テンプレ)
- 目的と指標(PR-AUC / Recall@5% / コスト)
- CV結果(平均±std)
- テスト結果(混同行列/閾値/コスト)
- 安定性(CI)
- 意思決定案(運用・再学習・監視)
FAQ:よくある質問
Q1. Accuracyはいつ使う?
A. 均衡データかつミスのコストが対称なとき。多くの現場では補助的に扱います。
Q2. どの閾値が正解?
A. ユースケース依存。Youdenはクラス重みが同等の仮定。コスト最小/Top-kが実務向き。
Q3. AUCが上がったのに業務が改善しない
A. Top-kや閾値後のPrecision/Recallを確認。営業枠/在庫制約と整合させる。
Q4. テストのCIは必要?
A. 意思決定の確からしさを示すために有用。ブートストラップやDeLongで提示。
この記事から次に読むべきもの(内部リンク)
-
-
【保存版】scikit-learn基礎:回帰・分類・前処理・パイプライン・交差検証を“実務の型”で習得
機械学習で迷子になる最大の理由は、前処理→学習→評価→改善の順番が曖昧なまま個々のアルゴリズムに飛びつくこと。 本記事は、未経験〜初学者が週10時間×2〜3週で到達できるscikit-learnの最短 ...
-
-
【保存版】ハイパーパラメータ入門:Grid/Random/Optunaの実務チューニング完全ガイド
チューニングのゴールは「スコアの数字遊び」ではありません。意思決定に耐える安定した最適化を短時間で作ること。 本記事は未経験〜初学者が週10時間×2週間で、GridSearchCV / Randomi ...
-
-
【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得
基礎文法の次は、実務で毎回出る処理を“型”として覚える段階です。 本記事は、pandas 2.x を前提に、欠損・外れ値・結合・ウィンドウ関数・時系列・カテゴリ処理・集計の自動化・大規模データの分割処 ...
-
-
【保存版】可視化入門:Matplotlib/Plotlyの使い分けと“伝わるグラフ設計”10ステップ
結論:可視化は「きれいに描く」ことではなく、意思決定を動かすための設計です。 本稿では、未経験〜初学者が 週10時間×1〜2週 で、Matplotlib/Plotlyを軸に “伝わるグラフ”の設計と実 ...
-
-
【保存版】データ職のポートフォリオ完全ガイド|再現性・評価・LTまで
ポートフォリオって「作ったものの置き場」でしょ? いいえ。採用側が見たいのは「意思決定に効いた証拠」と「再現性」です。 本ガイドは、未経験〜初学者が週10時間×4〜6週で、テーマ選定→要件定義→データ ...
最近のコメント