Sepanjang section ini kita merakit perkakas satu per satu: diagnosis overfitting, kerangka bias-variance, dropout, weight decay, early stopping, data augmentation, transfer learning, dan fine-tuning. Sebelum melangkah ke section berikutnya, kita perlu menyatukan semuanya dalam satu kerangka yang menjawab tiga pertanyaan: apa sebenarnya generalisasi itu, alat mana yang dipakai pada situasi mana, dan bagaimana angkanya diukur secara jujur. Pertanyaan terakhir sering diremehkan — satu angka akurasi dari satu pembagian acak bisa bergoyang delapan poin hanya karena keberuntungan pembagian. Chapter penutup ini merangkum kotak perkakasnya, lalu mengujinya lewat k-fold cross validation yang berjalan nyata di mesin ini.
Apa Itu Generalisasi #
Generalisasi adalah kemampuan model berperforma baik pada data baru yang diambil dari distribusi yang sama dengan data latih — bukan pada data latih itu sendiri. Data latih hanya menjadi sarana; yang dinilai adalah perilaku model di luar sarana tersebut. Tiga subset memegang peran yang tidak boleh saling menggantikan:
- Data latih — bahan yang boleh dihafal; performa di atasnya tidak bermakna sebagai bukti kualitas.
- Data validasi — perkiraan generalisasi selama model masih kita utak-atik; dipakai berulang untuk memilih arsitektur, learning rate, dan kapan berhenti.
- Data test — perkiraan generalisasi yang hanya dipakai sekali di akhir, setelah semua keputusan selesai.
Kotak Perkakas dari Section Ini #
| Chapter | Alat | Kapan dipakai |
|---|---|---|
| Overfitting dan Underfitting | diagnosis kurva latih vs validasi | membaca gap sejak epoch pertama, tiap eksperimen |
| Bias-Variance | kerangka kompromi kompleksitas | menentukan arah perbaikan: kapasitas atau data |
| Dropout | regularisasi layer | jaringan lebar dengan banyak parameter |
| Weight Decay | penalti norma bobot | default pada optimizer modern seperti AdamW |
| Early Stopping | hentikan latih tepat waktu | hampir selalu; murah dan tidak bertabrakan dengan alat lain |
| Data Augmentation | perluas data latih | data gambar/audio, label mahal |
| Transfer Learning | pakai ulang fitur pretrained | data kecil, tugas serumpun tugas asal |
| Fine-Tuning | buka body dengan lr kecil | tugas bergeser dari tugas asal |
Kedelapan alat tersebut bekerja pada empat sisi yang berbeda — peta berikut memetakan posisi masing-masing:
Alat-alat pada sisi data dan model saling melengkapi, bukan saling menggantikan: augmentasi menutup kekurangan jumlah, transfer learning menutup kekurangan label, dropout dan weight decay menekan kelebihan kapasitas, dan early stopping menjaga keduanya agar tidak berlatih terlalu jauh. Sisi pengukuran berdiri di atas semuanya — tanpa pengukuran yang jujur, kita bahkan tidak tahu alat mana yang sedang berhasil.
Satu Angka Bisa Bergoyang #
Berkas generalisasi_cv.py mendemonstrasikan bahaya satu pembagian tunggal, lalu memakai cross_val_score
untuk pengukuran yang lebih stabil. Dataset sintetis berisi 300 sampel dan 8 fitur; dua kandidat model dibandingkan — LogisticRegression dengan batas keputusan linier versus DecisionTreeClassifier tanpa batas kedalaman yang cenderung menghafal:
"""Mengukur generalisasi: satu pembagian vs k-fold cross validation.
Dataset sintetis make_classification 300 sampel, 8 fitur, 2 kelas.
Bagian 1 menunjukkan betapa bergantungnya satu angka test pada pembagian
acak. Bagian 2 memakai cross_val_score 5-fold untuk membandingkan dua
model: LogisticRegression (batas linier) vs DecisionTree tanpa batas
kedalaman (cenderung menghafal data latih).
"""
import numpy as np
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.tree import DecisionTreeClassifier
X, y = make_classification(
n_samples=300, n_features=8, n_informative=4, n_redundant=2,
random_state=42,
)
print(f"dataset : make_classification, {X.shape[0]} sampel, {X.shape[1]} fitur")
# ---------- 1. Satu pembagian = satu perkiraan ----------
print("\nsatu pembagian acak (75% latih / 25% test), DecisionTree:")
for seed in (0, 7, 21):
X_latih, X_test, y_latih, y_test = train_test_split(
X, y, test_size=0.25, random_state=seed
)
model = DecisionTreeClassifier(random_state=42)
model.fit(X_latih, y_latih)
akurasi = model.score(X_test, y_test)
print(f" random_state={seed:2d} -> akurasi test {akurasi:.3f}")
# ---------- 2. k-fold cross validation ----------
print("\n5-fold cross validation (cv=5, data dipakai bergilir):")
model_linier = LogisticRegression(max_iter=1000)
model_pohon = DecisionTreeClassifier(random_state=42)
for nama, model in (
("LogisticRegression", model_linier),
("DecisionTree (tanpa pruning)", model_pohon),
):
skor = cross_val_score(model, X, y, cv=5)
print(f" {nama:28s} fold {np.round(skor, 3)}")
print(f" {'':28s} mean {skor.mean():.3f} +- {skor.std():.3f}")
# ---------- 3. Gap latih vs cross validation ----------
model_pohon.fit(X, y)
akurasi_latih = model_pohon.score(X, y)
skor_pohon = cross_val_score(model_pohon, X, y, cv=5)
print(f"\nDecisionTree pada data latih penuh : {akurasi_latih:.3f}")
print(f"DecisionTree rata-rata cross val : {skor_pohon.mean():.3f}")
print(f"gap generalisasi : {akurasi_latih - skor_pohon.mean():.3f}")Output yang Dihasilkan:
dataset : make_classification, 300 sampel, 8 fitur
satu pembagian acak (75% latih / 25% test), DecisionTree:
random_state= 0 -> akurasi test 0.800
random_state= 7 -> akurasi test 0.720
random_state=21 -> akurasi test 0.800
5-fold cross validation (cv=5, data dipakai bergilir):
LogisticRegression fold [0.717 0.733 0.717 0.767 0.767]
mean 0.740 +- 0.023
DecisionTree (tanpa pruning) fold [0.783 0.833 0.867 0.9 0.833]
mean 0.843 +- 0.039
DecisionTree pada data latih penuh : 1.000
DecisionTree rata-rata cross val : 0.843
gap generalisasi : 0.157Mari kita telaah kode di atas baris per baris:
- Baris 16-19 (
make_classification): membangkitkan 300 sampel 8 fitur — 4 fitur informatif dan 2 redundan — denganrandom_state=42agar dataset identik di setiap eksekusi. - Baris 23-31 (satu pembagian): model dan data persis sama; hanya
random_statepembagian yang berganti 0 → 7 → 21, dan akurasi test bergoyang 0.800 → 0.720 → 0.800 — selisih 0.08 murni dari komposisi 75 sampel test yang kebetulan terambil. - Baris 35-36 (dua kandidat):
LogisticRegression(max_iter=1000)mewakili model berbatas linier;DecisionTreeClassifiertanpa batas kedalaman tumbuh sampai tiap lembar data latih murni — kandidat alami untuk menghafal. - Baris 42-44 (
cross_val_score):cv=5membagi data menjadi 5 lipatan; setiap lipatan bergiliran menjadi test sementara empat sisanya menjadi latih, lalu lima skor dilaporkan beserta mean dan simpangannya. - Baris 47-52 (gap generalisasi): pohon yang sama difit pada seluruh data mencetak 1.000 — bukti hafalan sempurna — sementara rata-rata cross validation hanya 0.843; gap 0.157 adalah ukuran langsung komponen hafalan dalam performa model.
Membaca Angka: Mean, Simpangan, dan Gap #
Tiga lapis informasi muncul dari keluaran di atas. Pertama, satu pembagian tunggal menilai DecisionTree antara 0.720 dan 0.800 — bandingkan dengan mean cross validation 0.843 ± 0.039 yang jauh lebih stabil karena setiap sampel ikut teruji tepat sekali. Kedua, DecisionTree memang mengungguli LogisticRegression (0.843 vs 0.740) — dataset ini tidak berbatas linier, jadi kapasitas pohon membantu. Ketiga, gap 1.000 − 0.843 = 0.157 memperingatkan bahwa sebagian performa pohon berasal dari hafalan; pohon dengan kedalaman dibatasi atau dengan pruning kemungkinan mempertahankan sebagian besar akurasi dengan gap jauh lebih kecil. Mean memberi tahu seberapa baik, simpangan memberi tahu seberapa percaya diri, dan gap memberi tahu seberapa banyak yang dihafal — ketiganya dibutuhkan sebelum mengambil keputusan. Mekanisme lengkap k-fold beserta variasinya (stratified, leave-one-out, grouped) didokumentasikan di scikit-learn.org/stable/modules/cross_validation.html .
Domain Shift: Batas dari Semua Pengukuran #
Seluruh pengukuran di atas bertumpu pada satu asumsi: data baru berasal dari distribusi yang sama dengan data latih. Dunia nyata sering melanggar asumsi tersebut — kamera berbeda pada data inferensi, populasi pengguna yang bergeser, atau perubahan musim pada data sensor. Pada situasi domain shift, angka cross validation yang meyakinkan sekalipun tidak menjamin performa di lapangan; pengujian perlu dilakukan ulang pada data dari domain baru tersebut. Diagnosis dan mitigasi domain shift dibahas khusus pada Chapter Robustness dan Distribution Shift di section Keamanan, Etika, dan Keandalan.
Dengan definisi yang jelas, peta alat yang lengkap, dan pengukuran yang jujur, kita kini siap meninggalkan pertanyaan “apakah model ini menggeneralisasi dengan baik” dan melangkah ke pertanyaan berikutnya: bagaimana mengevaluasi model secara menyeluruh dan menelusuri letak kesalahannya — fokus section Evaluasi dan Debugging Model .