Alur Kerja scikit-learn untuk Analis: dari Data Mentah ke Prediksi
TL;DR
Alur kerja scikit-learn punya enam tahap: pisah data latih dan data uji duluan, susun langkah pembersihan dalam Pipeline, latih model, ukur pakai metrik yang sesuai kasusnya, cari parameter terbaik lewat cross-validation, lalu simpan modelnya pakai joblib. Pipeline itu bagian yang paling sering dilewat, padahal dia yang mencegah kebocoran data dari data uji ke proses pelatihan.
Alur kerja scikit-learn selalu sama urutannya: pisah data, susun pipeline pembersihan, latih model, ukur hasilnya, cari parameter terbaik, simpan modelnya.
Banyak tutorial mulai dari nama algoritma. Menurutku itu urutan yang bikin orang nyasar.
Model yang kamu pilih biasanya nyumbang bagian kecil dari kualitas hasil. Yang nentuin justru cara kamu nyiapin data dan cara kamu ngukur.
Di bawah ini alur lengkapnya dengan satu kasus nyata: memprediksi pelanggan Toko Berkah yang bakal berhenti belanja.
Apa itu scikit-learn dan kapan dipakai?
scikit-learn adalah library Python buat machine learning klasik, mulai dari klasifikasi, regresi, sampai pengelompokan. Semua modelnya punya antarmuka yang sama: fit() buat belajar, predict() buat menebak. Begitu kamu paham satu model, sisanya ngikut.
Pakai scikit-learn kalau datamu berbentuk tabel dengan baris dan kolom, dan jumlahnya masih muat di memori laptop. Buat gambar, suara, atau teks panjang, ada library lain yang lebih cocok.
Tiga tipe pertanyaan yang paling sering dijawab pakai library ini:
- Klasifikasi. Pelanggan ini bakal berhenti langganan atau enggak?
- Regresi. Berapa omzet cabang ini minggu depan? Konsepnya ada di regression.
- Pengelompokan. Pelanggan aku terbagi jadi berapa kelompok perilaku?
Kenapa data uji harus dipisah paling awal?
Supaya kamu punya data yang beneran belum pernah dilihat model. Kalau kamu bersihin dan skalain seluruh data dulu baru dipisah, informasi dari data uji ikut masuk ke proses pelatihan. Namanya kebocoran data, dan efeknya skor latihan kelihatan bagus tapi model gagal di dunia nyata.
from sklearn.model_selection import train_test_split
X = df.drop(columns=["berhenti"])
y = df["berhenti"]
X_latih, X_uji, y_latih, y_uji = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y,
)
Dua argumen yang wajib kamu isi. random_state bikin pembagiannya sama tiap kali dijalankan, jadi hasilnya bisa diulang orang lain. stratify=y jaga supaya proporsi kelasnya sama di data latih dan data uji.
Kalau datamu punya urutan waktu, jangan pakai pembagian acak. Latih pakai data lama, uji pakai data terbaru. Model yang belajar dari masa depan buat menebak masa lalu selalu kelihatan hebat dan selalu gagal waktu dipakai.
Gimana cara nyiapin kolom kategori dan numerik?
Model scikit-learn cuma nerima angka. Kolom teks kayak nama cabang harus diubah dulu jadi angka, dan kolom angka biasanya perlu diskalakan supaya rentangnya seragam. ColumnTransformer ngerjain dua perlakuan berbeda itu di satu tempat.
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
kolom_angka = ["umur_pelanggan_hari", "total_belanja", "jumlah_transaksi", "jeda_hari_terakhir"]
kolom_kategori = ["cabang", "kanal_belanja"]
olah_angka = Pipeline([
("isi_kosong", SimpleImputer(strategy="median")),
("skala", StandardScaler()),
])
olah_kategori = Pipeline([
("isi_kosong", SimpleImputer(strategy="most_frequent")),
("kode", OneHotEncoder(handle_unknown="ignore")),
])
praproses = ColumnTransformer([
("angka", olah_angka, kolom_angka),
("kategori", olah_kategori, kolom_kategori),
])
Argumen handle_unknown="ignore" penting banget. Tanpa itu, model kamu bakal error waktu ketemu nama cabang baru yang gak ada di data latih.
SimpleImputer ngisi sel kosong. Buat kolom angka pakai median karena lebih tahan sama nilai ekstrem, buat kolom teks pakai nilai yang paling sering muncul.
Sebelum sampai sini, pastiin dulu kualitas kolomnya. Kolom dengan 60 persen nilai kosong lebih baik dibuang daripada ditambal. Cek panduan data quality buat daftar hal yang perlu diperiksa.
Gimana bikin Pipeline yang aman dari kebocoran?
Gabungin praproses dan model jadi satu objek. Begitu digabung, semua langkah pembersihan otomatis cuma belajar dari data latih, dan otomatis diterapkan ulang ke data uji dengan aturan yang sama.
from sklearn.linear_model import LogisticRegression
model = Pipeline([
("praproses", praproses),
("klasifikasi", LogisticRegression(max_iter=1000, class_weight="balanced")),
])
model.fit(X_latih, y_latih)
Satu baris fit() tadi ngerjain lima hal berurutan: ngisi sel kosong, nyekalakan angka, ngubah teks jadi kolom biner, lalu ngelatih model.
class_weight="balanced" bikin model kasih bobot lebih ke kelas yang jarang muncul. Berguna waktu cuma 8 persen pelangganmu yang berhenti.
Mulai dari model sederhana. Logistic regression cepat dilatih dan koefisiennya bisa dijelaskan ke tim bisnis. Kalau skornya udah kecatat, baru bandingin sama model yang lebih rumit.
Metrik mana yang dipakai buat data gak seimbang?
Jangan pakai akurasi sendirian. Kalau cuma 8 persen pelanggan yang berhenti, model yang menebak semua orang bertahan otomatis dapat akurasi 92 persen tanpa belajar apa pun. Pakai recall, precision, dan ROC AUC supaya kelihatan model kamu beneran nangkep pola atau enggak.
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
y_tebak = model.predict(X_uji)
probabilitas = model.predict_proba(X_uji)[:, 1]
print(classification_report(y_uji, y_tebak, digits=3))
print(confusion_matrix(y_uji, y_tebak))
print("ROC AUC:", round(roc_auc_score(y_uji, probabilitas), 3))
| Metrik | Artinya | Pakai kalau |
|---|---|---|
| Precision | Dari yang ditebak berhenti, berapa yang bener | Biaya salah tebak mahal, misalnya kasih diskon |
| Recall | Dari yang beneran berhenti, berapa yang ketangkap | Kehilangan pelanggan lebih mahal dari biaya promo |
| F1 | Gabungan precision dan recall | Butuh satu angka ringkas |
| ROC AUC | Kemampuan model mengurutkan risiko | Bandingin beberapa model sekaligus |
Pilih metrik utamanya sebelum kamu latih model. Kalau dipilih belakangan, kamu bakal tergoda milih yang angkanya paling bagus.
Ambang batas gak harus 0,5
Fungsi predict() pakai batas 0,5 secara default. Kamu bisa geser sesuai biaya bisnisnya.
tebakan = (probabilitas >= 0.35).astype(int)
Nurunin batas jadi 0,35 bikin lebih banyak pelanggan ketangkap sebagai berisiko, dengan konsekuensi lebih banyak yang salah tebak. Trade-off ini keputusan bisnis, bukan keputusan teknis.
Gimana cara pilih parameter model?
Pakai cross-validation, jangan coba-coba di data uji. Data uji cuma boleh disentuh sekali di akhir. Kalau kamu bolak-balik nyetel parameter sambil ngintip skor data uji, angka akhirnya udah gak bisa dipercaya.
from sklearn.model_selection import cross_val_score, StratifiedKFold
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
skor = cross_val_score(model, X_latih, y_latih, cv=cv, scoring="roc_auc")
print("rata-rata:", skor.mean().round(3), "| sebaran:", skor.std().round(3))
Angka sebaran sama pentingnya sama rata-rata. Skor 0,81 dengan sebaran 0,02 jauh lebih bisa dipercaya daripada 0,84 dengan sebaran 0,11.
from sklearn.model_selection import GridSearchCV
kisi = {"klasifikasi__C": [0.01, 0.1, 1, 10]}
pencarian = GridSearchCV(model, kisi, cv=cv, scoring="roc_auc", n_jobs=-1)
pencarian.fit(X_latih, y_latih)
print(pencarian.best_params_)
print(round(pencarian.best_score_, 3))
Perhatiin dua garis bawah di klasifikasi__C. Itu cara scikit-learn nunjuk parameter di dalam langkah pipeline bernama klasifikasi.
Penjelasan tiap parameter dan daftar model lengkapnya ada di panduan resmi scikit-learn.
Contoh kasus: prediksi pelanggan berhenti belanja di Toko Berkah
Toko Berkah punya 8.400 pelanggan terdaftar di program member. Definisi berhenti yang dipakai: gak ada transaksi selama 90 hari berturut-turut.
Fitur yang dipakai cuma lima, semuanya dari data transaksi yang udah ada:
| Kolom | Artinya |
|---|---|
| umur_pelanggan_hari | Lama jadi member |
| total_belanja | Akumulasi belanja 12 bulan terakhir |
| jumlah_transaksi | Banyaknya kunjungan |
| jeda_hari_terakhir | Hari sejak transaksi terakhir |
| cabang | Cabang yang paling sering didatangi |
Hasilnya: ROC AUC 0,83 di data uji, dengan recall 0,71 di ambang 0,35. Artinya dari setiap 100 pelanggan yang beneran bakal berhenti, model nangkep 71 orang.
Yang lebih berguna daripada skornya adalah bobot fiturnya. Kolom jeda_hari_terakhir nyumbang jauh lebih besar dari empat kolom lain digabung.
Temuan praktisnya: pelanggan yang gak transaksi lebih dari 34 hari punya peluang berhenti 3,2 kali lipat dibanding yang di bawah itu. Angka 34 hari itu yang akhirnya dipakai sebagai pemicu kirim promo, dan aturan sederhana ini bisa jalan tanpa model sama sekali.
Model yang bagus sering kali ngasih kamu aturan sederhana, bukan sistem rumit. Buat langkah lanjutannya, hasil prediksi ini enak dipasangin sama segmentation pelanggan biar promonya gak disamaratakan.
Gimana simpan dan pakai modelnya lagi?
import joblib
joblib.dump(pencarian.best_estimator_, "model_berhenti.joblib")
# di skrip lain
model = joblib.load("model_berhenti.joblib")
risiko = model.predict_proba(pelanggan_baru)[:, 1]
Karena yang disimpan adalah seluruh pipeline, kamu gak perlu ngulang langkah pembersihan di skrip prediksi. Data mentah masuk, probabilitas keluar.
Simpan juga versi scikit-learn yang kamu pakai di file requirements.txt. Model yang dilatih di versi lama kadang gak bisa dibuka di versi baru.
Kalau prediksinya mau jalan tiap pagi, bungkus jadi skrip terjadwal seperti di panduan dari notebook ke skrip terjadwal.
Kesalahan umum waktu pakai scikit-learn
1. Nyekalakan data sebelum dipisah
Kesalahan paling sering dan paling gak kelihatan. Rata-rata dari data uji ikut masuk ke penskalaan, skor jadi terlalu bagus. Pipeline mencegah ini otomatis.
2. Masukin kolom yang belum ada saat prediksi
Kolom total_belanja_setelah_berhenti jelas bikin skor sempurna dan modelnya gak berguna. Tanya untuk setiap kolom: nilai ini udah tersedia gak di saat aku perlu memprediksi?
3. Nilai ID ikut jadi fitur
Nomor member atau nomor transaksi kadang punya pola urutan yang kebetulan berkorelasi. Buang kolom ID dari fitur.
4. Ngejar skor tanpa patokan awal
Sebelum latih apa pun, catat skor dari aturan paling bodoh, misalnya tebak semua bertahan. Kalau modelmu cuma unggul tipis dari itu, kerumitannya gak sepadan.
5. Lupa data berubah setelah beberapa bulan
Perilaku pelanggan geser. Jadwalkan pengukuran ulang skor model tiap kuartal pakai data terbaru, dan latih ulang kalau turunnya nyata.
FAQ
Perlu jago matematika buat pakai scikit-learn?
Buat mulai, gak. Antarmuka scikit-learn seragam, jadi kamu cukup paham pola fit dan predict. Yang wajib kamu pahami justru bagian non-matematisnya: kenapa data uji harus dipisah duluan, dan kenapa akurasi bisa menipu di data yang gak seimbang. Matematika di balik modelnya bisa dipelajari sambil jalan.
Apa bedanya fit, transform, dan fit_transform?
Fit itu belajar dari data, misalnya nyatet rata-rata kolom buat penskalaan. Transform itu menerapkan hasil belajarnya. fit_transform ngelakuin keduanya sekaligus. Aturannya: fit cuma boleh dijalankan di data latih. Di data uji kamu cuma boleh transform, kalau gak informasi dari data uji bocor ke model.
Kenapa akurasi 95 persen bisa jadi model yang jelek?
Kalau cuma 5 persen pelanggan kamu yang berhenti langganan, model yang selalu menebak semua orang bertahan otomatis dapat akurasi 95 persen tanpa belajar apa-apa. Buat kasus yang timpang begini, pakai recall, precision, atau ROC AUC. Lihat juga confusion matrix supaya kamu tau jenis salahnya di mana.
Berapa banyak data minimal buat latih model?
Gak ada angka pasti, tapi patokan praktis: minimal beberapa ratus contoh untuk kelas yang paling jarang muncul. Kalau pelanggan yang berhenti cuma 40 orang, model bakal ngapalin ciri 40 orang itu dan gagal di data baru. Dalam kondisi begitu, analisis segmentasi biasa lebih berguna daripada model prediksi.
Kapan sebaiknya pakai model yang lebih rumit?
Setelah kamu punya model sederhana yang jalan dan skornya kecatat. Logistic regression atau decision tree jadi patokan awal yang bagus karena cepat dilatih dan hasilnya gampang dijelaskan ke tim bisnis. Naik ke random forest atau gradient boosting cuma kalau selisih skornya cukup besar untuk membenarkan tambahan kerumitan.
Langkah berikutnya
Tiga hal yang paling nentuin hasil: pisah data uji sebelum ngapa-ngapain, bungkus semua langkah pembersihan dalam Pipeline, dan pilih metrik sebelum latih model.
Coba mulai dari satu pertanyaan bisnis yang jawabannya cuma ya atau enggak. Lima kolom fitur udah cukup buat model pertama.
Buat tahap eksplorasi datanya, beberapa trik di 28 trik Jupyter Notebook bikin proses coba-coba fitur jadi jauh lebih cepat.
Kasus prediksi apa yang paling relevan di kerjaan kamu sekarang? Tulis di komentar.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Pandas groupby: Agregasi Data ala Pivot di Python (2026)
groupby ngelompokin baris berdasarkan kolom, lalu ngitung ringkasan per grup kayak total atau rata-rata. Ini pivot-nya pandas.
Pandas to_excel: Ekspor DataFrame ke Excel (2026)
to_excel nyimpen DataFrame pandas jadi file Excel .xlsx. Ini cara pakainya, dari satu sheet sampai banyak sheet, plus setelan yang bikin hasilnya rapi.
Pandas read_excel: Baca File Excel di Python
pandas read_excel baca file Excel jadi DataFrame, bisa pilih sheet tertentu dan lompatin baris judul yang berantakan. Ini cara pakai plus parameter penting dengan contoh data toko.