Setiap model machine learning menyimpan dua jenis nilai yang sering tertukar dalam percakapan sehari-hari: parameter yang dipelajari dari data oleh metode fit(), dan hyperparameter yang kita pilih sendiri sebelum pelatihan dimulai. Membaurkan keduanya berujung pada kesalahan nyata, misalnya berharap fit() ikut “belajar” nilai max_depth yang sebenarnya harus kita tentukan. Chapter ini memisahkan keduanya dengan tegas, menjelaskan mengapa hyperparameter harus ada, lalu memperlihatkan di mana keduanya hidup di dalam API scikit-learn melalui satu contoh kode yang dapat dijalankan.

Dua Jenis Nilai dalam Sebuah Model #

Parameter adalah bilangan yang diperbarui selama pelatihan. Pada LinearRegression dan LogisticRegression, parameter adalah koefisien coef_ dan intersep intercept_; pada KMeans, parameter adalah pusat klaster cluster_centers_; pada pohon keputusan, parameter adalah seluruh struktur pohon — ambang batas tiap simpul hingga feature_importances_. Semuanya ditarik dari data oleh algoritme, bukan ditulis oleh kita.

Hyperparameter adalah keputusan desain yang ditetapkan sebelum fit() dipanggil: k pada k-nearest neighbors, C pada SVM dan regresi logistik, max_depth pada pohon keputusan, n_estimators dan learning_rate pada model ensemble. Konvensi scikit-learn membuat keduanya mudah dibedakan: parameter hasil pelatihan selalu disimpan sebagai atribut yang namanya diakhiri garis bawah (coef_, tree_, feature_importances_), sedangkan hyperparameter hidup sebagai argumen konstruktor.

AspekParameterHyperparameter
Kapan ditentukanSelama fit() berjalanSebelum fit() dipanggil
Siapa yang menentukanAlgoritme, dari dataKita, sebagai perancang
Tempat penyimpananAtribut berakhiran _ (coef_, tree_)Argumen konstruktor (C, max_depth)
Contoh konkretKoefisien regresi, pusat klaster KMeansk, C, max_depth, n_estimators
Cara mengubahnyaLatih ulang dengan data berbedaPanggil set_params(), lalu fit ulang
JumlahnyaBisa ribuan hingga jutaanBiasanya puluhan

Mengapa Hyperparameter Harus Ada #

Pertanyaan yang wajar: kalau algoritme bisa mempelajari parameter, mengapa tidak sekalian mempelajari max_depth atau C? Jawabannya, tidak ada rumus tertutup yang memetakan dataset ke hyperparameter optimal. Nilai k yang ideal untuk 200 transaksi berlabel tidak sama dengan nilai ideal untuk dua juta citra medis; kedalaman pohon yang pas pada data bersih berbeda dari data penuh derau. Kualitas optimumnya bergantung pada ukuran data, tingkat derau, dan seberapa terpisah kelasnya — sifat-sifat yang tidak bisa diringkas menjadi satu rumus seragam.

Parameter berbeda: prosedur memperolehnya terdefinisi rapi. Regresi linier punya rumus kuadrat terkecil, regresi logistik meminimalkan loss function yang bentuknya eksplisit. Hyperparameter tidak punya padanan seperti itu, sehingga satu-satunya jalan adalah mencoba beberapa kandidat lalu membandingkan kinerjanya — dan itulah pekerjaan seluruh section ini.

Lingkar Penyetelan Model #

Karena hyperparameter tidak bisa dihitung, kita bekerja dalam sebuah lingkar (loop) penyetelan: tentukan daftar kandidat nilai, latih model untuk tiap kandidat dengan cross-validation, pilih kandidat dengan skor validasi terbaik, lalu latih ulang model terpilih pada seluruh data latih. Proses ini disebut hyperparameter tuning dan menjadi kerangka kerja semua alat pada chapter-chapter berikutnya.

Ada satu jebakan yang perlu kita antisipasi sejak awal: kalau lingkar penyetelan dan proses penilaian akhir memakai lipatan cross-validation yang sama, skor akhir akan terlalu optimistis — kita memilih kandidat terbaik berdasarkan angka itu, lalu melaporkan angka itu pula sebagai kinerja. Masalah selection bias ini dipecahkan dengan nested cross-validation, dan mekanisme lengkapnya kita bedah di Chapter Strategi Optimasi Lanjutan.

Di Mana Hyperparameter Berada #

Hyperparameter masuk lewat argumen konstruktor: DecisionTreeClassifier(max_depth=3, random_state=42). Setiap estimator scikit-learn juga menyediakan get_params() yang mengembalikan seluruh hyperparameter beserta nilainya, dan set_params() untuk mengubahnya tanpa membangun objek baru. Dua metode ini bukan hiasan: alat penyetelan otomatis seperti GridSearchCV mengandalkan get_params()/set_params() untuk membongkar dan merakit ulang konfigurasi estimator secara programatik.

Contoh Kode: Melihat Keduanya dalam Satu Objek #

Skrip berikut memakai satu DecisionTreeClassifier untuk menampilkan hyperparameter sebelum pelatihan dan parameter hasil pelatihan dalam satu alur, lengkap dengan momen pergantian hyperparameter lewat set_params().

python
# Hyperparameter dipilih SEBELUM pelatihan; parameter DIPPELAJARI oleh fit().
# Skrip ini mencetak keduanya secara berurutan pada satu DecisionTreeClassifier.

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

# Data sintetis 150 baris dengan seed tetap agar hasil reproducible.
X, y = make_classification(
    n_samples=150, n_features=6, n_informative=4, n_redundant=0,
    n_clusters_per_class=1, random_state=42,
)
X_latih, X_uji, y_latih, y_uji = train_test_split(
    X, y, test_size=0.3, stratify=y, random_state=42,
)

# Hyperparameter diatur di konstruktor -- sebelum model melihat satu baris data pun.
model = DecisionTreeClassifier(max_depth=3, min_samples_leaf=2, random_state=42)

print("== HYPERPARAMETER: get_params() SEBELUM fit() ==")
for nama in ("criterion", "splitter", "max_depth", "min_samples_leaf",
             "min_samples_split", "ccp_alpha", "random_state"):
    print(f"  {nama:18s} = {model.get_params()[nama]}")

# fit() adalah momen pembelajaran: parameter ditarik dari data latih.
model.fit(X_latih, y_latih)

print("\n== PARAMETER: atribut terlatih SETELAH fit() ==")
print(f"  tree_.node_count       = {model.tree_.node_count} simpul")
print(f"  tree_.n_leaves         = {model.tree_.n_leaves} daun")
print(f"  tree_.max_depth        = {model.tree_.max_depth} (batas hyperparameter: 3)")
print("  feature_importances_   = "
      + ", ".join(f"{v:.3f}" for v in model.feature_importances_))

print(f"\n  Akurasi data latih     = {model.score(X_latih, y_latih):.3f}")
print(f"  Akurasi data uji       = {model.score(X_uji, y_uji):.3f}")

# set_params() mengubah hyperparameter, tetapi TIDAK melatih ulang:
# parameter lama masih tersimpan sampai fit() dipanggil kembali.
model.set_params(max_depth=1)
print("\n== SETELAH set_params(max_depth=1) TANPA fit ulang ==")
print(f"  tree_.node_count       = {model.tree_.node_count} (parameter lama masih ada)")

model.fit(X_latih, y_latih)
print("\n== SETELAH set_params(max_depth=1) + fit() ulang ==")
print(f"  tree_.node_count       = {model.tree_.node_count} simpul")
print(f"  tree_.n_leaves         = {model.tree_.n_leaves} daun")
print(f"  Akurasi data uji       = {model.score(X_uji, y_uji):.3f}")

Output yang Dihasilkan:

text
== HYPERPARAMETER: get_params() SEBELUM fit() ==
  criterion          = gini
  splitter           = best
  max_depth          = 3
  min_samples_leaf   = 2
  min_samples_split  = 2
  ccp_alpha          = 0.0
  random_state       = 42

== PARAMETER: atribut terlatih SETELAH fit() ==
  tree_.node_count       = 9 simpul
  tree_.n_leaves         = 5 daun
  tree_.max_depth        = 3 (batas hyperparameter: 3)
  feature_importances_   = 0.073, 0.011, 0.000, 0.000, 0.868, 0.047

  Akurasi data latih     = 0.952
  Akurasi data uji       = 0.867

== SETELAH set_params(max_depth=1) TANPA fit ulang ==
  tree_.node_count       = 9 (parameter lama masih ada)

== SETELAH set_params(max_depth=1) + fit() ulang ==
  tree_.node_count       = 3 simpul
  tree_.n_leaves         = 2 daun
  Akurasi data uji       = 0.933

Mari kita bedah baris-baris kuncinya:

  1. Baris 18 (model = DecisionTreeClassifier(...)): tiga hyperparameter ditetapkan — max_depth=3, min_samples_leaf=2, dan random_state=42 — pada saat objek dibuat, jauh sebelum data dilihat.
  2. Baris 20–23 (loop get_params()): sebelum fit(), kita sudah bisa membaca seluruh konfigurasi desain. Nilai criterion = gini dan splitter = best adalah hyperparameter bawaan yang tidak kita ubah.
  3. Baris 26 (model.fit(X_latih, y_latih)): momen pembelajaran. Setelah baris ini, atribut tree_ dan feature_importances_ terisi — itulah parameter yang dipelajari.
  4. Baris 29–33: struktur pohon hasil pelatihan (9 simpul, 5 daun, kedalaman tercapai 3) dan pentingnya fitur (0,868 pada fitur kelima) adalah hasil, bukan pilihan; model akan menemukan angka-angka ini sendiri dari data.
  5. Baris 40–42 (set_params tanpa fit ulang): mengubah max_depth menjadi 1 tidak serta-merta menghapus pohon lama — tree_.node_count masih 9. Parameter lama bertahan sampai fit() dipanggil lagi.
  6. Baris 44–48 (fit() ulang): pohon baru tumbuh sesuai batas baru: hanya 3 simpul dan 2 daun. Menariknya, akurasi data uji justru naik dari 0,867 ke 0,933 — pohon yang lebih dangkal menggeneralisasi lebih baik pada data ini, dan perbedaan inilah yang mendorong kita menyetel hyperparameter secara sistematis.

Dengan definisi yang kini tegas, langkah berikutnya adalah mengotomatiskan lingkar penyetelan itu sendiri: bagaimana caranya mengevaluasi banyak kombinasi hyperparameter sekaligus tanpa menulis loop manual? Jawabannya adalah GridSearchCV, bintang utama Chapter Grid Search.

Referensi Resmi #