Model machine learning yang kita bangun bukan untuk menjawab soal yang sudah dilihatnya, melainkan soal yang belum pernah muncul — transaksi berikutnya, pasien berikutnya, rumah berikutnya. Kemampuan itu disebut generalisasi, dan kegagalan generalisasi adalah sumber masalah paling mahal dalam proyek machine learning. Kegagalannya datang dalam dua bentuk: model yang terlalu kaku sehingga pola aslinya tidak tertangkap (underfitting), dan model yang terlalu lentur sehingga ikut menghafal derau data (overfitting). Chapter ini membedah keduanya lewat eksperimen yang bisa Anda jalankan sendiri — satu kurva, tiga tingkat kompleksitas, dan tabel angka yang menampar.
Menghafal Bukan Berarti Paham #
Mari kita mulai dari masalahnya. Data dunia nyata selalu memuat dua komponen bercampur: pola yang ingin kita pelajari, dan derau (noise) acak yang tidak ingin kita pelajari — kesalahan pencatatan, faktor tak teramati, kebetulan sampling. Sebuah model yang bekerja baik harus menangkap polanya dan mengabaikan deraunya. Model yang ikut mempelajari derau akan tampak hebat di atas data yang dipakainya belajar, lalu jatuh begitu diuji pada data baru; ia seperti murid yang menghafal kunci jawaban satu paket soal, bukan memahami materinya.
Tingkat “kelenturan” model — istilah teknisnya kapasitas atau kompleksitas — adalah tuas utama yang menentukan posisi kita di antara dua jurang:
- Underfitting (kapasitas terlalu rendah): model terlalu sederhana untuk menangkap pola. Kesalahannya bersifat sistematis — kurva yang seharusnya melengkung dipaksa lurus. Hasilnya buruk pada data latih dan data uji. Istilah informalnya: model terlalu bias pada satu bentuk sederhana.
- Overfitting (kapasitas terlalu tinggi): model punya ruang cukup untuk menyalin data latih titik demi titik, termasuk deraunya. Kurvanya berayun liar menembus tiap titik latih. Hasilnya nyaris sempurna pada data latih tetapi runyuh pada data uji. Istilah informalnya: model memiliki variance tinggi — prediksinya sangat bergantung pada sampel kebetulan mana yang dipakai melatihnya; ganti sampelnya, kurvanya berubah drastis.
Ujian Klasik: Kurva Sinus Berderau #
Eksperimen standar untuk memperlihatkan kedua jurang ini dirancang sebagai berikut. Buat data dari fungsi sin(x) ditambah derau Gaussian — polanya sinus, deraunya acak. Sisihkan 20 titik sebagai data latih dan 20 titik baru sebagai data uji, keduanya dari proses yang sama. Lalu latih tiga model regresi polinomial berbeda derajat: 1 (garis lurus), 3 (kurva landai), dan 15 (kurva berparameter banyak), masing-masing dibangun dari gabungan PolynomialFeatures dan LinearRegression dalam sebuah Pipeline.
# Demonstrasi klasik underfitting vs overfitting pada data fungsi sinus berderau.
# Derajat polinomial 1 (terlalu sederhana), 3 (pas), dan 15 (terlalu kompleks)
# dibandingkan lewat MSE pada data latih dan data uji.
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures
def buat_data(n, rng):
"""Ambil n titik dari kurva sin(x) dengan derau Gaussian tetap."""
x = rng.uniform(-3.0, 3.0, size=n)
derau = rng.normal(loc=0.0, scale=0.4, size=n)
y = np.sin(x) + derau
return x.reshape(-1, 1), y
rng = np.random.default_rng(42)
X_latih, y_latih = buat_data(20, rng) # 20 titik untuk melatih model
X_uji, y_uji = buat_data(20, rng) # 20 titik baru untuk menguji
print(f"{'derajat':>7} {'parameter':>10} {'MSE latih':>11} {'MSE uji':>11}")
for derajat in [1, 3, 15]:
model = make_pipeline(
PolynomialFeatures(degree=derajat, include_bias=False),
LinearRegression(),
)
model.fit(X_latih, y_latih)
mse_latih = mean_squared_error(y_latih, model.predict(X_latih))
mse_uji = mean_squared_error(y_uji, model.predict(X_uji))
# 1 fitur input -> derajat d menghasilkan d + 1 parameter (d pangkat + intercept)
print(f"{derajat:>7} {derajat + 1:>10} {mse_latih:>11.3f} {mse_uji:>11.3f}")
print()
print("Pola khasnya: MSE latih turun terus seiring derajat naik,")
print("sedangkan MSE uji mula-mula turun lalu melonjak saat model terlalu kompleks.")Output yang Dihasilkan:
derajat parameter MSE latih MSE uji
1 2 0.156 0.160
3 4 0.070 0.105
15 16 0.011 2426126.947
Pola khasnya: MSE latih turun terus seiring derajat naik,
sedangkan MSE uji mula-mula turun lalu melonjak saat model terlalu kompleks.Bedah kode baris demi baris:
- Baris 12–17 (
def buat_data): satu fungsi pembangkit data. Baris 14 mengambilntitikxacak seragam di rentang[-3, 3]; baris 15 menambahkan derau Gaussian bersimpangan 0,4; baris 16 menggabungkannya menjadiy = sin(x) + derau. Karenarngdibuat berseed, data yang sama lahir di setiap eksekusi. - Baris 20–22:
rng = np.random.default_rng(42)menjadi sumber ketertentuan seluruh eksperimen. Baris 21 menarik 20 titik latih; baris 22 menarik 20 titik uji dari aliran acak yang sama — kedua himpunan berbeda, tetapi keduanya dari proses pembangkit yang identik, sehingga perbandingannya adil. - Baris 25–29 (loop dan
make_pipeline): tiap derajat membangun pipeline dua langkah —PolynomialFeaturesmengubah satu fiturxmenjadix, x², ..., x^d, laluLinearRegressionmencari koefisien terbaik lewat least squares. Derajat adalah hyperparameter kapasitas: derajat 15 memberi model 16 parameter untuk 20 titik data. - Baris 30–32: model dilatih hanya pada data latih, lalu MSE dihitung dua kali — pada data latih (seberapa rapat kurvanya menempel pada bahan belajar) dan pada data uji (seberapa jauh generalisasinya).
- Baris 33–34: tabel dicetak dengan kolom jumlah parameter sebagai ukuran kompleksitas yang eksplisit.
Membaca Tabel: Tanda Tangan Overfitting #
Tiga baris output di atas memuat seluruh cerita bab ini:
- Derajat 1 — underfitting: MSE latih 0,156 dan MSE uji 0,160, keduanya tinggi dan hampir setara. Garis lurus memang tidak bisa mengikuti lengkung sinus; kesalahan didominasi bentuk model yang salah, bukan derau. Ciri underfitting persis seperti ini: buruk di mana-mana.
- Derajat 3 — pas: MSE latih 0,070, MSE uji 0,105. Kurva kubik cukup lentur mengikuti sinus namun terlalu kaku untuk menyalin derau. Selisih latih-uji kecil, dan MSE uji terendah di antara ketiganya.
- Derajat 15 — overfitting: MSE latih 0,011 (nyaris sempurna) tetapi MSE uji 2.426.126,947. Inilah tanda tangan overfitting: MSE latih turun terus sementara MSE uji meroket. Akar dari MSE uji tersebut sekitar 1.557 — padahal seluruh nilai
yhanya bergerak di rentang kira-kira −1,4 sampai 1,4. Prediksinya melesat ribuan kali lipat dari rentang data.
Mengapa derajat 15 jatuh seburuk itu? Dengan 16 parameter dan hanya 20 titik latih, kurva polinomial berhasil menembus atau mendekati setiap titik latih — termasuk deraunya. Untuk melakukannya, koefisien x^13 hingga x^15 membengkak besar; di antara titik-titik latih yang berjarak, suku-suku pangkat tinggi itu saling mengalahkan dan membuat kurva berayun dengan amplitudo ribuan. Titik uji yang jatuh di wilayah ayunan itu menerima prediksi mustahil — dan kuadrat kesalahannya membengkak ke jutaan. Model tidak gagal karena kurang belajar; ia gagal karena belajar berlebihan.
Tuas Perbaikan yang Tersedia #
Ketika tanda tangan overfitting (atau underfitting) terbaca, kita memiliki repertoar tindakan standar yang teruji:
| Tindakan | Cara kerja | Membantu | Dibahas di |
|---|---|---|---|
| Tambah data latih | Derau rata-rata saling menghapus; kurva dipaksa konsisten | Overfitting | Section Evaluasi (learning curve) |
| Turunkan kompleksitas | Derajat/pohon lebih dangkal mengurangi kapasitas menghafal | Overfitting | Section Regresi dan Klasifikasi |
| Regularisasi (Ridge, Lasso) | Hukuman atas koefisien besar menahan ayunan kurva | Overfitting | Chapter Regularisasi: Ridge, Lasso, dan Elastic Net |
| Naikkan kompleksitas / fitur baru | Model kaku diberi bentuk yang lebih kaya | Underfitting | Section Feature Engineering |
| Cross-validation | Estimasi generalisasi lebih stabil sebelum memilih model | Keduanya (mencegah pilihan keliru) | Chapter Cross-Validation |
Ada satu disiplin terakhir yang menopang semua eksperimen di atas: seluruh angka yang kita baca — data latih 0,156, akurasi 0,974 pada chapter sebelumnya — hanya bermakna karena hasilnya sama setiap kali dijalankan ulang. Bagaimana kendali atas keacakan itu bekerja adalah bahasan penutup section ini, Chapter Reproduksibilitas dengan random_state.
Referensi Resmi #
- Linear Models — scikit-learn User Guide — bagian regresi polinomial yang dipakai pada eksperimen chapter ini.
- sklearn.preprocessing.PolynomialFeatures — API Reference — dokumentasi transformer pembangkit fitur pangkat.
- Model evaluation — scikit-learn User Guide — metrik evaluasi, termasuk MSE, beserta pemakaiannya yang benar.
- Common pitfalls and recommended practices — scikit-learn — risiko kebocoran data dan praktik penyetelan model yang sehat.