論文・記事に 「Accuracy」「Precision」「Recall」「F1」「ROC-AUC」「RMSE」「MAE」「MSE」「クロスエントロピー」「交差検証」「混同行列」 として登場する評価指標群。 「モデルの良さ」を客観的に測る道具。 タスクの種類とデータの性質で選び分けます。
論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:
機械学習・統計モデルの「良さ」を測る指標。 タスクの種類(分類 / 回帰 / ランキング / 生成)とデータの性質(クラス不均衡 / 外れ値)に応じて選びます。 「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['年度']==2023] ## 「東日本 vs 西日本」を 2 値ターゲットにする east = ['北海道','青森県','岩手県','宮城県','秋田県','山形県','福島県', '茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県', '新潟県','富山県','石川県','福井県','山梨県','長野県'] df['east'] = df['都道府県'].isin(east).astype(int) X = df[['A1101', 'A4101', 'A6101']].values ## 人口・高齢化率・婚姻件数 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)) |
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 : {mean_squared_error(y_true, y_pred, squared=False):.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}') |