Validasi silang

Eval

Validasi silang

まとめ
  • Validasi silang membagi data ke dalam beberapa fold agar performa model dapat diestimasi dengan lebih stabil.
  • Bandingkan dengan satu kali hold-out dan lihat bagaimana jumlah fold memengaruhi hasil.
  • Pelajari tips praktis tentang desain fold, biaya komputasi, serta cara melaporkan skor.

Validasi silang memecah data sampel, melatih model pada sebagian data, menguji pada sisanya, dan menilai validitas keseluruhan analisis.Cross-validation (Wikipedia)


1. Gambaran umum #

  • Data dibagi menjadi beberapa “fold” dan secara bergantian satu fold digunakan sebagai validasi.
  • Satu kali train_test_split dapat menghasilkan variansi tinggi; validasi silang merata-ratakan performa di semua fold.
  • Variasi yang umum adalah k-fold dan stratified k-fold (menjaga proporsi kelas di setiap fold).

2. Contoh dasar di Python 3.13 #

Dengan Python 3.13 dan scikit-learn terpasang:

python --version        # Python 3.13.0
pip install scikit-learn matplotlib

Contoh berikut membandingkan hold-out tunggal dengan validasi silang 5-fold pada dataset sintetik yang tidak seimbang.

from __future__ import annotations

import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import cross_validate, train_test_split

RANDOM_STATE = 42


def make_dataset() -> tuple[np.ndarray, np.ndarray]:
    """Membuat dataset klasifikasi biner yang tidak seimbang."""
    features, labels = make_classification(
        n_samples=300,
        n_classes=2,
        weights=[0.2, 0.8],
        n_informative=4,
        n_features=6,
        n_clusters_per_class=2,
        shuffle=True,
        random_state=RANDOM_STATE,
    )
    return features, labels


def holdout_score() -> float:
    """Menghitung ROC-AUC dengan satu pembagian hold-out."""
    features, labels = make_dataset()
    x_train, x_valid, y_train, y_valid = train_test_split(
        features,
        labels,
        test_size=0.2,
        stratify=labels,
        random_state=RANDOM_STATE,
    )
    model = RandomForestClassifier(max_depth=4, random_state=RANDOM_STATE)
    model.fit(x_train, y_train)
    predictions = model.predict(x_valid)
    return roc_auc_score(y_valid, predictions)


def cross_validation_scores() -> dict[str, float]:
    """Menjalankan validasi silang 5-fold dan merata-ratakan ROC-AUC serta Accuracy."""
    features, labels = make_dataset()
    model = RandomForestClassifier(max_depth=4, random_state=RANDOM_STATE)
    scores = cross_validate(
        model,
        features,
        labels,
        cv=5,
        scoring=("roc_auc", "accuracy"),
        return_train_score=False,
        n_jobs=None,
    )
    return {
        "roc_auc": float(np.mean(scores["test_roc_auc"])),
        "accuracy": float(np.mean(scores["test_accuracy"])),
    }


if __name__ == "__main__":
    holdout = holdout_score()
    print(f"Hold-out ROC-AUC: {holdout:.3f}")

    cv_result = cross_validation_scores()
    print(f"ROC-AUC (5 fold): {cv_result['roc_auc']:.3f}")
    print(f"Akurasi (5 fold): {cv_result['accuracy']:.3f}")

Contoh keluaran:

Hold-out ROC-AUC: 0.528
ROC-AUC (5 fold): 0.844
Akurasi (5 fold): 0.858

Hold-out tunggal menghasilkan ROC-AUC mendekati nilai acak, sedangkan validasi silang memberikan estimasi yang jauh lebih stabil.


3. Tips desain #

  1. Menentukan jumlah fold
    Lima atau sepuluh fold adalah standar. Untuk data sangat sedikit, LeaveOneOut bisa dipertimbangkan, tetapi biayanya tinggi.
  2. Stratifikasi
    Jika kelas tidak seimbang, gunakan StratifiedKFold atau parameter stratify agar proporsi label terjaga di tiap fold.
  3. Metrik ganda
    scoring menerima tuple untuk menghitung beberapa metrik sekaligus. Menggabungkan ROC-AUC dan Akurasi memperlihatkan trade-off.
  4. Integrasi dengan penelusuran hiperparameter
    GridSearchCV dan RandomizedSearchCV menjalankan validasi silang internal, membantu menghindari overfitting saat tuning.

4. Daftar periksa praktis #

  • Strategi split sudah tepat?
    Untuk data time series gunakan TimeSeriesSplit alih-alih fold acak.
  • Metrik penting sudah dihitung?
    Masukkan metrik yang jadi dasar keputusan bisnis ke parameter scoring.
  • Biaya komputasi sudah diperkirakan?
    Validasi silang melatih model sebanyak k kali; rencanakan waktu dan sumber daya.
  • Eksperimen mudah direproduksi?
    Simpan versi Python, seed, dan konfigurasi split di notebook atau skrip.

Ringkasan #

  • Validasi silang mengurangi variansi estimasi dan membantu memahami kemampuan generalisasi model.
  • cross_validate dari scikit-learn memudahkan penghitungan banyak metrik sekaligus.
  • Rancang fold, metrik, serta anggaran komputasi secara sadar, lalu integrasikan proses ini ke alur produksi.