📋 このステップで学ぶこと
Accuracy(正解率)の限界
混同行列の詳細な読み方
Precision、Recall、F1-scoreの使い分け
ROC曲線とAUC
マルチクラス分類の評価
不均衡データの対処法(SMOTE、クラス重み付け)
実践:顧客離脱予測プロジェクト
演習問題: 8問
🎯 1. Accuracyだけでは不十分な理由
不均衡データの問題
⚠️ Accuracyの罠
例:がん検査
・がん患者:10人(1%)
・健康な人:990人(99%)
最悪のモデル: 全員を「健康」と予測 → Accuracy = 99%!
でも、がん患者を1人も見つけられていない…
→ Accuracyだけでは不十分!
実例で確認
import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# 不均衡データを生成(陽性1%)
X, y = make_classification(
n_samples=1000,
n_features=20,
n_classes=2,
weights=[0.99, 0.01], # クラス0が99%、クラス1が1%
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# モデル1: 普通のモデル
model_normal = LogisticRegression(random_state=42, max_iter=1000)
model_normal.fit(X_train, y_train)
y_pred_normal = model_normal.predict(X_test)
# モデル2: 全て「0(陰性)」と予測する最悪のモデル
y_pred_worst = np.zeros_like(y_test)
print(“=== 不均衡データでのAccuracy ===”)
print(f”クラスの分布: クラス0={np.sum(y_test==0)}, クラス1={np.sum(y_test==1)}”)
print(f”\n普通のモデル: Accuracy = {accuracy_score(y_test, y_pred_normal):.4f}”)
print(f”最悪のモデル: Accuracy = {accuracy_score(y_test, y_pred_worst):.4f}”)
=== 不均衡データでのAccuracy ===
クラスの分布: クラス0=297, クラス1=3
普通のモデル: Accuracy = 0.9967
最悪のモデル: Accuracy = 0.9900
→ 最悪のモデルでも99%の正解率!
💡 Accuracyが向かない場合
不均衡データ (クラスの比率が偏っている)
コストが非対称 (偽陰性と偽陽性で重要度が異なる)
少数クラスが重要 (がん検出、不正検知など)
📋 2. 混同行列(Confusion Matrix)
混同行列の基本
【混同行列の構造】
予測
陽性 陰性
実 陽性 | TP | FN |
際 陰性 | FP | TN |
TP (True Positive): 真陽性 – 陽性を正しく陽性と予測
FP (False Positive): 偽陽性 – 陰性を誤って陽性と予測
FN (False Negative): 偽陰性 – 陽性を誤って陰性と予測
TN (True Negative): 真陰性 – 陰性を正しく陰性と予測
【具体例:がん検査】
予測がん 予測健康
実際がん | 80 | 20 | ← FN(見逃し)が危険!
実際健康 | 10 | 890 |
↑
FP(誤検出)
実装
from sklearn.metrics import confusion_matrix
# 不均衡データ(陽性10%)
X_real, y_real = make_classification(
n_samples=1000, n_features=20, n_classes=2,
weights=[0.9, 0.1], random_state=42
)
X_train_r, X_test_r, y_train_r, y_test_r = train_test_split(
X_real, y_real, test_size=0.3, random_state=42
)
# モデル訓練
model = LogisticRegression(random_state=42, max_iter=1000)
model.fit(X_train_r, y_train_r)
y_pred_r = model.predict(X_test_r)
# 混同行列
cm = confusion_matrix(y_test_r, y_pred_r)
TN, FP, FN, TP = cm.ravel()
print(“=== 混同行列の内訳 ===”)
print(f”True Negative (TN): {TN:3d} – 陰性を正しく陰性と予測”)
print(f”False Positive (FP): {FP:3d} – 陰性を誤って陽性と予測”)
print(f”False Negative (FN): {FN:3d} – 陽性を誤って陰性と予測”)
print(f”True Positive (TP): {TP:3d} – 陽性を正しく陽性と予測”)
=== 混同行列の内訳 ===
True Negative (TN): 261 – 陰性を正しく陰性と予測
False Positive (FP): 8 – 陰性を誤って陽性と予測
False Negative (FN): 3 – 陽性を誤って陰性と予測
True Positive (TP): 28 – 陽性を正しく陽性と予測
🎯 どの誤りが重要?
がん検査: FN(偽陰性)が最も危険 – がんを見逃す
スパムフィルター: FP(偽陽性)が問題 – 重要なメールを捨てる
📊 3. Precision、Recall、F1-score
それぞれの定義
【Precision(精度、適合率)】
Precision = TP / (TP + FP)
「陽性と予測したもののうち、実際に陽性だった割合」
【Recall(再現率、感度)】
Recall = TP / (TP + FN)
「実際の陽性のうち、正しく陽性と予測できた割合」
【F1-score】
F1 = 2 × (Precision × Recall) / (Precision + Recall)
PrecisionとRecallの調和平均
具体例で理解
from sklearn.metrics import precision_score, recall_score, f1_score, classification_report
precision = precision_score(y_test_r, y_pred_r)
recall = recall_score(y_test_r, y_pred_r)
f1 = f1_score(y_test_r, y_pred_r)
print(“=== 評価指標の計算 ===”)
print(f”混同行列: TP={TP}, FP={FP}, FN={FN}, TN={TN}”)
print(f”\nPrecision = TP/(TP+FP) = {TP}/({TP}+{FP}) = {precision:.4f}”)
print(f”Recall = TP/(TP+FN) = {TP}/({TP}+{FN}) = {recall:.4f}”)
print(f”F1-score = 2×(P×R)/(P+R) = {f1:.4f}”)
print(f”\n=== 解釈 ===”)
print(f”Precision {precision:.2%}: 陽性予測のうち{precision:.1%}が正しい”)
print(f”Recall {recall:.2%}: 実際の陽性の{recall:.1%}を検出”)
print(“\n=== 分類レポート ===”)
print(classification_report(y_test_r, y_pred_r, target_names=[‘Negative’, ‘Positive’]))
=== 評価指標の計算 ===
混同行列: TP=28, FP=8, FN=3, TN=261
Precision = TP/(TP+FP) = 28/(28+8) = 0.7778
Recall = TP/(TP+FN) = 28/(28+3) = 0.9032
F1-score = 2×(P×R)/(P+R) = 0.8358
=== 解釈 ===
Precision 77.78%: 陽性予測のうち77.8%が正しい
Recall 90.32%: 実際の陽性の90.3%を検出
=== 分類レポート ===
precision recall f1-score support
Negative 0.99 0.97 0.98 269
Positive 0.78 0.90 0.84 31
accuracy 0.96 300
macro avg 0.88 0.94 0.91 300
weighted avg 0.97 0.96 0.97 300
💡 どの指標を重視すべき?
重視する指標
使用例
Recall (見逃しを避ける)
がん検査、病気診断、不正検知
Precision (誤検出を避ける)
スパムフィルター、レコメンド
F1-score (バランス)
どちらも重要な場合、迷ったらこれ
📈 4. ROC曲線とAUC
ROC曲線とは?
📊 ROC(Receiver Operating Characteristic)曲線
閾値を変化させたときの性能の変化 を可視化する曲線です。
縦軸: True Positive Rate (TPR) = Recall
横軸: False Positive Rate (FPR) = FP/(FP+TN)
AUC(Area Under the Curve): ROC曲線の下の面積
・AUC = 1.0: 完璧な分類
・AUC = 0.5: ランダム予測
・AUC > 0.8: 良いモデル
ROC曲線の実装
from sklearn.metrics import roc_curve, roc_auc_score
# 予測確率を取得
y_proba = model.predict_proba(X_test_r)[:, 1]
# ROC曲線のデータを計算
fpr, tpr, thresholds = roc_curve(y_test_r, y_proba)
auc_score = roc_auc_score(y_test_r, y_proba)
print(f”=== ROC-AUC ===”)
print(f”AUC Score: {auc_score:.4f}”)
if auc_score > 0.9:
print(“解釈: 非常に優れたモデル”)
elif auc_score > 0.8:
print(“解釈: 良いモデル”)
elif auc_score > 0.7:
print(“解釈: まあまあのモデル”)
else:
print(“解釈: 改善が必要”)
=== ROC-AUC ===
AUC Score: 0.9745
解釈: 非常に優れたモデル
🔍 ROC曲線の読み方
理想的なROC曲線: 左上の角に近づく(TPR高い、FPR低い)、AUCが1.0に近い
ランダム予測: 対角線(y=x)、AUC = 0.5
ROC曲線の利点: 閾値に依存しない、不均衡データでも有効、モデル間の比較がしやすい
PR曲線(Precision-Recall曲線)
from sklearn.metrics import precision_recall_curve, average_precision_score
# PR曲線のデータを計算
precision_curve, recall_curve, thresholds_pr = precision_recall_curve(y_test_r, y_proba)
ap_score = average_precision_score(y_test_r, y_proba)
# ベースライン(陽性の割合)
baseline = np.sum(y_test_r) / len(y_test_r)
print(f”=== Precision-Recall ===”)
print(f”Average Precision (AP): {ap_score:.4f}”)
print(f”Baseline (陽性の割合): {baseline:.4f}”)
=== Precision-Recall ===
Average Precision (AP): 0.8234
Baseline (陽性の割合): 0.1033
💡 ROC曲線 vs PR曲線
項目
ROC曲線
PR曲線
用途
一般的な評価
不均衡データ
軸
TPR vs FPR
Precision vs Recall
推奨
バランスの取れたデータ
陽性が少ない場合
🎯 5. マルチクラス分類の評価
マルチクラスでの評価
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
# Irisデータセット(3クラス)
iris = load_iris()
X_train_i, X_test_i, y_train_i, y_test_i = train_test_split(
iris.data, iris.target, test_size=0.3, random_state=42, stratify=iris.target
)
# モデル訓練
model_iris = RandomForestClassifier(n_estimators=100, random_state=42)
model_iris.fit(X_train_i, y_train_i)
y_pred_i = model_iris.predict(X_test_i)
print(“=== マルチクラス分類レポート ===”)
print(classification_report(y_test_i, y_pred_i, target_names=iris.target_names))
=== マルチクラス分類レポート ===
precision recall f1-score support
setosa 1.00 1.00 1.00 15
versicolor 1.00 1.00 1.00 15
virginica 1.00 1.00 1.00 15
accuracy 1.00 45
macro avg 1.00 1.00 1.00 45
weighted avg 1.00 1.00 1.00 45
📊 平均の計算方法
macro平均: 各クラスの指標を単純平均(全クラスを平等に扱う)
weighted平均: 各クラスのサンプル数で重み付け平均(多いクラスを重視)
micro平均: 全クラスのTP、FP、FNを合計してから計算(Accuracyと同じ)
不均衡データでは: macro平均が推奨
⚖️ 6. 不均衡データの対処法
評価指標を理解したところで、不均衡データにどう対処するか を学びましょう。主に3つのアプローチがあります。
対処法①:サンプリング手法
📊 2つのサンプリング手法
アンダーサンプリング: 多数派クラスのサンプルを減らす
→ メリット:学習時間短縮 / デメリット:情報を捨てる
オーバーサンプリング: 少数派クラスのサンプルを増やす
→ メリット:情報を失わない / デメリット:過学習のリスク
対処法②:SMOTE(合成サンプル生成)
🌟 SMOTE(Synthetic Minority Over-sampling Technique)
少数派クラスの合成サンプルを生成 する手法。単純なコピーではなく、既存サンプル間を補間して新しいデータを作成するため、過学習のリスクが低い 。
# SMOTEの実装
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
# データ分割を先に行う(重要!)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
print(“SMOTE前:”, f”正常={sum(y_train==0)}, 陽性={sum(y_train==1)}”)
# 訓練データだけにSMOTEを適用
smote = SMOTE(random_state=42)
X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)
print(“SMOTE後:”, f”正常={sum(y_train_smote==0)}, 陽性={sum(y_train_smote==1)}”)
# モデル訓練
model = LogisticRegression(random_state=42, max_iter=1000)
model.fit(X_train_smote, y_train_smote)
# テストデータで評価(テストデータはそのまま!)
y_pred = model.predict(X_test)
SMOTE前: 正常=693, 陽性=7
SMOTE後: 正常=693, 陽性=693
⚠️ SMOTEの重要な注意点
必ずtrain_test_split後、訓練データだけにSMOTEを適用!
テストデータにSMOTEを適用すると、実際の性能を正しく測れません。テストデータは「実際の世界」を模擬しているため、不均衡のまま評価するべきです。
対処法③:クラスの重み付け
データを加工せずに、少数派クラスの誤分類ペナルティを大きく する方法です。
# クラスの重み付け(最も簡単な方法)
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
# 方法1: class_weight=’balanced’(自動計算)
model = LogisticRegression(
class_weight=’balanced’, # クラス比率から自動で重みを設定
random_state=42,
max_iter=1000
)
# 方法2: 手動で重みを指定
model = LogisticRegression(
class_weight={0: 1, 1: 10}, # 少数派クラスの重みを10倍
random_state=42,
max_iter=1000
)
# ランダムフォレストでも使用可能
model = RandomForestClassifier(
class_weight=’balanced’,
n_estimators=100,
random_state=42
)
✅ 対処法の選び方
まず試すべき: class_weight=’balanced’(最も簡単)
データが多い場合: アンダーサンプリング
データが少ない場合: SMOTE
重度の不均衡: 複数の手法を組み合わせる
対処法の比較
手法
メリット
デメリット
アンダーサンプリング
学習時間短縮、シンプル
多数派の情報を捨てる
オーバーサンプリング
情報を失わない
過学習のリスク、学習時間増加
SMOTE
過学習リスク低、情報を失わない
外れ値に弱い、学習時間増加
クラス重み付け
データ加工不要、最も簡単
全アルゴリズムで使えるわけではない
💼 7. 実践プロジェクト:顧客離脱予測
複数モデルの比較
import pandas as pd
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier
from xgboost import XGBClassifier
# 顧客離脱データを生成(離脱率25%)
X_churn, y_churn = make_classification(
n_samples=2000, n_features=15, n_informative=10, n_redundant=5,
n_classes=2, weights=[0.75, 0.25], random_state=42
)
X_train_c, X_test_c, y_train_c, y_test_c = train_test_split(
X_churn, y_churn, test_size=0.3, random_state=42, stratify=y_churn
)
# 複数のモデル
models_churn = {
‘Logistic Regression’: LogisticRegression(random_state=42, max_iter=1000),
‘Random Forest’: RandomForestClassifier(n_estimators=100, random_state=42),
‘Gradient Boosting’: GradientBoostingClassifier(n_estimators=100, random_state=42),
‘XGBoost’: XGBClassifier(n_estimators=100, random_state=42, eval_metric=’logloss’)
}
print(“=== モデルの比較 ===\n”)
for name, model in models_churn.items():
model.fit(X_train_c, y_train_c)
y_pred = model.predict(X_test_c)
y_proba = model.predict_proba(X_test_c)[:, 1]
accuracy = accuracy_score(y_test_c, y_pred)
precision = precision_score(y_test_c, y_pred)
recall = recall_score(y_test_c, y_pred)
f1 = f1_score(y_test_c, y_pred)
auc = roc_auc_score(y_test_c, y_proba)
print(f”{name:20s}: Acc={accuracy:.4f}, P={precision:.4f}, R={recall:.4f}, F1={f1:.4f}, AUC={auc:.4f}”)
=== モデルの比較 ===
Logistic Regression : Acc=0.8450, P=0.6667, R=0.6933, F1=0.6797, AUC=0.8912
Random Forest : Acc=0.9017, P=0.8095, R=0.8533, F1=0.8308, AUC=0.9567
Gradient Boosting : Acc=0.9050, P=0.8205, R=0.8533, F1=0.8366, AUC=0.9612
XGBoost : Acc=0.9083, P=0.8293, R=0.8600, F1=0.8444, AUC=0.9645
💼 ビジネス的な解釈
XGBoostが最良: F1=0.8444、AUC=0.9645
Recall 86%: 離脱顧客の86%を事前に検出
Precision 83%: 離脱予測の83%が正しい
閾値を調整することで、ビジネス目標に最適化 できます!
📝 練習問題
問題1
やさしい
混同行列の基本
混同行列で、TP=80、FP=20、FN=10、TN=890 のとき、Precision、Recall、Accuracyを計算してください。
解答を見る
解答
Precision = TP/(TP+FP) = 80/(80+20) = 0.80 (80%)
Recall = TP/(TP+FN) = 80/(80+10) = 0.89 (89%)
Accuracy = (TP+TN)/(TP+FP+FN+TN) = (80+890)/(80+20+10+890) = 0.97 (97%)
問題2
やさしい
評価指標の選択
以下の状況で、どの指標を重視すべきですか?
がん検査(見逃しを避けたい)
スパムフィルター(重要なメールを捨てたくない)
どちらも同程度に重要
解答を見る
正解:1.Recall、2.Precision、3.F1-score
1. Recall: がんを見逃す(FN)のが最も危険なため、Recallを最大化
2. Precision: 重要なメールをスパム扱い(FP)するのが問題なため、Precisionを重視
3. F1-score: PrecisionとRecallのバランスを取る
問題3
ふつう
AUCの解釈
モデルAのAUC=0.75、モデルBのAUC=0.92 のとき、どちらのモデルが優れていますか?また、それぞれのAUCはどのように解釈できますか?
解答を見る
解答
モデルBが優れている(AUC=0.92 > 0.75)
AUCの解釈:
・モデルA(0.75):まあまあのモデル(0.7〜0.8)
・モデルB(0.92):非常に優れたモデル(0.9以上)
AUCの意味:
ランダムに選んだ陽性サンプルと陰性サンプルにおいて、陽性サンプルの予測確率が陰性サンプルより高くなる確率
問題4
ふつう
閾値の調整
閾値を0.5から0.3に下げると、Precision、Recall、FP、FNはそれぞれどうなりますか?
解答を見る
解答
閾値を下げる(0.5→0.3)と、より多くのサンプルを「陽性」と予測します。
Recall:上がる (より多くの陽性を検出できる)
Precision:下がる (誤検出も増える)
FN:減る (見逃しが減る)
FP:増える (誤検出が増える)
つまり: 見逃しを減らしたいなら閾値を下げる、誤検出を減らしたいなら閾値を上げる
問題5
むずかしい
macro平均とweighted平均
3クラス分類で、各クラスのF1-scoreが以下の場合、macro平均とweighted平均を計算してください。
クラスA:F1=0.90、サンプル数=100
クラスB:F1=0.80、サンプル数=50
クラスC:F1=0.60、サンプル数=50
解答を見る
解答
macro平均 = (0.90 + 0.80 + 0.60) / 3 = 0.767
weighted平均 = (0.90×100 + 0.80×50 + 0.60×50) / 200 = (90 + 40 + 30) / 200 = 0.80
解釈:
・macro平均(0.767)は全クラスを平等に評価
・weighted平均(0.80)は多数クラス(A)に引っ張られている
・不均衡データでは、macro平均の方がクラスCの低い性能を反映
問題6
むずかしい
評価指標の実装
乳がんデータセットで、ロジスティック回帰とランダムフォレストを比較し、F1-scoreとAUCで評価してください。
解答を見る
解答
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score, roc_auc_score
# データ
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 2つのモデルを比較
models = {
‘Logistic Regression’: LogisticRegression(max_iter=10000, random_state=42),
‘Random Forest’: RandomForestClassifier(n_estimators=100, random_state=42)
}
print(“=== 乳がんデータセットでの比較 ===”)
for name, model in models.items():
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]
f1 = f1_score(y_test, y_pred)
auc = roc_auc_score(y_test, y_proba)
print(f”{name:20s}: F1={f1:.4f}, AUC={auc:.4f}”)
=== 乳がんデータセットでの比較 ===
Logistic Regression : F1=0.9714, AUC=0.9960
Random Forest : F1=0.9643, AUC=0.9941
結果: ロジスティック回帰がわずかに優れている(F1=0.9714、AUC=0.9960)
問題7
ふつう
SMOTEの適用タイミング
次のコードのうち、正しい SMOTEの使い方を選んでください。
# 選択肢A
smote = SMOTE()
X_resampled, y_resampled = smote.fit_resample(X, y)
X_train, X_test, y_train, y_test = train_test_split(X_resampled, y_resampled)
# 選択肢B
X_train, X_test, y_train, y_test = train_test_split(X, y)
smote = SMOTE()
X_train_resampled, y_train_resampled = smote.fit_resample(X_train, y_train)
解答を見る
正解:B
正しい手順:1. まず train/test に分割 → 2. 訓練データだけにSMOTEを適用 → 3. テストデータはそのまま
選択肢Aが間違いな理由:
分割前にSMOTEを適用すると、データリーケージ が発生します。訓練データとテストデータに同じような合成サンプルが含まれ、過度に楽観的な評価になってしまいます。
問題8
むずかしい
不均衡データ対処法の選択
次のシナリオで、最も適切な対処法を選んでください。
シナリオ: クレジットカード不正検知、データ:正常100万件・不正100件、要件:不正の80%以上を検出したい、制約:学習時間をなるべく短くしたい
A. アンダーサンプリング(正常を100件に減らす)
B. オーバーサンプリング(不正を100万件に増やす)
C. SMOTE(不正を10万件程度に増やす)
D. クラスの重み付け(データはそのまま)
解答を見る
正解:CまたはD(どちらも正解)
Aが不適切: 99.99%の正常データを捨てると、正常なパターンを十分に学習できない
Bが不適切: 学習時間が大幅に増加し、制約を満たせない
Cが適切: 正常データの情報を失わず、学習時間が比較的短い
Dも適切: データを加工しないので最も高速、Recallを高められる
実務では: まずクラスの重み付け(D)を試し、結果が不十分ならSMOTE(C)を試すのが効率的
📝 STEP 17 のまとめ
✅ このステップで学んだこと
Accuracy の限界と不均衡データの問題
混同行列 :TP、FP、FN、TNの理解
Precision :陽性予測の精度
Recall :陽性の検出率
F1-score :PrecisionとRecallのバランス
ROC曲線とAUC :閾値に依存しない評価
マルチクラス分類の評価(macro/weighted平均)
不均衡データの対処法 :SMOTE、クラス重み付け、サンプリング
🎯 評価指標の選び方(まとめ)
状況
推奨指標
バランスの取れたデータ
Accuracy で十分
不均衡データ
F1-score、AUC
偽陰性が致命的(見逃しNG)
Recall を最大化
偽陽性が問題(誤検出NG)
Precision を最大化
モデルの総合比較
AUC
🚀 次のステップへ
Part 4の分類問題とアンサンブル学習が完了しました!次のPart 5では、教師なし学習 を学びます。STEP 18では、クラスタリングの基礎 (K-means、階層的クラスタリング、DBSCAN)から始めます。
❓ よくある質問
Q1. F1-scoreとAUCはどちらを使うべき?
F1-score: 特定の閾値での性能を評価。実際のビジネス判断に近い。
AUC: 全ての閾値での性能を総合評価。モデル間の比較に適している。
推奨: モデル選択にはAUC、最終評価にはF1-scoreを使うことが多い
Q2. 不均衡データでの対策は?
データレベル:
・オーバーサンプリング(SMOTE)
・アンダーサンプリング
アルゴリズムレベル:
・クラス重み付け(class_weight=’balanced’)
・コスト敏感学習
評価レベル:
・F1-score、AUC、PR曲線を使う
Q3. 閾値はどう決める?
方法1: F1-scoreが最大になる閾値を選ぶ
方法2: ビジネス要件に基づいて決める(Recall 90%以上など)
方法3: PR曲線でPrecision=Recallになる点(ブレークイーブンポイント)
コード例:
from sklearn.metrics import f1_score
thresholds = np.arange(0.1, 0.9, 0.1)
f1_scores = [f1_score(y_test, (y_proba >= t).astype(int)) for t in thresholds]
Q4. マルチクラスでAUCを計算するには?
OvR (One-vs-Rest):
roc_auc_score(y_test, y_proba, multi_class='ovr')
OvO (One-vs-One):
roc_auc_score(y_test, y_proba, multi_class='ovo')
推奨: OvRが一般的。不均衡データでは’weighted’パラメータも検討
Q5. classification_reportの読み方は?
各行: クラスごとのPrecision、Recall、F1-score、サポート(サンプル数)
accuracy: 全体の正解率
macro avg: 各クラスの単純平均(不均衡データで有用)
weighted avg: サンプル数で重み付けした平均
注目ポイント: 少数クラスのRecallが低い場合、そのクラスを見逃している可能性
Q6. SMOTEを使うにはどうすればいい?
インストール: pip install imbalanced-learn
Google Colabでは:!pip install imbalanced-learn
使い方の流れ:
1. まずtrain_test_splitでデータを分割
2. 訓練データだけにSMOTEを適用
3. テストデータはそのまま使用(リサンプリングしない)
注意: テストデータにSMOTEを適用すると、実際の性能を正しく測れません
Q7. class_weight=’balanced’は何をしている?
クラスの重みを「サンプル数の逆数」に自動設定します。
weight = n_samples / (n_classes × np.bincount(y))
少数派クラスほど重みが大きくなり、誤分類のペナルティが大きくなります。
メリット: データを加工せずに不均衡に対処できる
対応アルゴリズム: LogisticRegression、RandomForest、SVM、XGBoostなど多数
×
artnasekai
#artnasekai #学習メモ