Model yang dilatih dan dinilai pada himpunan data yang sama akan selalu terlihat lebih baik daripada kemampuannya yang sebenarnya. Topik ini menjelaskan pemecahan masalah tersebut melalui tiga himpunan, yaitu data latih (train set), data validasi (validation set), dan data uji (test set), beserta disiplin penggunaannya. Praktiknya menggunakan dataset diabetes bawaan scikit-learn yang dipecah dua tahap dengan train_test_split, lalu diakhiri perbandingan skor pada ketiga himpunan.
Tiga himpunan dan tugasnya#
Ketiga himpunan menjalankan tugas yang berbeda pada siklus pemodelan. Data latih digunakan untuk menyesuaikan parameter model, misalnya koefisien pada regresi linear. Data validasi digunakan untuk membandingkan pilihan model dan hyperparameter, misalnya kedalaman pohon atau kekuatan regularisasi, dan boleh digunakan berkali-kali selama proses pemodelan berlangsung. Data uji digunakan satu kali saja di akhir proses, dan angkanya dilaporkan apa adanya sebagai perkiraan kinerja pada data baru.
Pembagian tugas itu sering disamakan dengan soal latihan dan ujian akhir. Soal latihan boleh dikerjakan berulang hingga polanya dikenal, sedangkan naskah ujian akhir dibuka satu kali pada saat penilaian. Disiplin yang menyertainya terletak pada satu aturan, yaitu data uji tidak boleh memengaruhi keputusan apa pun, baik pemilihan model, penyetelan hyperparameter, maupun penambahan fitur.
| Himpunan | Proporsi umum | Tugas | Frekuensi pemakaian |
|---|---|---|---|
| Data latih | 60-80% | Menyesuaikan parameter model | Setiap kali model dilatih |
| Data validasi | 10-20% | Membandingkan model dan hyperparameter | Berulang selama pemodelan |
| Data uji | 10-20% | Penilaian akhir kinerja | Satu kali, di akhir |
Proporsi pada tabel adalah kebiasaan yang lazim, bukan aturan baku. Dataset yang besar dapat menyisakan porsi uji yang lebih kecil, sedangkan dataset yang kecil membuat setiap baris mahal. Dataset yang kecil ditangani dengan cross-validation, yaitu pengulangan pemecahan data latih menjadi beberapa bagian validasi, untuk memanfaatkan data secara lebih hemat. Apa pun proporsinya, ketiga peran pada tabel tetap harus terpisah dan barisnya tidak saling bertukar.
Mengapa satu himpunan tunggal menipu#
Model dengan kapasitas yang cukup tidak berhenti pada pola umum, tetapi juga menyerap kekhususan baris data latihnya, termasuk derau (noise) yang menyertainya. Perilaku ini disebut overfitting. Semakin besar kapasitas model, semakin banyak kekhususan yang dapat dihafal, sehingga celah antara skor data latih dan skor data uji semakin lebar. Ketika model dinilai pada data yang sama persis dengan data pelatihannya, kekhususan yang terlanjur disesuaikan itu ikut dihitung sebagai keberhasilan, sehingga skornya naik tanpa mencerminkan kemampuan menghadapi data baru.
Penipuan yang sama terjadi pada skala yang lebih halus ketika satu himpunan digunakan untuk memilih model dan menilainya sekaligus. Setiap keputusan yang berpijak pada data uji, misalnya memilih model dengan skor tertinggi, membuat data uji ikut membentuk keputusan tersebut. Data uji itu berhenti menjadi penilai yang netral, dan tidak tersisa ukuran yang jujur lagi. Akibatnya setiap percobaan terlihat membaik, tetapi kemampuan menghadapi data baru tidak bergerak. Karena itu, pilihan model dan hyperparameter diuji pada data validasi, sedangkan data uji disimpan tanpa disentuh sampai seluruh keputusan selesai.
Pemisahan dua tahap dengan scikit-learn#
Pemecahan dilakukan dua tahap dengan fungsi train_test_split. Tahap pertama menyisihkan 20 persen data sebagai data uji, lalu tahap kedua mengambil 30 persen dari sisa sebagai data validasi. Angka acak dipatok melalui random_state agar pembagian yang sama dapat direproduksi. Skrip berikut menerapkannya pada dataset diabetes, kemudian melatih LinearRegression pada data latih dan membandingkan skornya pada ketiga himpunan.
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X, y = load_diabetes(return_X_y=True)
# pemisahan pertama: pisahkan data uji sebanyak 20 persen
X_latih, X_uji, y_latih, y_uji = train_test_split(
X, y, test_size=0.20, random_state=42
)
# pemisahan kedua: dari sisa data, pisahkan validasi sebanyak 30 persen
X_latih, X_valid, y_latih, y_valid = train_test_split(
X_latih, y_latih, test_size=0.30, random_state=42
)
print(f"Data latih : {X_latih.shape[0]} baris, {X_latih.shape[1]} fitur")
print(f"Data validasi : {X_valid.shape[0]} baris")
print(f"Data uji : {X_uji.shape[0]} baris")
model = LinearRegression().fit(X_latih, y_latih)
print(f"Skor data latih : {model.score(X_latih, y_latih):.4f}")
print(f"Skor data validasi : {model.score(X_valid, y_valid):.4f}")
print(f"Skor data uji : {model.score(X_uji, y_uji):.4f}")Data latih : 247 baris, 10 fitur
Data validasi : 106 baris
Data uji : 89 baris
Skor data latih : 0.5165
Skor data validasi : 0.5317
Skor data uji : 0.4490Dataset diabetes berisi 442 baris. Tahap pertama menyisakan 353 baris untuk latih dan 89 baris untuk uji, kemudian tahap kedua memecah 353 baris itu menjadi 247 baris latih dan 106 baris validasi. Metode score pada regresi linear mengembalikan koefisien determinasi , yaitu porsi variasi target yang dapat dijelaskan model. Skor data latih 0.5165 lebih tinggi daripada skor data uji 0.4490, dan jarak inilah gambaran optimisme ketika model menilai dirinya pada data yang dipelajarinya. Skor validasi 0.5317 bahkan sedikit melebihi skor data latih, dan hal itu wajar pada himpunan validasi yang hanya berisi 106 baris karena angka dari himpunan kecil memang berfluktuasi. Kesimpulannya tetap, yaitu skor data uji yang diambil satu kali itulah perkiraan yang paling jujur.
Kesalahan umum#
- Menyetel hyperparameter sambil memantau skor data uji. Kesalahan ini terasa ringan karena skor data uji memang dicetak oleh skrip. Padahal, setiap pembandingan semacam itu mengubah data uji menjadi himpunan validasi terselubung, sehingga pada penilaian akhir tidak tersisa ukuran yang netral. Pemantauan selama penyetelan dilakukan pada data validasi, dan skor data uji baru dibaca sekali di akhir.
- Menghitung statistik preprocessing sebelum pemecahan, misalnya menskalakan seluruh dataset terlebih dahulu. Kesalahan ini mudah terlewat karena pemecahan terlihat seperti langkah administratif, padahal statistik penskalaan memuat informasi dari setiap baris. Informasi data uji ikut masuk ke transformasi dan menimbulkan kebocoran data (data leakage). Statistik hanya boleh dihitung dari data latih, kemudian transformasi yang sama diterapkan ke data validasi dan data uji.
- Memecah data berurutan waktu secara acak. Kesalahan ini sulit terasa karena setiap baris memang terlihat setara, padahal urutan waktunya membawa informasi. Baris masa depan dapat berpindah ke data latih sehingga model terlanjur mengetahui kejadian yang seharusnya diprediksi. Data berwaktu dipecah mengikuti urutan waktunya, misalnya dengan menempatkan periode terakhir seluruhnya pada data uji.
Ringkasan#
- Data latih menyesuaikan parameter, data validasi membandingkan pilihan model dan hyperparameter, sedangkan data uji menyediakan penilaian akhir yang disentuh satu kali.
- Skor pada data latih adalah angka yang optimistis karena parameter telah disesuaikan pada data itu, bukan perkiraan kinerja pada data baru.
- Pemecahan dua tahap, yaitu 20 persen untuk uji lalu 30 persen dari sisanya untuk validasi, menghasilkan tiga himpunan dengan peran yang terpisah.
random_statemenjamin hasil pemecahan dapat direproduksi, danstratify=ymenjaga proporsi kelas pada masalah klasifikasi.
Referensi#
- Cross-validation: evaluating estimator performance — scikit-learn — Panduan resmi evaluasi model yang jujur, termasuk konvensi data latih dan data uji.
- sklearn.model_selection.train_test_split — scikit-learn
— Dokumentasi fungsi pemecahan beserta parameter
test_size,random_state, danstratify. - Google Machine Learning Crash Course — Google — Materi dasar machine learning yang membahas pemisahan data dan evaluasi model.