Optuna Hyperparameter Tuning 2026: Panduan Lengkap dengan Scikit-Learn, XGBoost, dan LightGBM
Panduan praktis Optuna 4.x untuk tuning scikit-learn, XGBoost, dan LightGBM: TPE sampler, pruner, cross-validation, storage backend, multi-objective, sampai integrasi MLflow di pipeline production 2026.
Optuna adalah framework open-source Python untuk hyperparameter tuning otomatis yang menggunakan algoritma Bayesian optimization (TPE) untuk menemukan kombinasi parameter terbaik lebih cepat daripada Grid Search atau Random Search. Di 2026 dengan rilis Optuna 4.x, framework ini jadi pilihan default untuk tuning model scikit-learn, XGBoost, LightGBM, dan PyTorch di ribuan tim ML production. Dalam panduan ini saya akan menunjukkan cara memakai Optuna secara praktis, dari trial pertama sampai integrasi ke pipeline produksi. Semua berdasarkan pengalaman saya menuning ratusan model batch scoring di tim payments (saya sempat menghabiskan tiga sprint hanya untuk membenahi study yang overfit gara-gara salah pruner).
Optuna 4.x memakai TPE (Tree-structured Parzen Estimator) sebagai sampler default, yang biasanya menemukan hyperparameter optimal 5–10× lebih cepat dari GridSearchCV pada search space besar.
Pruner seperti MedianPruner dan HyperbandPruner bisa memotong 40–70% waktu tuning dengan menghentikan trial yang tidak menjanjikan sebelum selesai training.
Optuna 4.0 (rilis Maret 2025) memperkenalkan JournalStorage sebagai backend recommended untuk distributed tuning, menggantikan file-lock lama yang bermasalah di NFS.
Untuk XGBoost dan LightGBM, gabungkan optuna.integration callbacks dengan cross-validation supaya estimasi generalisasi lebih stabil.
OptunaSearchCV menyediakan API drop-in replacement untuk GridSearchCV, jadi Anda bisa migrasi bertahap dari scikit-learn tanpa merombak pipeline.
Multi-objective optimization (Pareto front) berguna saat harus menyeimbangkan akurasi vs latency inferensi. Kasus umum saat model dideploy di balik API real-time.
Apa Itu Optuna dan Mengapa Populer di 2026
Optuna adalah framework hyperparameter optimization berbasis Python yang dikembangkan pertama kali oleh Preferred Networks, dan sekarang jadi proyek open-source dengan lebih dari 12 ribu bintang di GitHub. Berbeda dengan pendekatan tradisional seperti Grid Search yang meng-enumerate semua kombinasi parameter, Optuna memakai pendekatan define-by-run: search space didefinisikan secara dinamis di dalam fungsi objective Python biasa, bukan sebagai konfigurasi statis.
Filosofi define-by-run ini penting karena memungkinkan search space kondisional. Misalnya, saat Anda tuning XGBoost, hyperparameter gamma hanya relevan bila tree_method="exact". Dengan Optuna, Anda bisa menulis logika Python biasa untuk hanya men-sample gamma pada trial yang memakai exact. Framework lama seperti Hyperopt memerlukan configuration DSL yang canggung untuk kasus ini.
Alasan mengapa Optuna dominan di 2026:
Algoritma modern: TPE (default), CMA-ES untuk parameter kontinu, NSGA-II untuk multi-objective, dan QMCSampler untuk quasi-random search.
Ekosistem integrasi: callback resmi untuk XGBoost, LightGBM, CatBoost, PyTorch Lightning, Keras, Hugging Face Transformers, dan MLflow.
Distributed tuning: multi-worker paralel via JournalStorage atau RDB backend seperti PostgreSQL, tanpa perlu Ray atau Dask untuk kebanyakan use case.
Visualisasi bawaan: optuna.visualization menghasilkan plot Plotly siap pakai untuk optimization history, parallel coordinates, dan parameter importance.
Instalasi dan Setup Optuna 4.x
Install Optuna beserta modul opsional untuk visualisasi dan integrasi:
Sejak Optuna 4.0, banyak integration callback dipindahkan ke package terpisah optuna-integration untuk memangkas dependensi core. Ini adalah breaking change yang sering bikin bingung pengguna 3.x. Kalau Anda upgrade dari versi lama, ganti from optuna.integration import XGBoostPruningCallback menjadi from optuna_integration import XGBoostPruningCallback.
Verifikasi instalasi dengan smoke test singkat:
import optuna
def objective(trial):
x = trial.suggest_float("x", -10, 10)
return (x - 2) ** 2
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=50, show_progress_bar=True)
print(f"Best x: {study.best_value:.4f} at x={study.best_params['x']:.4f}")
Output diharapkan mendekati Best x: 0.0000 at x=2.0000. Optuna akan konvergen ke minimum dalam beberapa puluh trial. Kalau Anda melihat warning ExperimentalWarning, itu normal untuk fitur seperti JournalStorage dan tidak memengaruhi hasil.
Contoh Pertama: Optuna dengan Scikit-Learn RandomForest
Mari kita tuning RandomForestClassifier pada dataset load_breast_cancer. Contoh ini menunjukkan pola dasar yang akan Anda pakai berulang: fungsi objective yang menerima trial, sampling hyperparameter, training + evaluasi dengan cross-validation, lalu return metric.
Beberapa hal penting dari kode di atas. Pertama, saya set seed=42 pada TPESampler untuk reproducibility. Tanpa ini, Anda akan mendapat hasil sedikit berbeda tiap run karena TPE mengandalkan komponen stokastik. Kedua, saya pakai timeout=600 selain n_trials, jadi Optuna akan berhenti mana pun yang tercapai duluan. Ini penting untuk CI/CD di mana Anda punya budget waktu ketat. Ketiga, gunakan step=50 pada n_estimators agar TPE tidak buang-buang trial pada perbedaan yang tidak berarti (perbedaan n_estimators=100 vs 101 praktis nihil).
Kalau Anda sudah nyaman dengan pola dasar, langkah berikutnya adalah memperkaya feature set. Saya sudah bahas ini di panduan feature engineering dengan scikit-learn Pipeline dan ColumnTransformer. Intinya, kombinasikan pipeline feature engineering dengan Optuna dengan cara meletakkan hyperparameter transformer di dalam fungsi objective yang sama.
Memahami Sampler: TPE, CMA-ES, dan Random Sampler
Sampler menentukan bagaimana Optuna memilih nilai hyperparameter berikutnya. Pemilihan sampler yang salah adalah penyebab paling umum tuning yang tidak konvergen. Ada tiga pilihan utama di 2026.
TPESampler (default)
Tree-structured Parzen Estimator adalah pendekatan Bayesian yang membangun dua distribusi probabilitas: satu untuk parameter yang menghasilkan trial terbaik (top 25% by default via gamma), satu untuk sisanya. Sampler kemudian memilih titik yang memaksimalkan rasio l(x)/g(x). TPE efektif untuk 5–30 hyperparameter dan sudah cukup untuk 90% kasus di production.
CmaEsSampler
CMA-ES (Covariance Matrix Adaptation Evolution Strategy) unggul untuk pure continuous parameters dengan interaksi kompleks, misalnya tuning learning rate + momentum + weight decay di deep learning. Kurang cocok untuk kategorikal atau integer, dan butuh warm-up 20–30 trial sebelum sampling adaptifnya kick in.
QMCSampler dan RandomSampler
QMCSampler (Quasi-Monte Carlo) memberikan coverage search space yang lebih merata daripada random murni via Sobol sequence. Berguna untuk baseline atau tahap eksplorasi awal. RandomSampler hanya dipakai sebagai kontrol eksperimen, atau kalau Anda ingin membangun distribusi trial yang seragam untuk analisis post-hoc.
# Combining samplers: gunakan random untuk 20 trial pertama, lalu TPE
sampler = optuna.samplers.TPESampler(
n_startup_trials=20,
n_ei_candidates=24,
multivariate=True,
group=True,
seed=42,
)
study = optuna.create_study(sampler=sampler, direction="maximize")
Parameter multivariate=True (direkomendasikan sejak Optuna 3.0) membuat TPE memodelkan korelasi antar hyperparameter, bukan menganggap independen. Untuk kebanyakan model gradient boosting, ini meningkatkan konvergensi 15–25%. Kombinasikan dengan group=True kalau Anda punya conditional parameter.
Pruner: Menghentikan Trial Tidak Menjanjikan Lebih Awal
Pruner adalah early-stopping untuk trial: kalau di tengah training terlihat bahwa trial ini tidak akan mengalahkan best trial, Optuna akan menghentikannya untuk menghemat compute. Ini bisa menghemat 40–70% total tuning time pada workload yang mahal (training XGBoost 1000 iterasi, deep learning epoch panjang).
Ada tiga pruner utama:
MedianPruner: menghentikan trial jika intermediate value lebih buruk dari median trial sebelumnya pada step yang sama. Default dan konservatif.
HyperbandPruner: berdasarkan algoritma Hyperband, mengalokasikan resource secara adaptif. Sangat efektif tapi butuh minimum jumlah trial yang cukup (biasanya 100+).
SuccessiveHalvingPruner: asynchronous successive halving, cocok untuk distributed tuning.
Contoh integrasi dengan LightGBM, di mana Anda melaporkan intermediate score setiap boosting round:
Untuk model production yang butuh estimasi generalisasi yang stabil, jangan andalkan single train/valid split. Pakai k-fold cross-validation. Ada dua pola populer: (1) CV di dalam fungsi objective, atau (2) manual CV loop dengan reporting per-fold untuk pruning agresif.
Perhatikan n_jobs=4. Optuna akan menjalankan 4 trial paralel dalam thread yang sama. Untuk XGBoost yang sudah multi-threaded internal, kombinasi ini butuh perhitungan. Kalau mesin punya 16 core dan Anda set XGBoost nthread=16 plus Optuna n_jobs=4, Anda akan oversubscribe. Saya biasanya set XGBoost nthread ke 4 dan Optuna n_jobs ke jumlah core dibagi 4.
Optuna vs GridSearchCV dan Hyperopt: Perbandingan Praktis
Pertanyaan yang sering saya dapat: apakah harus migrasi dari GridSearchCV atau Hyperopt ke Optuna? Berikut ringkasan komparasi berdasarkan benchmark internal yang saya jalankan pada 12 dataset e-commerce di 2025.
Aspek
Optuna 4.x
GridSearchCV
Hyperopt
Algoritma default
TPE (Bayesian)
Exhaustive grid
TPE
Trial paralel
Ya (thread/process/distributed)
Ya (joblib)
Terbatas (Spark, MongoDB)
Pruning
Ya (Median, Hyperband, ASHA)
Tidak
Tidak
Conditional search space
Native Python
Tidak natural
Butuh DSL
Persistence
SQLite/RDB/JournalStorage
Manual pickling
MongoDB/Spark Trials
Visualisasi
Plotly bawaan
Tidak ada
Terbatas
Aktif dikembangkan
Ya (rilis rutin)
Stabil
Minimal update sejak 2023
Learning curve
Sedang
Rendah
Sedang-tinggi
Kesimpulan singkat: GridSearchCV masih layak untuk search space kecil (<100 kombinasi) di mana Anda ingin reproducibility mutlak. Hyperopt secara efektif deprecated, karena commit terakhir minimal, dokumentasi tertinggal, dan API TPE-nya kalah dari Optuna. Optuna adalah default 2026 untuk hampir semua use case tuning modern.
Untuk migrasi bertahap, gunakan OptunaSearchCV sebagai drop-in replacement:
Menyimpan dan Melanjutkan Study dengan Storage Backend
Untuk tuning yang butuh berjam-jam atau berjalan di CI/CD, Anda wajib pakai storage backend agar trial history persisten. Optuna mendukung tiga backend utama.
Sederhana dan cukup untuk laptop dev. Jangan pakai untuk multi-worker karena SQLite lock akan jadi bottleneck di atas ~4 worker paralel.
RDB (PostgreSQL/MySQL, multi-worker)
storage = "postgresql+psycopg2://user:pass@db-host:5432/optuna"
study = optuna.create_study(
study_name="xgb-prod", storage=storage, load_if_exists=True,
)
Pilihan production standar. Bisa handle 20+ worker paralel. Butuh instance database dedicated, jadi jangan pakai database aplikasi Anda karena volume write bisa tinggi.
JournalStorage (recommended sejak 4.0)
JournalStorage menulis trial ke append-only log file, cocok untuk shared filesystem seperti NFS atau S3 (lihat Optuna 4.0 release notes). Tidak butuh database server, tapi tetap safe untuk multi-worker.
from optuna.storages import JournalStorage
from optuna.storages.journal import JournalFileBackend
storage = JournalStorage(JournalFileBackend("./optuna-journal.log"))
study = optuna.create_study(
study_name="hpo-run", storage=storage, load_if_exists=True,
direction="maximize",
)
Untuk deployment production, saya biasanya kombinasikan storage backend dengan endpoint FastAPI untuk trigger tuning on-demand. Pola ini saya bahas lebih dalam di panduan FastAPI serving scikit-learn di production.
Multi-Objective Optimization untuk Trade-off Akurasi vs Latency
Di dunia nyata, model terbaik bukan model dengan akurasi tertinggi, melainkan model dengan trade-off terbaik antara akurasi, latency inferensi, dan ukuran memori. Optuna mendukung multi-objective optimization via NSGA-II sampler untuk menemukan Pareto front.
import time
def objective(trial):
params = {
"n_estimators": trial.suggest_int("n_estimators", 50, 800, step=50),
"max_depth": trial.suggest_int("max_depth", 3, 15),
}
model = RandomForestClassifier(**params, random_state=42, n_jobs=-1)
scores = cross_val_score(model, X, y, cv=5, scoring="roc_auc", n_jobs=-1)
model.fit(X, y)
# Ukur latency inference untuk 1000 sample
start = time.perf_counter()
for _ in range(1000):
_ = model.predict(X[:1])
latency_ms = (time.perf_counter() - start) * 1000 / 1000
return scores.mean(), latency_ms
study = optuna.create_study(
directions=["maximize", "minimize"],
sampler=optuna.samplers.NSGAIISampler(seed=42),
)
study.optimize(objective, n_trials=100)
# Ambil Pareto front
for trial in study.best_trials:
print(f"AUC={trial.values[0]:.4f}, latency={trial.values[1]:.3f}ms, params={trial.params}")
Output berupa daftar trial yang tidak didominasi, artinya tidak ada trial lain yang lebih baik di kedua metrik sekaligus. Tim product/ML kemudian bisa memilih titik pada Pareto front sesuai constraint bisnis (misalnya "AUC minimum 0.92 dengan latency di bawah 5ms").
Visualisasi Hasil Optimasi
Modul optuna.visualization menghasilkan plot interaktif Plotly. Empat plot yang wajib Anda tahu:
plot_param_importances adalah yang paling saya andalkan. Ia memakai fANOVA untuk menghitung berapa persen variance objective yang dijelaskan oleh tiap hyperparameter. Kalau learning_rate menyumbang 70% importance dan colsample_bytree cuma 2%, di run berikutnya Anda bisa mempersempit range learning_rate dan fix colsample_bytree ke default.
plot_slice menunjukkan hubungan tiap hyperparameter dengan objective value. Berguna untuk mendeteksi apakah range yang Anda set terlalu sempit (best value ada di ujung range = sinyal untuk perluas) atau ada plateau (fungsi flat = hyperparameter tidak penting untuk dataset ini).
Integrasi Optuna dengan Pipeline Produksi
Untuk deployment production, berikut pattern yang saya rekomendasikan setelah tuning ratusan model batch scoring:
Pisahkan tuning dari training final. Tuning menghasilkan best_params.json. Script training final memuat JSON ini dan melakukan single training pada full dataset dengan random seed berbeda untuk validasi.
Version control study. Simpan storage database di S3 atau NFS bersama dengan git commit hash sebagai study_name. Ini memungkinkan reproduksi tuning dan audit.
Fixed compute budget, bukan fixed n_trials. Set timeout berdasarkan SLA CI, bukan angka trial ajaib. Kombinasi timeout + pruner memberikan hasil terbaik dalam waktu terbatas.
MLflow integration untuk tracking. Gunakan MLflowCallback untuk log tiap trial ke MLflow, sangat berguna saat mengaudit hyperparameter production model dari waktu ke waktu.
Terakhir, untuk mendalami algoritma yang digunakan (terutama detail teoritis TPE dan Hyperband), baca paper Optuna asli (Akiba et al., 2019). Meskipun API sudah banyak berkembang, prinsip algoritmiknya tetap valid.
Pertanyaan yang Sering Ditanyakan
Apakah Optuna gratis untuk komersial?
Ya. Optuna dirilis di bawah lisensi MIT yang mengizinkan pemakaian komersial tanpa royalti. Tidak ada versi enterprise berbayar. Seluruh fitur (termasuk distributed tuning, JournalStorage, dan integrasi ML framework) tersedia gratis di repo GitHub resmi.
Berapa n_trials yang ideal untuk tuning XGBoost?
Untuk 7–10 hyperparameter XGBoost dengan TPE sampler, biasanya 100–300 trial sudah cukup mendekati optimum, dengan diminishing returns setelah 500 trial. Kalau Anda memakai HyperbandPruner, target 200–500 trial karena banyak akan di-prune lebih awal sehingga cost per trial jauh lebih rendah.
Bagaimana cara resume study Optuna yang terhenti?
Buat study dengan storage backend persisten (SQLite, RDB, atau JournalStorage) dan load_if_exists=True. Saat script dijalankan ulang, Optuna akan memuat trial sebelumnya dan melanjutkan optimasi. TPE sampler akan menggunakan seluruh history untuk sampling berikutnya.
Apakah Optuna support GPU untuk deep learning tuning?
Optuna sendiri agnostik terhadap GPU. Ia hanya mengorkestrasi trial. Framework yang Anda tune (PyTorch, TensorFlow, XGBoost dengan device="cuda") menangani GPU. Untuk multi-GPU tuning paralel, jalankan beberapa worker Optuna dengan environment variable CUDA_VISIBLE_DEVICES berbeda menunjuk ke storage backend yang sama.
Kenapa best_value Optuna tidak sesuai dengan performance di test set?
Ini gejala overfitting pada validation set. Solusi: (1) gunakan cross-validation di dalam objective bukan single split, (2) tambah trial minimum sebelum menganggap tuning selesai, (3) hold out true test set yang tidak pernah dilihat Optuna, dan (4) pertimbangkan regularisasi lebih kuat di search space (misalnya reg_lambda, min_child_weight XGBoost).
Apa perbedaan sampler dan pruner di Optuna?
Sampler menentukan kombinasi hyperparameter apa yang dicoba berikutnya berdasarkan hasil trial sebelumnya (TPE, CMA-ES, Random). Pruner menentukan kapan menghentikan trial yang sedang berjalan kalau terlihat tidak menjanjikan (Median, Hyperband, ASHA). Keduanya bekerja bersama: sampler memilih kandidat cerdas, pruner memotong yang buruk lebih awal.
Priya is a senior data engineer with 11 years building analytics platforms, most recently at Stripe where she led the migration of the merchant analytics pipeline from pandas to polars (cut p95 batch latency from 42 minutes to under 6). Before Stripe she spent four years at Mode Analytics writing the query engine that powered customer dashboards, and two years at Etsy on the seller-insights team.
She writes mainly about polars internals, lazy evaluation patterns, and the practical edges of moving production pandas code to polars without breaking analyst muscle memory. Her side project is a 12k-row benchmark suite comparing pandas 2.x, polars, and DuckDB across realistic e-commerce joins.
Priya lives in Oakland, mentors through Women in Data, and is slowly learning to play go.
Pandera 0.22 mengubah kontrak data jadi kode Python berbasis class. Panduan validasi Pandas dan Polars di pipeline produksi, dari DataFrameModel sampai integrasi dbt, Airflow, dan FastAPI.
Playbook production serving model scikit-learn dengan FastAPI: Pydantic V2, lifespan handler, micro-batching, ONNX Runtime, Uvicorn+Gunicorn, dan monitoring Prometheus untuk p99 di bawah 30 ms.