Penyelidikan chapter sebelumnya berakhir pada satu kesimpulan: model churn perlu belajar dari perilaku pelanggan yang baru. Namun mengganti model produksi bukan pekerjaan semalam — model baru yang belum teruji bisa saja lebih buruk dari model lama, dan sekali keputusan retensi salah sasaran, kepercayaan tim retensi ikut runtuh. Babak operasional menyediakan prosedur yang menjawab kekhawatiran itu: pola juara dan penantang (champion-challenger), di mana model baru harus membuktikan diri melawan model berkuasa sebelum dipromosikan — dan selalu ada jalan pulang bila ternyata salah. Pada chapter ini kita jalankan prosedurnya tuntas untuk kedai kita.
Kapan Model Perlu Diperbarui #
Pelatihan ulang (retraining) memakan waktu dan menimbulkan risiko, sehingga pemicunya perlu jelas. Empat pemicu ini mencakup hampir seluruh kasus di praktik:
| Pemicu | Contoh di kedai | Sifat pemicu |
|---|---|---|
| Terjadwal | latih ulang tiap kuartal dengan data terakumulasi | rutin, bisa direncanakan |
| Data drift terdeteksi | kunjungan turun 47%, belanja naik 56% (chapter sebelumnya) | berbasis alarm pemantauan |
| Akurasi golden set melorot | skor turun di bawah ambang layanan 0,75 | berbasis performa |
| Perubahan bisnis yang disengaja | program member baru mengubah makna kolom belanja | diketahui dari rapat, bukan dari data |
Pemicu terjadwal adalah jaring pengaman terakhir: sekalipun tidak ada alarm, model tetap disegarkan berkala agar tidak semakin jauh tertinggal dari kenyataan. Sisanya adalah alarm dini — makin cepat pemicu tertangkap, makin kecil kerusakan yang ditimbulkan. Apa pun pemicunya, tindakan yang dijalankan sama: bangunkan kandidat baru, adu melawan juara, putuskan dengan bukti.
Pola Juara dan Penantang #
Aturan mainnya sederhana: model yang sedang melayani produksi disebut juara (champion); kandidat pengganti disebut penantang (challenger). Keduanya diadu pada satu wasit yang sama — golden set, yaitu cuplikan data terbaru yang berlabel dan tidak pernah ikut pelatihan. Penantang hanya dipromosikan bila mengalahkan juara pada metrik utama; jika kalah, juara tetap bertahan dan penantang menjadi catatan bahwa ide itu sudah dicoba.
Pada kasus kita, pola hubungan fitur-target memang berubah: dahulu churn didorong jarangnya kunjungan, kini didorong besarnya belanja per kunjungan. Kita bangun tiga set data — pola lama untuk melatih juara, pola baru sebagai tambahan data penantang, dan golden set dari pola terbaru sebagai wasit.
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
def buat_data(n, seed, bobot_kunjungan, bobot_belanja):
rng = np.random.default_rng(seed)
kunjungan = rng.integers(1, 15, n)
belanja = rng.integers(50, 350, n)
skor = bobot_kunjungan * (8 - kunjungan) + bobot_belanja * (belanja - 180) + rng.normal(0, 3, n)
churn = (skor > np.quantile(skor, 0.6)).astype(int)
return pd.DataFrame({"kunjungan": kunjungan, "belanja": belanja, "churn": churn})
data_lama = buat_data(60, 42, 0.8, 0.02)
data_baru = buat_data(30, 7, 0.3, 0.06)
golden_set = buat_data(24, 2024, 0.3, 0.06)
fitur = ["kunjungan", "belanja"]
juara = LogisticRegression(max_iter=1000).fit(data_lama[fitur], data_lama["churn"])
kandidat = LogisticRegression(max_iter=1000).fit(
pd.concat([data_lama, data_baru])[fitur],
pd.concat([data_lama, data_baru])["churn"],
)
baris = []
for nama, model in [("juara v1 (data lama)", juara), ("kandidat v2 (lama + baru)", kandidat)]:
prediksi = model.predict(golden_set[fitur])
benar = prediksi == golden_set["churn"].values
positif = golden_set["churn"].values == 1
baris.append({
"model": nama,
"akurasi_golden": f"{benar.mean():.3f}",
"recall_golden": f"{benar[positif].mean():.3f}",
})
tabel = pd.DataFrame(baris)
print(tabel.to_string(index=False))
print()
recall_juara = float(tabel.loc[0, "recall_golden"])
recall_kandidat = float(tabel.loc[1, "recall_golden"])
if recall_kandidat > recall_juara:
print("keputusan: PROMOSI - kandidat v2 menjadi model produksi baru")
else:
print("keputusan: TETAP - juara v1 dipertahankan sebagai model produksi")Output yang Dihasilkan:
model akurasi_golden recall_golden
juara v1 (data lama) 0.750 0.800
kandidat v2 (lama + baru) 0.792 0.900
keputusan: PROMOSI - kandidat v2 menjadi model produksi baruMari kita telaah bagian-bagian pentingnya:
- Baris 6-12 (pembangkit data berpola): fungsi
buat_datamenerima bobot tiap fitur, sehingga pola lama (kunjungan berbobot 0,8) dan pola baru (belanja berbobot 0,06) lahir dari kode yang sama — membedah perbedaannya jadi mudah. - Baris 15-17 (tiga peran data):
data_lamamelatih juara,data_barumenambah pengalaman penantang, dangolden_setmurni menjadi wasit — tidak pernah menyentuh pelatihan keduanya. - Baris 20-25 (dua model, dua pengalaman): juara belajar dari 60 baris pola lama; kandidat belajar dari 90 baris gabungan. Satu-satunya perbedaan prosedur adalah datanya — syarat eksperimen terkendali yang kita pegang sejak chapter Membandingkan Model .
- Baris 28-36 (adu di hadapan wasit): kedua model memprediksi golden set yang sama; akurasi dan recall dihitung dengan cara yang sama persis.
- Baris 42-47 (keputusan dari angka): aturan promosi diuji pada recall — metrik utama program retensi sejak awal. Kandidat menang 0,900 lawan 0,800, dengan akurasi yang ikut naik; keputusan PROMOSI keluar dari kode, bukan dari kata hati.
Promosi dan Jalan Pulang #
Promosi bukan akhir prosedur — ia adalah awal masa uji. Artefak kandidat mendapat status produksi, tetapi artefak juara lama tidak dibuang: ia menjadi jaminan. Bila metrik pemantauan memburuk dalam masa transisi (katakanlah, dua pekan pertama), tim tinggal mengembalikan status produksi ke versi lama — tindakan yang disebut rollback. Registri sederhana berikut memperlihatkan cara kerjanya:
registri = {
"model_churn_v1.joblib": {"status": "arsip", "catatan": "dilatih pada 60 baris data lama"},
"model_churn_v2.joblib": {"status": "produksi", "catatan": "dilatih pada 90 baris lama+baru"},
}
def tampilkan_registri(registri):
for berkas, info in registri.items():
print(f"{berkas:22} status={info['status']:8} {info['catatan']}")
print("registri setelah promosi v2:")
tampilkan_registri(registri)
registri["model_churn_v2.joblib"]["status"] = "arsip"
registri["model_churn_v1.joblib"]["status"] = "produksi"
print()
print("registri setelah rollback ke v1:")
tampilkan_registri(registri)Output yang Dihasilkan:
registri setelah promosi v2:
model_churn_v1.joblib status=arsip dilatih pada 60 baris data lama
model_churn_v2.joblib status=produksi dilatih pada 90 baris lama+baru
registri setelah rollback ke v1:
model_churn_v1.joblib status=produksi dilatih pada 60 baris data lama
model_churn_v2.joblib status=arsip dilatih pada 90 baris lama+baruMari kita telaah bagian-bagian pentingnya:
- Baris 1-4 (registri versi): satu entri per artefak, lengkap dengan status dan asal-usul data latihnya — versi ringan dari metadata yang kita tulis di chapter Menyimpan Model .
- Baris 15-16 (penukaran status): rollback hanyalah dua baris karena kedua artefak tetap ada di tempatnya; yang berubah hanyalah penunjuk “siapa yang melayani produksi”.
- Bacaan menyeluruh: di produksi nyata, registri semacam ini hidup di alat seperti MLflow dengan syarat promosi yang tercatat — siapa menyetujui, metrik apa yang jadi dasar — sehingga setiap perubahan model bisa diaudit bertahun kemudian.
Prosedur lengkapnya kini berbentuk lingkaran yang sehat: pantau (chapter Pemantauan Model ), deteksi perubahan, latih kandidat, adu di golden set, promosi bila menang, rollback bila buruk — lalu kembali memantau. Model kedai kita pun selalu punya cara menjadi lebih baik tanpa pernah mempertaruhkan layanan.
Rangkuman #
- Empat pemicu pembaruan: terjadwal, data drift, akurasi golden set melorot, dan perubahan bisnis yang disengaja — semuanya bermuara pada prosedur yang sama.
- Pola juara-penantang mengharuskan kandidat mengalahkan model berkuasa pada golden set yang sama dan netral; keputusan promosi keluar dari aturan metrik, bukan kesan sesaat.
- Kasus kita berakhir PROMOSI: kandidat yang belajar dari 90 baris mengungguli juara pada recall 0,900 lawan 0,800 dan akurasi 0,792 lawan 0,750.
- Registri versi menjaga jalan pulang: artefak lama tidak dibuang, status produksi hanya berpindah, dan rollback adalah tindakan dua baris yang tercatat asal-usulnya.
Dengan prosedur pembaruan yang aman, satu pertanyaan terakhir menggantung di babak deployment: apakah semua masalah memang layak dijawab dengan model yang dipasangkan ke produksi? Kapan deployment sebaiknya tidak dilakukan, dan kewajiban apa yang menyertai begitu model dipakai orang? Chapter penutup section ini menjawabnya: Batasan Deployment .
Referensi: