Chapter Support Vector Machine di section klasifikasi mengajari kita memisahkan dua kelas dengan bidang pemisah seluas mungkin di ruang kernel. Deteksi anomali hanya punya satu kelas — “normal” — sehingga triknya dibalik: One-Class SVM memetakan data normal ke ruang kernel berdimensi tinggi, lalu memisahkan seluruh kerumunan tersebut dari titik origin dengan bidang yang sebisanya menjauh. Hasilnya bukan klasifikasi dua kelas, melainkan sebuah fungsi batas: decision_function bernilai positif di dalam wilayah normal dan negatif di luarnya, dihitung hanya dari segelintir support vector. Berbeda dengan LOF yang menyimpan seluruh data latih, model semacam ini ringkas untuk diterapkan berulang; harganya adalah dua kenop yang harus ditala dengan hati-hati (nu dan gamma) serta satu syarat yang tidak bisa ditawar: penskalaan fitur.
Batas Kerapatan di Ruang Kernel #
Secara intuitif, One-Class SVM dengan kernel RBF bekerja seperti perkiraan kerapatan: fungsi kepatutan Gaussian diletakkan di setiap titik latih, dan decision_function(x) menjumlahkan kepatutan semua titik terhadap x dikurangi ambang ρ. Titik yang dikelilingi banyak tetangga mendapat skor positif; titik di wilayah kosong mendapat skor negatif. Optimisasinya hanya melibatkan sebagian kecil data — support vector — yang menjadi penentu posisi batas; sisanya bisa dibuang tanpa mengubah hasil.
Dua parameter mengendalikan bentuk batas tersebut:
nu(0–0,5] memainkan dua peran sekaligus: batas atas pecahan data latih yang boleh jatuh di sisi salah (diperlakukan outlier) dan batas bawah pecahan data yang menjadi support vector. Kecilkannu→ batas longgar dan sedikit titik ditandai; besarkan → batas rapat dan biaya komputasi naik.gammamengatur lebar kernel RBF: kecil berarti batas halus dan global, besar berarti batas berlekuk mengikuti tiap kelompok titik — risiko overfitting pada data kecil.
decision_function(x) = Σ_i α_i · k(x_i, x) − ρ k = exp(−γ ‖x_i − x‖²)Perhatikan rumus kernelnya: seluruh mekanisme bergantung pada jarak Euclidean ‖x_i − x‖. Di sinilah letak syarat mutlak bab ini — jarak Euclidean tidak adil ketika satu fitur berskala ratusan dan fitur lain berskala satuan.
Penskalaan Fitur Bersifat Wajib #
Data transaksi TokoKita memiliki kolom nilai belanja (ratusan ribu rupiah, varians ~1500) dan kolom jumlah item (satuan, varians ~4). Pada data mentah, kuadrat jarak hampir seluruhnya disumbang kolom nilai: anomali 7 simpangan baku pada kolom item menyumbang jarak yang lebih kecil daripada selisih wajar kolom nilai. Kernel RBF menjadi nyaris buta terhadap satu dimensi. Solusinya standar: StandardScaler menyetarakan kedua kolom sebelum masuk model — dan Pipeline dari scikit-learn memastikan scaler ikut terpasang dengan benar saat validasi silang.
Praktik: Model Mentah versus Model Terskala #
Eksperimen di bawah memakai 240 transaksi normal bersih sebagai data latih dan 40 transaksi normal lain sebagai penguji. Empat transaksi uji sengaja dipilih dengan simpangan baku yang kita ketahui — dua di antaranya menyimpang tepat ~7 simpangan baku, satu hanya pada kolom nilai, satu hanya pada kolom item. Model yang sama (kernel RBF, nu=0.05) dilatih dua kali: pada data mentah dan pada data hasil StandardScaler. Setelah tabel perbandingan, dua sapuan kecil membedah makna nu dan gamma lewat jumlah support vector serta angka salah-tandai.
# One-Class SVM: batas kerapatan di ruang kernel -- penskalaan fitur wajib.
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.svm import OneClassSVM
rng = np.random.default_rng(42)
# 1) Data latih bersih: 240 transaksi normal satu kerumunan.
# Nilai belanja berskala ratusan; jumlah item berskala satuan.
latih = rng.normal(loc=[120.0, 8.0], scale=[40.0, 2.0], size=(240, 2))
uji_normal = rng.normal(loc=[120.0, 8.0], scale=[40.0, 2.0], size=(40, 2))
# 2) Empat transaksi uji dengan simpangan baku yang kita ketahui.
uji = np.array(
[
[400.0, 8.0], # +7 sigma pada nilai, 0 sigma pada item
[120.0, 22.0], # 0 sigma pada nilai, +7 sigma pada item
[350.0, 20.0], # gabungan besar (+5,75 sigma, +6 sigma)
[40.0, 2.0], # gabungan moderat (-2 sigma, -3 sigma)
]
)
mu = latih.mean(axis=0)
sigma = latih.std(axis=0)
# 3) Dua model dengan spesifikasi sama: satu pada data mentah,
# satu pada data yang sudah melalui StandardScaler.
mentah = OneClassSVM(kernel="rbf", gamma="scale", nu=0.05).fit(latih)
skala = StandardScaler().fit(latih)
latih_s = skala.transform(latih)
model_skala = OneClassSVM(kernel="rbf", gamma=0.05, nu=0.05).fit(latih_s)
print("Model mentah vs terskala (decision_function < 0 = anomali):")
print(" nilai_ribu item dev_nilai dev_item df_mentah pred df_skala pred")
for x in uji:
baris = x.reshape(1, -1)
baris_s = skala.transform(baris)
dev = (x - mu) / sigma
print(
f" {x[0]:>9.1f} {x[1]:>4.1f} {dev[0]:>9.2f} {dev[1]:>8.2f}"
f" {mentah.decision_function(baris)[0]:>10.2f} {mentah.predict(baris)[0]:>4d}"
f" {model_skala.decision_function(baris_s)[0]:>9.2f} {model_skala.predict(baris_s)[0]:>4d}"
)
uji_normal_s = skala.transform(uji_normal)
salah_mentah = int((mentah.predict(uji_normal) == -1).sum())
salah_skala = int((model_skala.predict(uji_normal_s) == -1).sum())
print(f" salah tandai pada 40 transaksi normal: mentah {salah_mentah}, skala {salah_skala}")
# 4) Parameter nu: batas atas pecahan outlier latih, batas bawah pecahan SV.
print("\nSapuan nu (gamma=0.05, data terskala):")
print(" nu n*nu SV aktual latih ditandai normal-uji ditandai")
for nu in (0.02, 0.05, 0.10):
m = OneClassSVM(kernel="rbf", gamma=0.05, nu=nu).fit(latih_s)
sv = len(m.support_vectors_)
latih_flag = int((m.predict(latih_s) == -1).sum())
uji_flag = int((m.predict(uji_normal_s) == -1).sum())
print(f" {nu:.2f} {nu * len(latih):>4.0f} {sv:>9d} {latih_flag:>14d} {uji_flag:>19d}")
# 5) Parameter gamma: lebar kernel; tidak ada satu nilai yang aman untuk semua data.
uji_s = skala.transform(uji)
print("\nSapuan gamma (nu=0.05, data terskala):")
print(" gamma SV uji tertangkap salah tandai normal")
for g in (0.005, 0.02, 0.05, 0.3, 1.0):
m = OneClassSVM(kernel="rbf", gamma=g, nu=0.05).fit(latih_s)
tangkap = int((m.predict(uji_s) == -1).sum())
salah = int((m.predict(uji_normal_s) == -1).sum())
print(f" {g:>5.3f} {len(m.support_vectors_):>3d} {tangkap:>14d} {salah:>19d}")Output yang Dihasilkan:
Model mentah vs terskala (decision_function < 0 = anomali):
nilai_ribu item dev_nilai dev_item df_mentah pred df_skala pred
400.0 8.0 7.22 0.04 -5.72 -1 -5.10 -1
120.0 22.0 -0.02 7.38 -0.13 -1 -5.22 -1
350.0 20.0 5.93 6.33 -5.30 -1 -5.68 -1
40.0 2.0 -2.09 -3.11 0.01 1 -1.43 -1
salah tandai pada 40 transaksi normal: mentah 4, skala 3
Sapuan nu (gamma=0.05, data terskala):
nu n*nu SV aktual latih ditandai normal-uji ditandai
0.02 5 7 4 2
0.05 12 14 13 3
0.10 24 25 25 4
Sapuan gamma (nu=0.05, data terskala):
gamma SV uji tertangkap salah tandai normal
0.005 14 4 3
0.020 14 4 3
0.050 14 4 3
0.300 18 4 4
1.000 49 4 5Mari kita bedah hasil eksekusinya:
- Baris 15–24 (empat titik uji): simpangan tiap kolom dihitung dari statistik data latih yang sesungguhnya (bukan angka bulat teoritis) — kolom
devpada tabel memperlihatkan +7,22σ dan +7,38σ untuk sepasang anomali yang kita rancang sama kuatnya. - Baris 33–43 (tabel mentah vs skala): inilah bukti terpenting chapter ini. Pada model mentah, anomali +7,22σ di kolom nilai dihukum
decision_function−5,72, sedangkan anomali +7,38σ di kolom item hanya −0,13 — simpangan setara, hukuman berbeda lebih dari empat puluh kali lipat. Model terskala memberi keduanya nilai yang nyaris seimbang (−5,10 dan −5,22). Baris keempat semakin menegaskan: penyimpangan gabungan moderat (−2,09σ, −3,11σ) sama sekali lolos pada model mentah (+0,01) dan tertangkap pada model terskala (−1,43). - Baris 44–47 (salah tandai): model mentah salah menandai 4 dari 40 transaksi normal, model terskala 3 dari 40. Penskalaan bukan hanya soal menangkap anomali — batas yang adil terhadap semua dimensi juga memperbaiki ketepatan pada data normal.
- Baris 49–57 (sapuan
nu): jumlah support vector selalu berada di atas batas bawah n·nu(7 ≥ 5; 14 ≥ 12; 25 ≥ 24) dan pecahan data latih yang ditandai mengikutinudari dekat (4, 13, dan 25 dari 240 — sekitar 1,7%, 5,4%, 10,4%). Makna gandanutampak sebagai angka, bukan janji dokumentasi. - Baris 59–67 (sapuan
gamma): keempat anomali uji kita kuat, sehingga tertangkap pada semua nilai gamma — perbedaannya muncul pada harga yang dibayar: dari gamma 0,005 ke 1,0, salah-tandai normal naik dari 3 menjadi 5 dan jumlah support vector membengkak dari 14 menjadi 49. Gamma besar membungkus tiap kelompok titik dengan batasnya sendiri; pada 240 titik, kerumunan yang rapat pun akhirnya “berkecil-kecil” di dalam batas yang terlalu rapat.
Menyetel nu dan gamma dengan Jujur #
Kesulitan jujur One-Class SVM: tidak ada resep bawaan untuk gamma, dan efeknya berinteraksi dengan nu. Sapuan kita memperlihatkan pola minimum: mulai dari nu sesuai dugaan pecahan anomali latih (0,01–0,1), lalu tala gamma dengan pengamatan yang tidak butuh label — misalnya memantau berapa persen data normal tertahan yang ikut ditandai. Jika label anomali tersedia, bahkan untuk sampel kecil, penilaian berbasis presisi-recall jauh lebih informatif — persis materi chapter penutup section ini.
Dengan tiga detektor di tangan, peta pemilihannya kini lengkap:
| Detektor | Model tersimpan | Penskalaan | Kenop utama | Kekuatan khas |
|---|---|---|---|---|
| Isolation Forest | Rumpun pohon ringkas | Tidak wajib | contamination | Data besar, dimensi banyak |
| Local Outlier Factor | Seluruh data latih | Dibutuhkan (basis jarak) | n_neighbors | Kerumunan berkepadatan campuran |
| One-Class SVM | Support vector saja | Wajib | nu, gamma | Batas halus, prediksi murah |
Ketiganya menghasilkan skor atau label, namun satu pertanyaan belum terjawab di seluruh section ini: bagaimana memutuskan apakah detektor kita bagus? Akurasi jelas bukan jawabannya ketika anomali hanya 1% data. Chapter Evaluasi Anomaly Detection menutup section dengan kerangka pengukuran yang benar untuk kelas langka — presisi dan recall pada titik operasi, average precision, dan kehati-hatian terhadap ROC-AUC yang terlihat manis padahal menipu.
Referensi Resmi #
- sklearn.svm.OneClassSVM — API Reference
— definisi
nu,gamma,decision_function, dansupport_vectors_. - Outlier detection — scikit-learn User Guide — posisi One-Class SVM di antara metode deteksi anomali.
- Support Vector Machines — scikit-learn User Guide — latar kernel RBF dan parameter gamma yang diwarisi dari SVM klasifikasi.