Pemodelan pada proyek ini bergerak berurutan dari model paling sederhana hingga gradient boosting, dan setiap langkahnya dinilai dengan metrik yang sama pada pembagian data yang sama. Topik ini membahas tahap tersebut, yaitu penentuan baseline, pemilihan metrik penalaan untuk kelas ganas, perbandingan regresi logistik dengan gradient boosting, dan penalaan terarah dua hyperparameter pada data latih. Praktiknya menggunakan skrip baseline-ke-booster.py pada dataset breast cancer dengan data uji 114 baris yang tetap disimpan tanpa disentuh.
Baseline sebagai batas bawah#
Baseline adalah titik tolak sederhana yang memperlihatkan kinerja tanpa kecerdasan apa pun. Model pada tahap ini adalah DummyClassifier dengan strategi kelas terbanyak, yaitu selalu menebak jinak karena kelas jinak paling banyak pada data latih. Baseline ini sengaja dibuat lemah karena tugasnya bukan memprediksi dengan baik, melainkan menetapkan batas bawah yang wajib dilampaui setiap model sungguhan.
Nilai baseline juga sekaligus menguji pilihan metrik. Dengan metrik F1 kelas ganas yang ditetapkan pada definisi masalah, model yang selalu menebak jinak mencetak nilai tepat nol karena tidak pernah memprediksi kelas ganas. Angka nol ini jujur dan informatif. Apabila akurasi yang digunakan, model yang sama justru mencetak angka tinggi tanpa kemampuan apa pun, dan jarak antara baseline dan model sungguhan menjadi kabur. Metrik per kelas membuat baseline tampil sebagaimana adanya.
scikit-learn menyediakan strategi DummyClassifier lain, yaitu uniform untuk tebakan acak merata dan stratified untuk tebakan yang mengikuti proporsi kelas data latih. Kedua strategi itu sesekali menebak kelas ganas, sehingga F1-nya berfluktuasi di atas nol dan batas bawahnya tidak setegas strategi kelas terbanyak. Angka 0.0000 dengan simpangan baku 0.0000 pada keluaran skrip menegaskan pilihan ini, karena tebakan yang sama pada setiap lipatan menghasilkan skor yang sama pula. Model sungguhan yang skornya berada di bawah baseline adalah tanda kekeliruan pada rangkaian data atau penilaian, bukan tanda model yang buruk.
Metrik penalaan dan pembagian lipatan#
Metrik penalaan harus berupa satu angka tunggal agar konfigurasi yang berbeda dapat diranking, dan proyek ini memakai F1 kelas ganas. Dengan sebagai presisi kelas ganas dan sebagai recall-nya, F1 dihitung sebagai berikut.
F1 adalah rata-rata harmonik, sehingga nilai yang rendah pada salah satu komponen menarik nilai akhirnya ke bawah. Model yang banyak melewatkan kasus ganas memiliki recall rendah dan langsung terlihat buruk pada F1, sesuai dengan konsekuensi yang dinyatakan pada definisi masalah. Kelas positif pada perhitungan ini adalah label 0, dan penetapan itu dilakukan sekali melalui make_scorer(f1_score, pos_label=0) lalu dipakai pada seluruh perbandingan.
Penilaian setiap model menggunakan cross-validation lima lipatan yang disusun StratifiedKFold(n_splits=5, shuffle=True, random_state=42). Pembagian berstrata menjaga proporsi kelas pada setiap lipatan, sedangkan pengacakan dengan seed tetap membuat hasilnya dapat direproduksi. Rata-rata lima lipatan jauh lebih stabil daripada satu pemisahan tunggal, dan simpangan baku antarlipatan dilaporkan bersamanya sebagai ukuran lebar fluktuasinya. Satu aturan yang menyertai seluruh tahap ini adalah data uji tetap di luar perhitungan, sebagaimana dirangkum diagram berikut.
Dari regresi logistik ke gradient boosting#
Model kedua adalah regresi logistik yang dibungkus StandardScaler dalam satu pipeline. Penskalaan ini mengikuti temuan EDA tentang skala fitur yang berbeda ribuan kali, dan pemakaian pipeline memastikan statistik penskalaan dihitung ulang pada setiap lipatan dari data latihnya saja. Model ketiga adalah HistGradientBoostingClassifier dengan pengaturan bawaannya, yaitu 100 tahap dengan learning rate 0.1 dan 31 daun per pohon, sebagai wakili keluarga gradient boosting.
"""Dari baseline hingga gradient boosting dengan penalaan terarah."""
from sklearn.datasets import load_breast_cancer
from sklearn.dummy import DummyClassifier
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score, make_scorer
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
data = load_breast_cancer(as_frame=True)
X, y = data.data, data.target
# pembagian yang sama sejak tahap EDA: data uji 20 persen dan tidak disentuh
X_latih, X_uji, y_latih, y_uji = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
# kelas positif ditetapkan sebagai ganas (label 0) sesuai definisi masalah
f1_ganas = make_scorer(f1_score, pos_label=0)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
def nilai_cv(model, nama):
skor = cross_val_score(model, X_latih, y_latih, scoring=f1_ganas, cv=cv)
print(f"{nama:<30} F1 ganas = {skor.mean():.4f} (simpangan baku {skor.std():.4f})")
return skor.mean()
nilai_cv(DummyClassifier(strategy="most_frequent"), "Baseline kelas terbanyak")
nilai_cv(
make_pipeline(StandardScaler(), LogisticRegression(max_iter=5000, random_state=42)),
"Regresi logistik",
)
nilai_cv(HistGradientBoostingClassifier(random_state=42), "HistGB bawaan (100 tahap)")
# penalaan terarah pada dua hyperparameter paling berpengaruh
# dengan anggaran tahap yang dipatok kecil, yaitu 50 tahap
print("Penalaan HistGradientBoosting dengan anggaran 50 tahap:")
terbaik = (None, -1.0)
for learning_rate in (0.05, 0.2):
for max_leaf_nodes in (4, 15):
model = HistGradientBoostingClassifier(
learning_rate=learning_rate,
max_leaf_nodes=max_leaf_nodes,
max_iter=50,
random_state=42,
)
skor = cross_val_score(model, X_latih, y_latih, scoring=f1_ganas, cv=cv)
rata = skor.mean()
print(f" learning_rate={learning_rate:<5} max_leaf_nodes={max_leaf_nodes:<3} "
f"F1 ganas = {rata:.4f}")
if rata > terbaik[1]:
terbaik = ((learning_rate, max_leaf_nodes), rata)
lr, mln = terbaik[0]
print(f"Konfigurasi terpilih : learning_rate={lr}, max_leaf_nodes={mln}")Baseline kelas terbanyak F1 ganas = 0.0000 (simpangan baku 0.0000)
Regresi logistik F1 ganas = 0.9703 (simpangan baku 0.0135)
HistGB bawaan (100 tahap) F1 ganas = 0.9585 (simpangan baku 0.0165)
Penalaan HistGradientBoosting dengan anggaran 50 tahap:
learning_rate=0.05 max_leaf_nodes=4 F1 ganas = 0.9439
learning_rate=0.05 max_leaf_nodes=15 F1 ganas = 0.9404
learning_rate=0.2 max_leaf_nodes=4 F1 ganas = 0.9554
learning_rate=0.2 max_leaf_nodes=15 F1 ganas = 0.9585
Konfigurasi terpilih : learning_rate=0.2, max_leaf_nodes=15Ketiga titik pada tangga pemodelan terbaca jelas dari keluarannya. Baseline berhenti di nol, regresi logistik melompat ke 0.9703, dan gradient boosting bawaan berada di 0.9585 dengan simpangan baku yang lebih lebar. Selisih kedua model sungguhan hanya 0.012, lebih kecil daripada simpangan baku antarlipatan keduanya, sehingga selisih itu tidak cukup untuk menyatakan satu keluarga model mengungguli yang lain pada data sekecil ini. Temuan ini sekaligus mengingatkan bahwa keunggulan gradient boosting bukan sesuatu yang otomatis, karena data yang kecil dan bersih dengan fitur yang sudah dipahami dengan baik memang menjadi wilayah kuat model linear. Proyek tetap melanjutkan penalaan pada HistGradientBoosting sebagai model akhir, dan pembandingan berikutnya menunggu penilaian di data uji.
Penalaan terarah dua hyperparameter#
Penalaan diarahkan pada dua hyperparameter yang paling memengaruhi bentuk model, yaitu learning_rate yang menentukan besarnya koreksi pada setiap tahap dan max_leaf_nodes yang menentukan kompleksitas tiap pohon. Anggaran tahap dipatok kecil pada max_iter=50 agar perbedaan perilaku antarkonfigurasi terlihat, karena dengan anggaran besar, learning rate kecil dapat menyusul pada tahap-tahap akhir dan perbedaannya menjadi samar. Empat kombinasi nilai ditelaah dengan lima lipatan yang sama persis, sehingga perbandingannya berpasangan pada pembagian data yang identik.
Pola hasilnya terbaca dari keluaran skrip. Pada learning rate 0.05, kedua pilihan jumlah daun menghasilkan F1 di sekitar 0.94, yaitu tanda kekurangan pembelajaran karena 50 tahap belum cukup bagi langkah koreksi yang kecil. Menaikkan learning rate ke 0.2 memulihkan skornya, dan kombinasi terbaik tercapai pada 0.9585 dengan 15 daun. Nilai itu sama persis dengan skor model bawaan yang memakai 100 tahap, sehingga penalaan berhasil menemukan konfigurasi yang mencapai kualitas yang sama dengan setengah anggaran tahapnya.
Kesalahan umum#
- Menala hyperparameter sambil memantau skor data uji. Data uji berubah menjadi himpunan validasi terselubung dan penilaian akhirnya kehilangan makna. Seluruh penalaan dijalankan dengan cross-validation pada data latih.
- Membangun jaringan kombinasi besar tanpa arah. Ratusan kombinasi menghasilkan banyak skor yang selisihnya di bawah fluktuasi antarlipatan dan tidak dapat diranking. Penalaan dimulai dari dua atau tiga hyperparameter yang paling memengaruhi model.
- Melupakan penskalaan pada model yang sensitif skala. Regresi logistik tanpa
StandardScalerpada dataset ini berkonvergensi lambat dan koefisiennya tidak setara antarfitur. Model dan penskalaannya dibungkus dalam satupipeline. - Membandingkan model dengan metrik yang berbeda. Dua skor yang dihitung terhadap kelas positif berbeda tidak dapat diranking. Satu metrik tunggal dengan definisi kelas positif yang sama digunakan sejak definisi masalah.
- Menggunakan pembagian lipatan yang berbeda antar-model. Perbedaan skor kemudian bercampur dengan perbedaan pembagian data, sehingga hasilnya tidak berpasangan. Objek
StratifiedKFoldyang sama digunakan ulang untuk setiap model agar perbandingannya adil. - Memilih kombinasi terbaik dari skor yang berdekatan tanpa mempertimbangkan kompleksitas. Dua konfigurasi dengan skor yang hampir sama sebaiknya dimenangkan oleh konfigurasi yang lebih sederhana karena lebih tahan terhadap perubahan data.
Ringkasan#
- Baseline kelas terbanyak mencetak F1 kelas ganas nol dan menetapkan batas bawah yang wajib dilampaui model sungguhan.
- F1 kelas ganas dengan
pos_label=0menjadi satu-satunya metrik pembanding, dan setiap model dinilai dengan cross-validation lima lipatan berstrata pada data latih. - Regresi logistik mencatat 0.9703 dan gradient boosting bawaan 0.9585, dengan selisih yang berada di dalam fluktuasi antarlipatan sehingga tidak dianggap menentukan.
- Penalaan terarah pada
learning_ratedanmax_leaf_nodesmenemukan konfigurasi 0.2 dan 15 daun yang mencapai skor model bawaan dengan setengah anggaran tahapnya.
Referensi#
- sklearn.ensemble.HistGradientBoostingClassifier — scikit-learn
— Dokumentasi model boosting beserta nilai bawaan
learning_rate,max_iter, danmax_leaf_nodes. - sklearn.metrics.make_scorer — scikit-learn
— Dokumentasi pembuatan skor khusus dengan
pos_labeluntuk metrik penalaan. - 3.2. Tuning the hyper-parameters of an estimator — scikit-learn — Panduan resmi penalaan hyperparameter dan pencarian grid.