Model yang baru selesai dilatih hampir selalu tampak mengesankan pada data yang dipakai melatihnya. Pertanyaan evaluasi yang sesungguhnya bukan “seberapa akurat model pada data latih?”, melainkan “bisakah kita memercayai model ini pada data yang belum pernah dilihat?”. Chapter ini meletakkan tiga prinsip fondasi bagi seluruh section: akurasi latih nyaris tidak berarti, generalisasi adalah tujuan sebenarnya, dan data uji hanya boleh disentuh satu kali. Ketiga prinsip tersebut akan kita lihat bekerja dalam angka lewat satu contoh KNN yang sengaja dibuat terlalu rajin menghafal.

Mengapa Akurasi Latih Nyaris Tidak Berarti #

Bayangkan seorang siswa yang menempel jawaban ujian tahun lalu di mejanya, lalu mendapat nilai sempurna saat ujian yang sama diulang. Nilai tersebut tidak mengatakan apa-apa tentang pemahamannya; nilai tersebut hanya mengukur kemampuan mengingat. Model machine learning memiliki cara menghafal yang serupa, dan algoritme k-nearest neighbors (KNN) dengan n_neighbors=1 adalah contoh paling gamblang: setiap titik latih adalah tetangga terdekat dari dirinya sendiri, sehingga prediksi pada data latih selalu tepat. Akurasi latih model tersebut akan membaca 1.000 pada masalah apa pun, termasuk masalah yang mustahil dipelajari.

Masalahnya bukan sekadar KNN. Model dengan kapasitas cukup besar — pohon keputusan yang tumbuh penuh, polynomial berderajat tinggi, jaringan saraf dengan parameter melimpah — hampir selalu bisa menekan galat latih mendekati nol karena model tersebut cukup fleksibel untuk menghafal seluruh data, termasuk deraunya. Angka yang indah di data latih dengan demikian mengukur kemampuan mengingat, bukan kemampuan menalar pola.

Generalisasi: Tujuan Evaluasi yang Sesungguhnya #

Tujuan melatih model adalah generalisasi: performa yang terjaga pada data baru yang berasal dari distribusi serupa, misalnya transaksi esok hari, pasien baru minggu depan, atau sensor yang terus memancarkan pembacaan. Evaluasi adalah prosedur untuk menjawab satu pertanyaan itu secara jujur: “bisakah model ini dipercaya pada data baru?”. Seluruh alat yang akan kita bahas di section ini — holdout, cross-validation, confusion matrix, precision-recall, hingga kurva pembelajaran — pada dasarnya adalah cara yang semakin hati-hati untuk mengaproksimasi pertanyaan tersebut tanpa menipu diri sendiri.

Tiga Peran Dataset: Latih, Validasi, dan Uji #

Praktik yang sehat membagi data ke dalam tiga peran yang berbeda. Pembagian ini terasa formalistis pada awalnya, tetapi menjadi penentu kejujuran seluruh laporan performa model.

SubsetPeranAnalogiSeberapa sering dipakai
Data latih (training)Bahan belajar model lewat fit()Buku latihan soalBebas, berulang-ulang
Data validasi (validation)Menilai kandidat model, memilih hyperparameterTry-out sebelum ujianBerkali-kali, tetapi di luar fit()
Data uji (test)Ujian akhir setelah semua keputusan selesaiUjian akhirSekali saja, di paling akhir

Data validasi dan data uji sama-sama tidak dipakai melatih model, tetapi keduanya berbeda nasib: data validasi boleh dipakai berulang kali untuk membandingkan kandidat, sedangkan data uji harus diperlakukan seperti amplop tertutup yang hanya dibuka satu kali. Skor pada data uji adalah satu-satunya angka yang pantas dilaporkan sebagai perkiraan performa di dunia nyata.

Akurasi Latih vs Akurasi Uji dalam Angka #

Mari kita buktikan prinsip di atas dengan satu eksperimen kecil. Kita latih dua model KNN pada data yang sama: k=1 yang menghafal setiap titik, dan k=15 yang memutuskan lewat mayoritas lima belas tetangga sehingga prediksinya lebih halus.

python
# Akurasi pada data latih bukan bukti model bisa menggeneralisasi.
# KNN dengan k=1 menghafal tiap titik latih; KNN dengan k=15
# mengambil suara mayoritas 15 tetangga sehingga prediksi lebih halus.

from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

# Data sintetis tetap: 120 sampel, 2 fitur, kelas cukup tumpang tindih.
X, y = make_classification(
    n_samples=120,
    n_features=2,
    n_informative=2,
    n_redundant=0,
    n_clusters_per_class=2,
    flip_y=0.18,
    class_sep=1.0,
    random_state=42,
)

# Satu split tunggal: 70% latih, 30% uji (ujian akhir, disentuh sekali).
X_latih, X_uji, y_latih, y_uji = train_test_split(
    X, y, test_size=0.3, stratify=y, random_state=42
)

for k in (1, 15):
    model = KNeighborsClassifier(n_neighbors=k)
    model.fit(X_latih, y_latih)
    akurasi_latih = accuracy_score(y_latih, model.predict(X_latih))
    akurasi_uji = accuracy_score(y_uji, model.predict(X_uji))
    print(
        f"KNN k={k:2d} : akurasi latih = {akurasi_latih:.3f} ,"
        f" akurasi uji = {akurasi_uji:.3f}"
    )

Output yang Dihasilkan:

text
KNN k= 1 : akurasi latih = 1.000 , akurasi uji = 0.806
KNN k=15 : akurasi latih = 0.786 , akurasi uji = 0.917

Mari kita telaah baris-baris kode yang berperan penting:

  1. Baris 11–20 (X, y = make_classification(...)): data sintetis dibuat dengan random_state=42 sehingga hasilnya selalu sama. Parameter flip_y=0.18 sengaja menukar label 18% sampel agar kelas saling tumpang tindih — kondisi realistis ketika menghafal mulai terlihat menjanjikan.
  2. Baris 23–25 (train_test_split(...)): 30% data disisihkan sebagai data uji. Parameter stratify=y menjaga proporsi kelas di kedua sisi split; random_state=42 membuat pembagian ini bisa direproduksi.
  3. Baris 27–29 (for k in (1, 15)): kedua model dilatih pada data latih yang identik; satu-satunya perbedaan adalah jumlah tetangga yang dimintai suara.
  4. Baris 30–31 (akurasi_latih dan akurasi_uji): akurasi diukur pada dua kumpulan berbeda — data yang dipakai belajar dan data yang belum pernah dilihat model.

Perhatikan pembalikan yang terjadi pada output. Model k=1 mencetak akurasi latih 1.000 — sempurna karena model tersebut menghafal — tetapi akurasi ujinya paling rendah di antara keduanya. Model k=15 justru tampil lebih sederhana pada data latih (akurasi latih lebih rendah), namun jauh lebih bisa dipercaya pada data baru. Jika kita memilih model berdasarkan skor latih, kita akan memilih model yang lebih buruk untuk produksi. Inilah inti bab ini dalam dua baris angka: skor latih mengukur hafalan, skor uji mengaproksimasi generalisasi.

Ketika Data Uji Disentuh Berulang Kali #

Bahaya kedua setelah percaya akurasi latih adalah kebiasaan memakai data uji sebagai tempat mencoba-coba. Skenarionya lazim: kita menguji 50 varian model ke data uji, lalu melaporkan varian dengan skor uji tertinggi. Secara statistik, kita baru saja memilih varian yang paling beruntung pada satu set ujian — dan skor “terbaik” tersebut hampir pasti tidak akan terulang pada data produksi. Semakin sering data uji dipakai untuk mengambil keputusan, semakin terkikis nilainya sebagai perkiraan yang jujur; praktik ini sering disebut test set burn-out. Prosedur yang benar telah tersedia: gunakan data validasi atau cross-validation untuk semua keputusan pengembangan, dan buka data uji tepat satu kali sebagai penutup. Alat paling sederhana untuk itu adalah holdout, yang akan kita bahas mekanikanya pada Chapter Train-Test Split dan Holdout.

Referensi Resmi #