Membangun model kompetitif: gradient boosting dengan XGBoost & LightGBM, teknik ensemble (bagging, boosting, stacking), dan hyperparameter tuning yang terstruktur — dilengkapi praktik model kompetitif untuk churn

Setelah di episode 24 kita membawa model ke produksi, pada episode ini kita membuat model yang layak diproduksi: advanced modeling & ensemble. Baseline Logistic Regression (episode 9) sudah cukup untuk memulai, tetapi untuk masalah yang kompetitif — kompetisi, bisnis dengan margin tipis, akurasi tinggi — kalian butuh arsenal yang lebih kuat.
Mengapa ensemble mendominasi data tabular? Karena kombinasi model yang beragam hampir selalu lebih akurat dan lebih stabil daripada satu model. Dan di antara semua teknik ensemble, gradient boosting (XGBoost, LightGBM) telah menjadi standar de facto untuk data tabular sejak lebih dari satu dekade. Episode ini membangun kemampuan itu plus tuning yang terstruktur — bukan tuning asal.
Ensemble menggabungkan banyak model untuk prediksi akhir. Tiga pendekatan utama:
| Pendekatan | Ide | Contoh |
|---|---|---|
| Bagging | Banyak model paralel, hasil dirata-rata | Random Forest |
| Boosting | Model berurutan, tiap model membetulkan error sebelumnya | XGBoost, LightGBM |
| Stacking | Model "meta" belajar dari output model dasar | StackingClassifier |
Random Forest melatih banyak decision tree pada sampel acak data & fitur, lalu merata-rata prediksi mereka — mengurangi variance (episode 9) tanpa menaikkan bias.
Gradient boosting membangun pohon berurutan: setiap pohon baru dilatih untuk memprediksi sisa error (residual) dari kombinasi pohon sebelumnya.
Kekuatannya: model kompleks secara bertahap, tiap langkah diperbaiki oleh pohon berikutnya. Kelemahannya: sensitif terhadap noise & overfit jika tidak dikendalikan (learning rate, regularisasi).
pip install xgboost lightgbmimport pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
import xgboost as xgb
import lightgbm as lgb
df = pd.read_csv("telco_churn.csv")
X = df.drop(columns=["churn"])
y = df["churn"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
params = {"random_state": 42, "n_estimators": 300}
xgb_model = xgb.XGBClassifier(max_depth=6, learning_rate=0.05, **params)
lgb_model = lgb.LGBMClassifier(num_leaves=31, learning_rate=0.05, **params)
for name, model in [("XGBoost", xgb_model), ("LightGBM", lgb_model)]:
model.fit(X_train, y_train)
auc = roc_auc_score(y_test, model.predict_proba(X_test)[:, 1])
print(f"{name:9s} AUC test: {auc:.3f}")Kedua library punya prinsip yang sama (boosting) dengan implementasi berbeda: XGBoost unggul untuk dataset kecil-menengah dan fitur kategorikal; LightGBM lebih cepat di dataset besar dan hemat memori. Pada data tabular, keduanya hampir selalu mengalahkan model linier baseline — dan episode ini menantang kalian untuk membuktikannya sendiri.
Tip
Aturan praktis yang hampir selalu benar: untuk data tabular, XGBoost/LightGBM adalah baseline yang kuat — sering lebih baik dari deep learning. Gunakan model ini sebagai titik acuan sebelum mencoba pendekatan lain. Deep learning baru menang jelas pada data teks, gambar, dan audio.
Tuning asal-asalan = overfit ke test set (episode 11) dan membuang waktu. Gunakan cross-validation terstruktur:
from sklearn.model_selection import RandomizedSearchCV
param_grid = {
"learning_rate": [0.01, 0.05, 0.1],
"max_depth": [3, 5, 7],
"subsample": [0.7, 0.9, 1.0],
"n_estimators": [200, 400],
}
search = RandomizedSearchCV(
xgb.XGBClassifier(random_state=42),
param_grid, n_iter=20,
cv=5, scoring="roc_auc", n_jobs=-1, random_state=42,
)
search.fit(X_train, y_train)
print("best params:", search.best_params_)
print("best AUC CV:", round(search.best_score_, 3))Prinsip yang harus dipegang: tuning terjadi di validation fold, evaluasi final di test set sekali saja. RandomizedSearchCV dengan 20 kombinasi × 5 fold = 100 training — jauh lebih efisien daripada grid lengkap, dan cukup untuk menemukan area parameter yang baik.
Urutan prioritas tuning untuk gradient boosting (pengalaman praktisi):
Setel yang paling berpengaruh dulu, sisanya tetap default. Ini menghindari ruang pencarian yang meledak.
Stacking menggabungkan model berbeda dan melatih model meta di atasnya:
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
base = [
("lr", LogisticRegression(max_iter=1000)),
("rf", xgb.XGBClassifier(n_estimators=200, max_depth=5)),
("lgb", lgb.LGBMClassifier(n_estimators=200, num_leaves=31)),
]
stack = StackingClassifier(
estimators=base,
final_estimator=LogisticRegression(),
cv=5,
)
stack.fit(X_train, y_train)
auc = roc_auc_score(y_test, stack.predict_proba(X_test)[:, 1])
print("stacking AUC:", round(auc, 3))Stacking bernilai ketika model dasar beragam — jika semuanya sama, meta-model tidak belajar apa-apa. Di kompetisi Kaggle, stacking model kuat dengan regularisasi meta-model adalah kunci papan atas; di industri, ia dipakai saat margin akurasi sangat berharga.
| Pitfall | Dampak | Solusi |
|---|---|---|
| Tuning di test set berulang | Test bocor, angka palsu | Tuning CV, test sekali |
| Grid search raksasa | Waktu terbuang | RandomizedSearch + prioritas parameter |
| Ensemble tanpa keberagaman | Tidak ada peningkatan | Pilih model yang berbeda |
| Boosting tanpa regularisasi | Overfit diam-diam | Learning rate + early stopping |
| Mengabaikan interpretability | Model tak bisa dijelaskan | SHAP (episode 20) untuk boosting |
Inti yang harus dibawa pulang:
Di episode 26 selanjutnya kita akan membahas ekosistem & tren modern 2026 — agentic analytics, semantic layers, dan peta industri yang memandu arah kalian ke depan. Sampai jumpa di episode 26!