Validasi silang stratifikasi

Eval

Validasi silang stratifikasi

まとめ
  • Stratified k-fold menjaga proporsi kelas pada setiap fold, sangat penting untuk data yang tidak seimbang.
  • Bandingkan k-fold stratifikasi dengan k-fold standar untuk melihat perbedaan bias kelas.
  • Catat kiat desain ketika ketidakseimbangan sangat ekstrem dan bagaimana membaca hasilnya di lapangan.
import matplotlib.pyplot as plt
import numpy as np
import japanize_matplotlib
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import KFold, StratifiedKFold, train_test_split
from sklearn.metrics import roc_auc_score

RND = 42

Membangun model dan menjalankan validasi silang #

Dataset percobaan #

n_classes = 10
X, y = make_classification(
    n_samples=210,
    n_classes=n_classes,
    n_informative=n_classes,
    n_features=12,
    n_clusters_per_class=1,
    weights=[0.82, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02],
    random_state=RND,
)
plt.title("Jumlah sampel per kelas pada y")
plt.hist(y)
plt.xlabel("Label")
plt.ylabel("Jumlah")
plt.show()

png

Rasio kelas setelah split #

Kita bagi data, kemudian periksa proporsi kelas pada set pelatihan dan validasi.

StratifiedKFold #

Proporsi kelas tetap seragam di pelatihan maupun validasi.

skf = StratifiedKFold(n_splits=4)
for train_index, valid_index in skf.split(X, y):
    X_train, X_valid = X[train_index], X[valid_index]
    y_train, y_valid = y[train_index], y[valid_index]
    plt.figure(figsize=(8, 2))
    plt.subplot(121)
    plt.title("Data latihan")
    train_label_cnt = [(y_train == i).sum() for i in range(n_classes)]
    plt.ylabel("Jumlah")
    plt.bar(np.arange(n_classes), train_label_cnt)
    plt.subplot(122)
    plt.title("Data validasi")
    valid_label_cnt = [(y_valid == i).sum() for i in range(n_classes)]
    plt.bar(np.arange(n_classes), valid_label_cnt)
    plt.show()

png

KFold biasa #

K-fold standar bisa menghasilkan fold validasi yang sama sekali tidak memuat kelas minoritas tertentu.

kf = KFold(n_splits=4)
for train_index, valid_index in kf.split(X, y):
    X_train, X_valid = X[train_index], X[valid_index]
    y_train, y_valid = y[train_index], y[valid_index]
    plt.figure(figsize=(8, 2))
    plt.subplot(121)
    plt.title("Data latihan")
    train_label_cnt = [(y_train == i).sum() for i in range(n_classes)]
    plt.ylabel("Jumlah")
    plt.bar(np.arange(n_classes), train_label_cnt)
    plt.subplot(122)
    plt.title("Data validasi")
    valid_label_cnt = [(y_valid == i).sum() for i in range(n_classes)]
    plt.bar(np.arange(n_classes), valid_label_cnt)
    plt.show()

png


Pertimbangan praktis #

  • Ketidakseimbangan ekstrem: jika kelas minoritas hanya memiliki sedikit sampel, kombinasikan stratifikasi dengan validasi silang berulang untuk mengurangi variansi.
  • Tugas regresi: discretise target menjadi bin agar StratifiedKFold dapat menjaga distribusi nilai.
  • Kebijakan pengacakan: aktifkan shuffle=True (dengan seed tetap) bila dataset memiliki urutan temporal atau kelompok yang bisa menimbulkan bias.

Stratified k-fold adalah pengganti langsung k-fold ketika keseimbangan kelas menjadi isu utama. Ia menghasilkan split validasi yang lebih adil, menstabilkan metrik seperti ROC-AUC, dan memperbaiki perbandingan antar model pada dataset tidak seimbang.