Ketika dua kelas bisa dipisahkan garis, bukan hanya satu garis yang berhasil — ada tak terhingga banyaknya. Garis yang miring sedikit, garis yang menempel dekat klaster spam, garis yang menempel dekat klaster ham: semuanya “benar” pada data latih, tetapi menimbulkan prediksi berbeda untuk email baru. Support Vector Machine (SVM) menjawab ambiguitas itu dengan kriteria tegas: pilih garis yang jauhnya paling sama dari kedua kelas — garis tengah dari jalan terlebar yang bisa dibentangkan di antara keduanya. Filosofi “margin terlebar” ini terbukti kokoh secara teori dan praktik, dan lewat kernel trick, SVM mampu menghasilkan batas keputusan melengkung tanpa benar-benar meninggalkan dunia aljabar linear.

Margin dan Support Vector #

Bayangkan dua kelompok titik di peta dan sebuah jalan yang memisahkannya. Margin adalah lebar jalan tersebut — jarak dari garis tengah ke titik terdekat tiap sisi. SVM mencari garis tengah yang memaksimalkan margin. Titik-titik yang berdiri tepat di tepi jalan disebut support vector — mereka adalah satu-satunya data yang menentukan keputusan. Geser atau hapus titik lain yang berada jauh di dalam wilayahnya, dan garis tidak bergerak sedikit pun; geser satu support vector, garis ikut bergeser.

Sifat ini memberi dua konsekuensi menarik. Pertama, model SVM ringkas secara alami: prediksi email baru hanya membutuhkan support vector, bukan seluruh data latih — lawan persis dari KNN yang menggandeng semua tetangga. Kedua, SVM tahan terhadap titik jauh di dalam wilayah yang aman, tetapi sangat peka terhadap titik di dekat batas — karakter yang perlu diingat saat membaca hasilnya.

Margin Lunak dan Parameter C #

Data nyata jarang bisa dipisahkan sempurna; beberapa email spam pasti menyusup ke wilayah ham. Margin lunak (soft margin) mengizinkan pelanggaran: beberapa titik boleh masuk ke dalam jalan atau bahkan ke sisi yang salah, asalkan pelanggarannya dikenai biaya. Parameter C menetapkan berat biaya tersebut per satuan pelanggaran.

Arah parameternya sering membingungkan, jadi mari kita pelankan. C besar berarti pelanggaran mahal — model memilih jalan sempit yang nyaris tanpa pelanggaran pada data latih; margin menjadi “keras”. C kecil berarti pelanggaran murah — model memilih jalan lebar dan bersedia membiarkan beberapa titik melanggar; margin menjadi “lunak” dan batas keputusan lebih halus. Konvensinya sama dengan C pada regresi logistik: keduanya adalah kebalikan kekuatan regularisasi, berlawanan dengan alpha pada Ridge yang justru sebanding. Jika Anda menghafal satu kalimat saja: C besar = pemasangan ketat ke data latih, C kecil = regularisasi kuat.

Kernel Trick #

Kelebihan terbesar SVM: mengatasi data yang tidak terpisahkan linier dengan cara yang elegan. Data dua kelas yang saling melingkar, misalnya, tidak bisa dipisah garis di bidang datar — tetapi jika setiap titik diproyeksikan ke dimensi lebih tinggi (misalnya menambahkan fitur kuadrat), pemisah datar muncul di dimensi baru itu. Kernel trick memungkinkan SVM bekerja di dimensi tinggi tersebut tanpa pernah menghitung koordinat proyeksinya: fungsi kernel mengevaluasi produk titik antar-titik secara langsung, dan seluruh optimasi margin ternyata hanya membutuhkan produk titik, bukan koordinatnya.

Kernel yang paling dipakai adalah RBF (radial basis function), yang mengukur kemiripan dua titik seperti kurva Gaussian. Hyperparameter gamma mengatur jangkauannya: gamma kecil membuat tiap support vector berpengaruh jauh sehingga batas melengkung landai; gamma besar membuat pengaruhnya lokal sehingga batas terpecah menjadi pulau-pulau kecil di sekitar tiap titik — bentuk lain dari overfitting. Bersama C, keduanya membentuk bidang kendali utama SVM.

KernelBentuk batasKapan dipakai
linearGaris/bidang lurusFitur banyak, data besar (pakai LinearSVC)
rbfLentur mengikuti dataPilihan umum saat data tak terpisah linier
polyPolinomial berderajat dStruktur berderajat tinggi yang diketahui
sigmoidMenyerupai jaringan sarafJarang; hasil sering kurang stabil

Dua catatan praktis menutup teori ini. Pertama, SVM sangat membutuhkan scaling: margin dan kernel RBF dibangun dari jarak antar-titik, sehingga fitur bersatuan besar akan mendominasi perhitungan — StandardScaler sebelum SVM bukan opsional. Kedua, biaya pelatihan SVC tumbuh sekitar kuadratik sampai kubik terhadap jumlah data (O(n²) sampai O(n³)); pada puluhan ribu data, proses melambat nyata. Untuk kasus linier berskala besar, LinearSVC jauh lebih efisien karena tidak memakai kernel sama sekali.

Sekarang kita buktikan seluruh cerita itu dalam satu eksperimen: email ham yang menumpuk rapat dikelilingi email spam yang menyebar luas — pola yang menuntut batas melengkung:

python
# SVM: hyperplane ber-margin terlebar, support vector, dan kernel RBF.
# Kisah: email ham menumpuk rapat di satu wilayah, email spam menyebar luas.

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC, LinearSVC

X, y = make_blobs(
    n_samples=60,
    centers=[(-1.5, 0.0), (1.5, 0.0)],
    cluster_std=[0.8, 2.6],  # ham rapat, spam menyebar luas
    random_state=42,
)

X_latih, X_uji, y_latih, y_uji = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

# LinearSVC: mencari hyperplane (di sini garis lurus) pemisah terbaik.
model_linier = make_pipeline(
    StandardScaler(),
    LinearSVC(random_state=42),
)
model_linier.fit(X_latih, y_latih)

# SVC dengan kernel RBF: batas keputusan boleh melengkung.
model_rbf = make_pipeline(
    StandardScaler(),
    SVC(kernel="rbf", C=1.0, gamma=0.5, random_state=42),
)
model_rbf.fit(X_latih, y_latih)

print("Perbandingan batas keputusan (42 email latih, 18 email uji):")
for nama, model in [("LinearSVC", model_linier), ("SVC RBF", model_rbf)]:
    print(f"  {nama:<10} akurasi latih {model.score(X_latih, y_latih):.3f}   "
          f"akurasi uji {model.score(X_uji, y_uji):.3f}")

svm_rbf = model_rbf[-1]
print(f"\nSupport vector pada SVC RBF: {svm_rbf.support_vectors_.shape[0]} "
      f"dari {X_latih.shape[0]} email latih")
print(f"  per kelas (ham, spam): {svm_rbf.n_support_[0]}, {svm_rbf.n_support_[1]}")

print("\nPengaruh parameter C pada SVC RBF (gamma=0.5):")
print("  C        akurasi latih   akurasi uji   jumlah SV")
for c in [0.01, 1.0, 10.0]:
    model = make_pipeline(
        StandardScaler(),
        SVC(kernel="rbf", C=c, gamma=0.5, random_state=42),
    )
    model.fit(X_latih, y_latih)
    jumlah_sv = model[-1].support_vectors_.shape[0]
    print(f"  {c:<6}  {model.score(X_latih, y_latih):>12.3f}   "
          f"{model.score(X_uji, y_uji):>11.3f}   {jumlah_sv:>9d}")

Output yang Dihasilkan:

text
Perbandingan batas keputusan (42 email latih, 18 email uji):
  LinearSVC  akurasi latih 0.881   akurasi uji 0.944
  SVC RBF    akurasi latih 0.905   akurasi uji 1.000

Support vector pada SVC RBF: 22 dari 42 email latih
  per kelas (ham, spam): 10, 12

Pengaruh parameter C pada SVC RBF (gamma=0.5):
  C        akurasi latih   akurasi uji   jumlah SV
  0.01           0.905         1.000          42
  1.0            0.905         1.000          22
  10.0           0.976         0.944          13

Mari kita telaah baris-baris kode di atas:

  1. Baris 11–16 (make_blobs): 60 email dibentuk sebagai dua gumpalan dengan sebaran tidak sama — ham rapat (cluster_std=0.8) dan spam lebar (cluster_std=2.6). Atribut cluster_std menerima daftar agar tiap kelas punya sebaran sendiri; wilayah spam pun mengurung sebagian wilayah ham.
  2. Baris 23–27 (LinearSVC dalam pipeline): make_pipeline merangkai StandardScaler dan classifier menjadi satu objek — scaling dijalankan otomatis setiap fit dan predict, pola yang wajib untuk SVM.
  3. Baris 30–34 (SVC(kernel="rbf")): model kernel dengan C=1.0 dan gamma=0.5; semua argumen sama kecuali bentuk batas yang kini boleh melengkung.
  4. Baris 41–44 (support_vectors_, n_support_): atribut SVC (tidak dimiliki LinearSVC) yang menghitung titik-titik penentu batas — total dan per kelas.
  5. Baris 47–56 (sweep C): tiga model identik kecuali nilai C; tabel mencetak akurasi latih, akurasi uji, dan jumlah support vector agar efek C terbaca dari tiga sudut sekaligus.

Hasilnya memperlihatkan pembagian peran dengan jelas. LinearSVC mencapai akurasi uji 0,944 dengan garis lurus; SVC berkernel RBF mencapai 1,000 karena batasnya boleh membungkus klaster ham yang rapat — itulah nilai kernel pada data yang tumpang-tindih secara asimetris. Dari 42 email latih, hanya 22 yang menjadi support vector (10 ham dan 12 spam): separuh data latih sama sekali tidak menentukan batas, bukti empiris bahwa SVM hanya peduli pada titik-titik tepi.

Tabel sweep C memperlihatkan trade-off margin dengan angka. Dengan C=0.01, pelanggaran nyaris bebas: seluruh 42 titik menjadi support vector (jalan begitu lebar hingga semua titik ikut menahan tepiannya) dan akurasi uji 1,000. Dengan C=10, pemasangan menjadi ketat: akurasi latih melonjak ke 0,976, jumlah support vector turun ke 13 (jalan menyempit, hanya titik tersulit yang menahan), tetapi akurasi uji turun ke 0,944 — pola overfitting klasik yang diperkuat bukti jumlah support vector-nya. Nilai C=1.0 berada di tengah: margin cukup lebar, 22 support vector, generalisasi tetap sempurna pada data ini.

Sepanjang section ini kita bekerja pada klasifikasi binier: ham melawan spam. Padahal dunia nyata sering bertanya tiga kelas atau lebih — kategori email utama/sosial/promosi, spesies bunga, penilaian kredit tiga tingkat. Bagaimana algoritme binier ini dipakai untuk masalah banyak kelas? Chapter penutup section, Klasifikasi Multiclass, membongkar strategi di baliknya.