Semua metrik sejauh ini menjawab “seberapa baik model sekarang”. Learning curve menjawab pertanyaan yang lebih strategis: “ke mana performa ini akan bergerak jika kita menambah data — dan apakah menambah data memang obat yang tepat?”. Kurva pembelajaran menggambar skor data latih dan skor data validasi sebagai fungsi dari jumlah sampel latih, dan bentuk kedua kurva tersebut ternyata mengandung diagnosis yang hampir selalu bisa dibaca langsung: model yang menghafal, model yang terlalu sederhana, dan titik di mana data tambahan berhenti membayar. Chapter ini membedah fungsi learning_curve dari scikit-learn, membaca dua pola klasik dalam angka, lalu menutup dengan tabel keputusan pola → diagnosis → tindakan.

Cara Kerja learning_curve #

Fungsi learning_curve dari sklearn.model_selection menjalankan eksperimen bertingkat: untuk tiap ukuran latih yang diminta (misalnya 30, 60, 120, 180, 240 sampel), fungsi ini melatih model pada subset sebesar tersebut, mengukur skor pada data latih itu sendiri dan pada data validasi, lalu mengulang prosesnya untuk tiap fold cross-validation. Hasilnya tiga array: ukuran latih efektif, matriks skor latih berdimensi (jumlah ukuran) x (jumlah fold), dan matriks skor validasi dengan bentuk yang sama. Rata-rata per baris (.mean(axis=1)) menghasilkan dua kurva yang siap dibaca — kita tidak menggambar grafiknya, tetapi mencetak angkanya.

Satu detail mekanis perlu dicatat: karena tiap putaran memakai cross-validation 5-fold, satu fold selalu disisihkan sebagai validasi, sehingga ukuran latih maksimum adalah 4/5 dari data. Pada data 300 sampel, baris terakhir tabel kita berhenti di 240 sampel latih — bukan 300.

Dua Pola yang Bisa Didiagnosis #

Pola pertama: selisih (gap) besar, skor latih tinggi. Kurva latih nempel di angka tinggi (misalnya 1,000 untuk pohon keputusan yang tumbuh penuh) sementara kurva validasi tertinggal jauh di bawah. Model cukup fleksibel untuk menghafal data latih berapa pun ukurannya, tetapi hafalan tersebut tidak menular ke data baru. Diagnosisnya adalah overfitting — didominasi variansi. Menambah data akan menutup gap perlahan, tetapi obat yang lebih murah dan lebih cepat adalah menurunkan kapasitas model: membatasi kedalaman pohon, menambah regularisasi, atau memilih model yang lebih sederhana.

Pola kedua: kedua kurva rendah dan berdempetan. Kurva latih dan kurva validasi berjarak sempit, keduanya berhenti di level yang tidak memuaskan. Model sudah terlalu sederhana untuk menangkap pola data — diagnosisnya underfitting — didominasi bias. Yang penting: menambah data TIDAK akan menolong pola ini; kedua kurva sudah sejajar, sehingga data baru hanya memperpanjang garis datar yang sama. Obatnya ada di sisi model dan fitur: model yang lebih ekspresif, fitur baru yang lebih informatif, atau rekayasa fitur yang lebih baik.

Kapan Menambah Data Membayar #

Kurva pembelajaran juga menjawab pertanyaan anggaran. Bila kurva validasi masih menanjak tajam di ujung kanan grafik, data tambahan kemungkinan besar masih memperbaiki performa — pengumpulan data layak didanai. Bila kurva validasi sudah mendatar, data tambahan bernilai kecil; anggaran lebih baik dialihkan ke sumber masalah yang lain. Mari kita lihat keduanya sekaligus pada dua model atas data yang sama.

python
# Learning curve: skor latih vs skor validasi seiring bertambahnya data.
# Dua pola berbeda muncul dari dua model pada data yang sama.

import numpy as np
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, learning_curve
from sklearn.tree import DecisionTreeClassifier

# Data sintetis tetap berisi 300 sampel dengan derau label (flip_y)
# supaya skor tidak pernah menyentuh 1.000 dan polanya terlihat jelas.
X, y = make_classification(
    n_samples=300,
    n_features=10,
    n_informative=6,
    n_redundant=2,
    flip_y=0.10,
    random_state=42,
)

# Dengan 5-fold CV, satu fold selalu disisihkan sebagai validasi,
# sehingga ukuran data latih maksimum = 4/5 x 300 = 240 sampel.
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
ukuran_latih = np.array([30, 60, 120, 180, 240])

kandidat = [
    ("LogisticRegression", LogisticRegression(max_iter=1000, random_state=42)),
    ("DecisionTree tumbuh penuh", DecisionTreeClassifier(random_state=42)),
]

for nama, estimator in kandidat:
    ukuran, skor_latih, skor_validasi = learning_curve(
        estimator, X, y, train_sizes=ukuran_latih, cv=cv,
        scoring="accuracy", n_jobs=1,
    )
    rata_latih = skor_latih.mean(axis=1)
    rata_validasi = skor_validasi.mean(axis=1)

    print(f"== {nama} ==")
    print("   n   |  latih  | validasi |   gap")
    for n, a, b in zip(ukuran, rata_latih, rata_validasi):
        print(f" {n:>5d} |  {a:.3f}  |  {b:.3f}   | {a - b:.3f}")
    print()

Output yang Dihasilkan:

text
== LogisticRegression ==
   n   |  latih  | validasi |   gap
    30 |  0.940  |  0.793   | 0.147
    60 |  0.900  |  0.823   | 0.077
   120 |  0.867  |  0.820   | 0.047
   180 |  0.853  |  0.827   | 0.027
   240 |  0.833  |  0.827   | 0.007

== DecisionTree tumbuh penuh ==
   n   |  latih  | validasi |   gap
    30 |  1.000  |  0.743   | 0.257
    60 |  1.000  |  0.797   | 0.203
   120 |  1.000  |  0.773   | 0.227
   180 |  1.000  |  0.850   | 0.150
   240 |  1.000  |  0.803   | 0.197

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 12–19 (make_classification): 300 sampel dengan flip_y=0.10 menaruh lantai galat di atas nol — data memang mengandung 10% label yang tertukar sehingga tidak ada model yang mencapai akurasi 1,000.
  2. Baris 23–24 (cv dan ukuran_latih): fold diacak dan dikunci random_state=42; daftar ukuran latih naik dari 30 sampai 240 — batas maksimum 5-fold CV.
  3. Baris 26–29 (kandidat): dua estimator dengan struktur berlawanan — LogisticRegression yang kapasitasnya terbatas, dan DecisionTreeClassifier tanpa batas kedalaman yang kapasitasnya sangat besar.
  4. Baris 32–35 (learning_curve(...)): satu pemanggilan mengembalikan tiga array; skor_latih dan skor_validasi berbentuk matriks 5 ukuran x 5 fold.
  5. Baris 36–37 (.mean(axis=1)): rata-rata antar fold per ukuran mengubah matriks menjadi dua kurva angka; kolom gap pada baris 42 mencetak selisihnya sebagai alat diagnosis utama.

Bacaan output pertama — LogisticRegression — adalah pola konvergensi. Dari 30 sampai 240 sampel, skor latih turun (0,940 → 0,833) sementara skor validasi naik (0,793 → 0,827); gap menutup dari 0,147 menjadi 0,007. Kedua kurva berakhir rendah dan berdempet — model ini sudah mentok di kemampuannya menangkap pola dari 10 fitur tersebut. Data tambahan akan mempersempit gap sedikit lagi lalu berhenti; kenaikan berarti harus datang dari fitur atau model yang lebih ekspresif.

Bacaan output kedua — DecisionTree tumbuh penuh — adalah pola gap yang gigih. Skor latih tertahan di 1,000 pada setiap ukuran: pohon tanpa batas kedalaman selalu sanggup menghafal seluruh data latih, berapa pun banyaknya. Sementara itu skor validasi berkisar 0,74–0,85 dan gap tetap lebar (0,15–0,26) bahkan di 240 sampel. Diagnosis: overfitting yang didominasi variansi. Menambah data ke beberapa ribu sampel akan menutup gap pelan-pelan, tetapi membatasi kedalaman pohon atau memangkasnya jauh lebih murah. Bandingkan tabel di bawah:

Pola pada learning curveDiagnosisObat yang tepat
Latih tinggi, validasi jauh di bawah, gap lebarOverfitting (variansi tinggi)Turunkan kapasitas: batasi kedalaman, regularisasi, model lebih sederhana
Kedua kurva rendah dan berdempetUnderfitting (bias tinggi)Naikkan kapasitas atau perbaiki fitur; data tambahan tidak menolong
Validasi masih menanjak di ujung kananData belum cukupKumpulkan data tambahan — investasi masih membayar
Validasi mendatar di ujung kananData sudah cukupHentikan pengumpulan; perbaiki sumber masalah yang lain

Kedua pola tersebut — gap lebar karena variansi, kurva datar karena bias — adalah wajah dari kompromi fundamental yang mengatur semua model machine learning. Bab penutup section ini membongkar kompromi itu sampai ke rumusnya: bias-variance tradeoff, tempat bias, variansi, dan derau dipisahkan menjadi tiga angka yang bisa dihitung sendiri pada Chapter Bias-Variance Tradeoff.

Referensi Resmi #