Overfitting pada Pohon

Alasan pohon tunggal mudah goyah dan menghafal data latih bila dibiarkan tumbuh bebas.

Daftar isi

Pohon keputusan yang dibiarkan tumbuh bebas akan terus membagi data sampai setiap daunnya murni, dan kecenderungan itulah yang membuat pohon tunggal mudah menghafal data latih. Topik ini menjelaskan mengapa perilaku tersebut muncul, bagaimana perubahan kecil pada data latih dapat mengubah struktur pohon, serta hyperparameter apa saja yang menahan pertumbuhannya. Eksperimen pada dataset breast cancer bawaan scikit-learn mengukur akurasi latih dan uji untuk kedalaman satu sampai dua belas, sehingga celah keduanya terbaca langsung dari satu tabel.

Menghafal derau bila dibiarkan tumbuh#

Tanpa batasan, algoritme pohon terus mencari pembagian terbaik sampai setiap daun hanya berisi satu kelas, atau bahkan satu contoh. Pada titik itu pohon tidak lagi menangkap pola umum, melainkan menyimpan jawaban setiap baris data latih. Derau (noise), yaitu penyimpangan kecil yang muncul secara kebetulan pada data, ikut tersimpan karena pohon memperlakukannya sama seperti pola yang sungguh-sungguh. Perilaku menghafal inilah yang disebut overfitting, dan akurasi pada data latih mendekati sempurna sementara kinerja pada data baru berhenti membaik.

Kelemahan kedua bersifat struktural, yaitu pohon tunggal memiliki varians (variance) yang tinggi. Pembagian terbaik pada sebuah simpul ditentukan oleh contoh yang tersedia di dalamnya, sehingga pergantian kecil pada data latih dapat memindahkan ambang dan mengubah seluruh cabang di bawahnya. Dua sampel bootstrap dari data yang sama pun kerap menghasilkan pohon dengan struktur yang berbeda. Sampel bootstrap adalah sampel acak yang diambil dengan pengembalian. Pohon yang terbentuk dari separuh data pun dapat memilih fitur terbaik yang berbeda, sehingga prediksinya pada contoh baru ikut bergeser. Ketidakstabilan itulah yang dimanfaatkan bagging, teknik yang merata-ratakan banyak pohon sehingga kegoyahan masing-masing saling terhapus.

Hyperparameter penahan pertumbuhan#

Pustaka scikit-learn menyediakan beberapa penahan yang bekerja pada titik berbeda. max_depth membatasi banyaknya tingkat pertanyaan, min_samples_leaf menolak pembagian yang menghasilkan daun dengan contoh terlalu sedikit, sedangkan min_samples_split mensyaratkan jumlah contoh minimum sebelum sebuah simpul boleh dibagi. Ketiganya memperpendek pohon dengan mekanisme masing-masing, dan nilai yang terlalu ketat justru menimbulkan underfitting, yaitu model yang terlalu kaku untuk menangkap pola. Kombinasi dua penahan juga lazim, misalnya batas kedalaman yang longgar disertai daun yang tidak boleh terlalu kecil. Semua nilai tersebut berperan sebagai kebijakan berhenti, yaitu penentu seberapa jauh pohon boleh menyesuaikan diri pada data latih.

Penahan lainnya bekerja setelah pohon selesai tumbuh, yaitu cost-complexity pruning. Teknik ini memangkas cabang yang kontribusinya terhadap penurunan ketidakmurnian kecil dibanding biaya kerumitan yang dibawanya. Pada scikit-learn, kekuatan pemangkasan diatur melalui parameter ccp_alpha. Semua penahan tersebut adalah hyperparameter, sehingga nilainya dipilih dengan membandingkan skor pada data validasi atau cross-validation, bukan dengan membaca akurasi data latih.

Penahanan juga mengubah sifat keputusan modelnya. Pohon yang pendek memaksa setiap daun mengelompokkan lebih banyak contoh, sehingga keputusannya lebih kasar tetapi lebih stabil. Tujuan penyetelannya bukan skor data latih tertinggi, melainkan skor terbaik pada data yang belum pernah dilihat.

Eksperimen kedalaman satu sampai dua belas#

Skrip berikut melatih DecisionTreeClassifier untuk kedalaman satu sampai dua belas dengan random_state=42, lalu mengumpulkan akurasi latih dan uji setiap kedalaman ke dalam tabel pandas. Dataset breast cancer dipilih karena fiturnya banyak dan saling berkorelasi, sehingga ruang bagi penghafalan lebih luas dibanding dataset iris. Pemecahan data mengikuti kesepakatan jalur, yaitu test_size=0.2 dengan random_state=42.

python kedalaman-vs-skor.py
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

pd.set_option("display.width", 80)

X, y = load_breast_cancer(return_X_y=True)
X_latih, X_uji, y_latih, y_uji = train_test_split(
    X, y, test_size=0.2, random_state=42
)

baris = []
for kedalaman in range(1, 13):
    pohon = DecisionTreeClassifier(
        max_depth=kedalaman, random_state=42
    ).fit(X_latih, y_latih)
    baris.append(
        {
            "depth": kedalaman,
            "akurasi_latih": pohon.score(X_latih, y_latih),
            "akurasi_uji": pohon.score(X_uji, y_uji),
        }
    )

tabel = pd.DataFrame(baris)
print(tabel.to_string(index=False, float_format="{:.4f}".format))
text Keluaran
 depth  akurasi_latih  akurasi_uji
     1         0.9209       0.8947
     2         0.9297       0.9298
     3         0.9780       0.9474
     4         0.9956       0.9474
     5         0.9956       0.9474
     6         0.9978       0.9386
     7         1.0000       0.9474
     8         1.0000       0.9474
     9         1.0000       0.9474
    10         1.0000       0.9474
    11         1.0000       0.9474
    12         1.0000       0.9474

Akurasi latih naik cepat dan menyentuh 1.0000 pada kedalaman tujuh, yang berarti pohon sudah menghafal seluruh data latihnya. Akurasi uji bergerak berbeda dari akurasi latih, yaitu naik pesat pada kedalaman rendah, berhenti naik di sekitar 0.9474, kemudian mendatar dengan sedikit fluktuasi. Mulai kedalaman tujuh, angkanya tidak berubah lagi. Pohon sudah berhenti tumbuh secara alami ketika daunnya murni, sehingga batasan yang lebih longgar tidak menghasilkan pohon yang berbeda.

Celah antara kolom akurasi_latih dan akurasi_uji menjadi ukuran langsung overfitting. Pada kedalaman dua belas, selisih tersebut mencapai 0.0526. Angka ini berarti model sempurna pada data latih, tetapi kinerjanya pada data baru tidak membaik sama sekali. Kedalaman terbaik menurut kolom uji berada pada rentang tiga sampai lima, dan tambahan kedalaman di atasnya hanya menambah penghafalan. Pembacaan tabel seperti ini menjadi cara tercepat melihat tren, tetapi keputusan akhir tetap diserahkan pada cross-validation yang merata-ratakan banyak pemecahan.

Kesalahan umum#

  • Memilih kedalaman berdasarkan akurasi data latih. Akurasi latih selalu naik ketika kedalaman bertambah karena pohon semakin bebas menghafal, sehingga angka itu tidak pernah membedakan model yang baik dan model yang hanya menghafal. Kedalaman yang tepat justru terbaca dari titik ketika akurasi uji berhenti naik, seperti rentang tiga sampai lima pada tabel eksperimen. Penilaiannya menggunakan data validasi atau cross-validation.
  • Menyetel penahan dengan berulang kali melihat skor data uji. Data uji yang dikonsultasikan berkali-kali berubah menjadi himpunan validasi terselubung, dan laporan akhirnya kehilangan ukuran yang netral. Penyetelan harian dilakukan pada data validasi, sedangkan skor data uji baru dibaca sekali di akhir.
  • Menganggap pohon yang lebih dalam selalu lebih buruk. Kedalaman yang terlalu kecil justru menimbulkan underfitting karena pohon menjadi terlalu kaku untuk menangkap pola, dan nilai optimumnya dicari, bukan diasumsikan.
  • Membandingkan angka eksperimen antar dataset secara langsung. Akurasi bergantung pada dataset dan pemecahannya, karena jumlah contoh, jumlah fitur, dan tingkat derau setiap dataset berbeda. Yang dipelajari dari tabel adalah pola pergerakannya, bukan nilai persisnya.

Ringkasan#

  • Pohon tanpa batas membagi data sampai daun murni sehingga ikut menyimpan derau data latih sebagai pola.
  • Struktur pohon goyah, yaitu perubahan kecil data latih dapat memindahkan ambang dan mengubah seluruh cabang di bawahnya.
  • max_depth, min_samples_leaf, min_samples_split, dan ccp_alpha menahan pertumbuhan masing-masing dari titik yang berbeda.
  • Akurasi latih yang cepat menyentuh 1.0 sementara akurasi uji berhenti naik adalah pasangan tanda overfitting yang paling mudah dibaca.

Referensi#