Idenya
Setiap masalah supervised ML disiapkan dengan cara yang sama:
- X, yaitu fitur: apa yang kamu ketahui tentang setiap contoh, satu baris per contoh, satu kolom per fitur. (Disebut juga input, prediktor, variabel.)
- y, yaitu label atau target: jawaban untuk setiap contoh.
Model mempelajari sebuah fungsi dari X ke y. Lalu muncul pertanyaan pentingnya: apakah model itu berfungsi pada contoh yang belum pernah dilihatnya? Untuk menjawab dengan jujur, kamu menyembunyikan sebagian contoh selama training lalu mengujinya sesudahnya.
X dan y
Contoh utama di track ini adalah churn pelanggan: memprediksi pelanggan mana yang akan berhenti membeli, supaya toko bisa menawarkan sesuatu sebelum mereka pergi. Setiap baris churn.csv adalah satu pelanggan. Beberapa kolom mendeskripsikan perilakunya, dan satu kolom, churned, mencatat apakah mereka benar-benar pergi. Dalam istilah machine learning, kolom-kolom deskriptif itu adalah fitur (X) dan jawaban yang ingin kamu prediksi adalah label (y):
import pandas as pd
churn = pd.read_csv("churn.csv")
features = ["tenure_months", "orders_90d", "avg_order_value", "days_since_last_order", "support_tickets", "app_user"]
X = churn[features]
y = churn["churned"]
print(X.shape, y.shape)
print(X.head(3))
(400, 6) (400,)
tenure_months orders_90d avg_order_value days_since_last_order support_tickets app_user
0 12 7 163000 47 1 0
1 33 4 472000 73 1 0
2 5 0 124000 14 0 0
Xberbentuk 2-D: 400 baris × 6 fitur. scikit-learn selalu mengharapkan X berbentuk 2-D (ingatreshape(-1, 1)dari track NumPy).yberbentuk 1-D: satu label per baris, dalam urutan yang sama.customer_idbukan fitur: ia hanya sebuah nama. Model bisa "belajar" bahwa customer 1003 churn, yang tidak memberi tahu apa pun tentang customer baru.
Fitur kategoris
Model melakukan perhitungan, jadi kategori teks seperti segment ("Consumer", "Business") harus menjadi angka. Cara standarnya adalah one-hot encoding: satu kolom 0/1 per kategori.
encoded = pd.get_dummies(churn[["segment"]], dtype=int)
print(encoded.head(3))
segment_Business segment_Consumer
0 0 1
1 1 0
2 1 0
Kenapa tidak cukup Consumer = 0, Business = 1? Dengan dua kategori itu tidak masalah. Dengan tiga (Jakarta = 0, Bandung = 1, Surabaya = 2), angka akan menyiratkan urutan dan jarak ("Surabaya dua kali Bandung"), yang tidak masuk akal. One-hot menghindari mengarang hubungan yang tidak ada. Modul preprocessing membahas ini dengan alat-alat scikit-learn.
Kenapa butuh set test?
Bayangkan guru yang memberi murid-muridnya soal ujian yang persis sama untuk latihan. Setiap murid mendapat nilai 100%, dan nilai itu tidak memberi tahu apakah mereka benar-benar belajar. Model yang dinilai pada data yang dipakai untuk melatihnya punya masalah yang sama: ia mungkin sudah menghafal contoh-contohnya.
Jadi kamu membagi datanya:
- set training (biasanya 70–80%): model belajar darinya.
- set test (sisanya): dikunci, dipakai sekali di akhir untuk memperkirakan performa pada data baru.
Ini pembagian manual dengan NumPy, supaya kamu melihat bahwa tidak ada sihir apa pun:
import numpy as np
rng = np.random.default_rng(42)
order = rng.permutation(len(churn))
cut = int(len(churn) * 0.75)
train_idx, test_idx = order[:cut], order[cut:]
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
print(len(X_train), len(X_test))
print(round(y_train.mean(), 3), round(y_test.mean(), 3))
300 100
0.327 0.36
Mengacak dulu itu penting: kalau file-nya terurut (semua yang churn ada di akhir), pembagian tanpa pengacakan akan menaruh semuanya di set test.
train_test_split
Mengacak lalu memotong data secara manual memang bisa, tapi mudah salah, dan kamu akan melakukannya di hampir setiap proyek. scikit-learn mengerjakan semuanya dalam satu pemanggilan:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
print(X_train.shape, X_test.shape)
print(round(y_train.mean(), 3), round(y_test.mean(), 3))
(300, 6) (100, 6)
0.337 0.33
test_size=0.25: seperempatnya masuk ke set test.random_state=42: sebuah seed, supaya pembagiannya sama di setiap eksekusi (pelajaran dari modul random NumPy).stratify=y: menjaga tingkat churn tetap sama di kedua bagian. Penting saat salah satu kelas lebih jarang.
Urutan keempat hasilnya selalu X_train, X_test, y_train, y_test.
Leakage: saat jawabannya menyelinap ke fitur
Data leakage terjadi saat sebuah fitur berisi informasi yang tidak akan kamu miliki saat prediksi dibuat, sering kali versi samaran dari jawabannya. Model terlihat luar biasa saat diuji dan gagal saat dipakai sungguhan.
Contoh di sebuah toko:
- Memprediksi churn dengan fitur "jumlah voucher retensi yang dikirim". Voucher dikirim karena customer memang sudah mulai pergi: fitur itu adalah akibat dari label-nya.
- Memprediksi belanja bulan depan memakai "total belanja tahun ini", di mana "tahun ini" mencakup bulan depan.
- Menghitung rata-rata nilai order atas semua data (training dan test) lalu memakainya sebagai fitur: informasi test bocor ke training.
Untuk setiap fitur, tanyakan: "pada saat aku membuat prediksi ini, apakah aku sudah tahu nilai ini?" Kalau tidak, itu bocor. Dan biarkan set test tidak tersentuh sampai paling akhir.
Skor yang terlalu sempurna secara mencurigakan (99% padahal para ahli memperkirakan 75%) adalah gejala klasiknya.
Mengapa ini penting untuk kode yang bersih
Penyiapan X/y yang jelas, dengan daftar nama fitur yang eksplisit, mendokumentasikan dengan tepat apa yang dilihat model. Simpan di satu tempat (FEATURES = [...]) supaya training dan prediksi memakai kolom yang sama dalam urutan yang sama. Seed membuat pembagian bisa direproduksi, dan set test yang tidak tersentuh membuat skor akhirnya jujur, dan itulah dasar keputusan para stakeholder.
Rangkuman
- X = fitur (2-D, satu baris per contoh), y = label (1-D, urutan yang sama).
- ID bukan fitur; kategori teks menjadi angka lewat one-hot encoding.
- Bagi menjadi set training dan test; acak dulu; set test dipakai sekali, di akhir.
train_test_split(X, y, test_size=0.25, random_state=42, stratify=y)mengembalikanX_train, X_test, y_train, y_test.- Leakage: fitur yang belum diketahui saat prediksi dibuat. Skor yang terlalu bagus adalah tanda peringatan.