Keputusan memilih satu dari beberapa model hanya sebagus cara membandingkannya. Perbandingan yang adil menuntut tiga disiplin sekaligus, yaitu baris data yang sama, metrik yang sama, dan pembacaan selisih yang memperhitungkan variasi antar fold. Topik ini mempraktikkan ketiganya dengan membandingkan regresi logistik, pohon keputusan, dan random forest pada dataset breast cancer, lalu menutupnya dengan uji t berpasangan (paired t-test) atas fold yang sama.
Tiga syarat perbandingan yang adil#
Syarat pertama adalah baris uji yang sama. Dua model yang dinilai pada pemisahan berbeda membawa keberuntungan pemisahan masing-masing ke dalam angkanya, sehingga selisih skor mencampur dua sumber sekaligus, yaitu perbedaan model dan perbedaan komposisi data uji. Pemisahan dibuat satu kali dengan train_test_split yang random_state dan stratify-nya dipatok sama, kemudian hasilnya digunakan bersama oleh seluruh kandidat model. Untuk perbandingan antar fold, objek pembagi fold yang sama diberikan kepada setiap model.
Syarat kedua adalah perlakuan preprocessing yang sama. Penskalaan yang dihitung dari data yang berbeda membuat dua model bekerja pada masukan yang tidak sebanding, dan penskalaan yang dihitung dari seluruh data menimbulkan kebocoran. Cara yang paling aman adalah membungkus setiap model beserta transformasinya dalam Pipeline, sehingga statistik transformasi hanya dihitung dari data latih pada setiap percobaan. Struktur ini juga memastikan setiap model dibandingkan tanpa keuntungan tersembunyi dari perlakuan fitur yang berbeda.
Syarat ketiga adalah metrik yang sama beserta ambangnya. Akurasi menerapkan ambang 0.5 secara implisit, sedangkan AUC menilai urutan skor tanpa ambang, sehingga membandingkan akurasi satu model dengan AUC model lain tidak menghasilkan keputusan yang bermakna. Satu metrik dipilih sesuai tujuan masalah, lalu digunakan untuk semua kandidat, dan angka pelengkapnya dilaporkan sebagai informasi tambahan.
Uji t berpasangan atas fold yang sama#
Selisih rata-rata dua skor cross-validation belum cukup untuk menyatakan satu model unggul, karena skor antar fold berayun dan rata-rata kecil dapat berubah urutan pada seed yang berbeda. Uji t berpasangan bekerja pada selisih per fold , dengan dan sebagai skor kedua model pada fold yang sama. Karena kedua model menilai fold yang persis sama, variasi antar fold saling meniadakan, dan yang tersisa adalah konsistensi arah selisihnya. Statistik ujinya adalah
dengan rata-rata selisih per fold, deviasi standar selisih, dan banyaknya fold. Nilai yang kecil menunjukkan selisih yang arahnya konsisten dan bukan hasil keberuntungan beberapa fold saja.
Pembacaannya memerlukan tiga catatan kejujuran. Dengan yang kecil, misalnya lima fold, daya ujinya rendah sehingga selisih yang nyata pun dapat gagal melewati taraf 0.05. Fold-fold tersebut juga saling bertumpuk karena data latihnya berbagi baris, sehingga uji ini lebih tepat dibaca sebagai perkiraan, bukan pengujian yang bersih secara statistik. Karena itu rata-rata, deviasi standar, dan nilai dilaporkan sebagai satu kesatuan, bukan nilai saja.
Praktik: tiga model pada data yang sama#
Skrip bandingkan-model.py menyiapkan tiga fungsi model, yaitu pipeline StandardScaler dan LogisticRegression, DecisionTreeClassifier berkedalaman empat, serta RandomForestClassifier dengan 100 pohon, semuanya dengan random_state=42. Satu pemisahan data uji digunakan bersama, kemudian StratifiedKFold lima fold yang sama diberikan kepada cross_val_score ketiga model. Pada akhirnya, ttest_rel dari scipy menguji berpasangan dua model teratas, yaitu regresi logistik dan random forest. Skrip dijalankan dari direktori topiknya dengan python3 -B bandingkan-model.py.
"""Membandingkan tiga model pada pemisahan, fold, dan metrik yang sama."""
from scipy.stats import ttest_rel
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier
X, y = load_breast_cancer(return_X_y=True)
def logreg():
return make_pipeline(StandardScaler(), LogisticRegression(max_iter=5000))
def pohon():
return DecisionTreeClassifier(max_depth=4, random_state=42)
def hutan():
return RandomForestClassifier(n_estimators=100, random_state=42)
kandidat = [
("regresi logistik", logreg),
("pohon keputusan ", pohon),
("random forest ", hutan),
]
# pemisahan yang sama untuk ketiga model
X_latih, X_uji, y_latih, y_uji = train_test_split(
X, y, test_size=0.20, random_state=42, stratify=y
)
print("Akurasi satu pemisahan yang sama (random_state=42):")
for nama, buat in kandidat:
akurasi = buat().fit(X_latih, y_latih).score(X_uji, y_uji)
print(f" {nama}: {akurasi:.4f}")
# fold yang sama untuk ketiga model
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
print()
print("Akurasi per fold pada cross-validation yang sama:")
print(f" {'model':<18}" + "".join(f" fold {i}" for i in range(1, 6)) + " rata-rata")
skor_semua = {}
for nama, buat in kandidat:
skor = cross_val_score(buat(), X, y, cv=cv)
skor_semua[nama.strip()] = skor
baris = "".join(f" {s:.4f}" for s in skor)
print(f" {nama:<18}{baris} {skor.mean():.4f}")
# uji t berpasangan atas dua model dengan rata-rata terbaik
t_stat, p_nilai = ttest_rel(skor_semua["regresi logistik"], skor_semua["random forest"])
print()
print("Uji t berpasangan, regresi logistik vs random forest:")
print(f" t = {t_stat:.4f}, p = {p_nilai:.4f}")Akurasi satu pemisahan yang sama (random_state=42):
regresi logistik: 0.9825
pohon keputusan : 0.9386
random forest : 0.9561
Akurasi per fold pada cross-validation yang sama:
model fold 1 fold 2 fold 3 fold 4 fold 5 rata-rata
regresi logistik 0.9737 0.9474 0.9649 0.9912 0.9912 0.9737
pohon keputusan 0.9561 0.8684 0.9211 0.9298 0.9381 0.9227
random forest 0.9649 0.9386 0.9561 0.9474 0.9735 0.9561
Uji t berpasangan, regresi logistik vs random forest:
t = 2.5865, p = 0.0609Pada satu pemisahan tunggal, regresi logistik tercatat 0.9825 dan unggul 2.64 poin persentase atas random forest, selisih yang tampak cukup untuk langsung dijadikan dasar keputusan. Tabel cross-validation pada fold yang sama menyajikan pembacaan yang lebih hati-hati, yaitu rata-rata 0.9737 berbanding 0.9561, sehingga keunggulannya menyusut menjadi 1.76 poin persentase. Urutan keduanya tetap sama pada pemisahan ini, tetapi tabel juga memperlihatkan ayunan antar fold, misalnya skor pohon yang jatuh ke 0.8684 pada fold kedua.
Uji t berpasangan melengkapi pembacaan tersebut. Nilai t 2.5865 dengan p 0.0609 menyertai selisih yang positif pada kelima pasangan fold, tetapi lima pasangan belum cukup untuk melewati taraf 0.05. Kesimpulan yang jujur adalah regresi logistik tampak unggul atas random forest pada data ini. Namun, bukti dari lima fold belum kuat untuk menyatakan keunggulan itu pasti. Keputusan dapat ditunda sampai tersedia lebih banyak fold atau pengulangan cross-validation.
Kesalahan umum#
- Membandingkan model pada pemisahan berbeda karena dieksekusi di tempat terpisah dengan seed berbeda. Selisih yang terbaca mencampur perbedaan model dengan keberuntungan pemisahan. Perbaikannya adalah membuat satu objek pemisahan atau pembagi fold, lalu memberikannya kepada semua kandidat.
- Membandingkan metrik yang berbeda, misalnya akurasi lawan AUC, karena keduanya mengukur hal yang berbeda pada skala yang berbeda. Satu metrik dipilih sesuai tujuan masalah dan digunakan untuk seluruh kandidat.
- Menyatakan satu model unggul dari selisih tipis tanpa uji apa pun. Selisih 0.0176 pada lima fold masih berpeluang berasal dari kebetulan, seperti p 0.0609 pada praktik di atas. Selisih dilaporkan bersama sebarannya dan diuji berpasangan sebelum dinyatakan konsisten.
- Menerapkan uji berpasangan pada skor yang tidak berpasangan.
ttest_relmengasumsikan kedua deret skor berasal dari fold yang sama, sedangkan skor dari pembagi fold berbeda tidak memiliki pasangan yang sah. Pembagi fold yang sama diberikan kepada kedua model sebelum uji dijalankan. - Menguji setiap pasangan model lalu melaporkan pasangan dengan p terkecil. Makin banyak pasangan yang diuji, makin besar peluang satu pasangan meloloskan taraf 0.05 karena kebetulan semata. Pasangan yang diuji ditetapkan lebih dahulu sesuai pertanyaan perbandingannya.
Ringkasan#
- Perbandingan yang adil menuntut baris uji, preprocessing, dan metrik yang sama, dan pipeline per model menjaga dua syarat pertama.
- Uji t berpasangan menghitung selisih pada fold yang sama, sehingga variasi antar fold tidak dihitung dua kali.
- Hasil praktiknya, regresi logistik unggul 1.76 poin persentase atas random forest pada rata-rata lima fold, tetapi p 0.0609 belum melewati taraf 0.05.
- Selisih yang tipis dilaporkan bersama sebaran dan hasil ujinya, bukan sebagai kemenangan yang pasti.
Referensi#
- sklearn.model_selection.cross_val_score — scikit-learn — Dokumentasi penilaian model pada fold yang sama untuk semua kandidat.
- sklearn.model_selection.train_test_split — scikit-learn
— Dokumentasi pemisahan dengan
stratifydanrandom_stateyang dipatok sama. - scipy.stats.ttest_rel — SciPy — Dokumentasi uji t dua sampel berpasangan yang dipakai pada praktik.