β˜€οΈSiang
AI & Data Science

Support Vector Machine (SVM)

TOKEN

Tutorial lengkap SVM β€” konsep margin dan hyperplane, berbagai jenis kernel, klasifikasi & regresi, tuning hyperparameter, dan implementasi dengan scikit-learn

Artikel: Ml Svm Artikel: Ml Svm


1. Pengenalan SVM

Support Vector Machine (SVM) adalah salah satu algoritma Machine Learning paling elegan dan powerful, yang dikembangkan oleh Vladimir Vapnik dan kolega pada tahun 1963-1995. SVM pertama kali dipopulerkan dengan konsep Maximum Margin Classifier dan kemudian diperluas dengan Kernel Trick oleh Boser, Guyon, dan Vapnik pada tahun 1992.

Inti dari SVM sederhana namun powerful: SVM mencari hyperplane terbaik yang memisahkan kelas-kelas data dengan margin terbesar. Margin adalah jarak antara hyperplane dengan data point terdekat dari masing-masing kelas (yang disebut support vectors).

Kapan Menggunakan SVM?

Diagram: Pengaruh Parameter C pada SVM
β—‹ β—‹ β—‹ ● ●
C KECIL (misal 0.01): C BESAR (misal 100):
β—‹ β—‹ β—‹ ● ●
β—‹ β—‹ ←margin kecilβ†’ ● ●
β—‹ β—‹ Γ— Γ— ●
● ● (margin kecil)
● ●
Lebih sedikit
misclassification β†’
variance tinggi
Overfitting tendency
Python β€” Perbandingan C pada SVM
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

# Dataset dengan noise (overlapping classes)
X, y = make_classification(
    n_samples=200, n_features=2, n_redundant=0,
    n_informative=2, n_clusters_per_class=1,
    flip_y=0.1, random_state=42  # 10% noise
)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

fig, axes = plt.subplots(1, 4, figsize=(20, 5))
C_values = [0.001, 0.01, 1, 100]

for ax, C in zip(axes, C_values):
    svm = SVC(kernel='linear', C=C)
    svm.fit(X_train, y_train)
    
    train_acc = svm.score(X_train, y_train)
    test_acc = svm.score(X_test, y_test)
    n_sv = len(svm.support_)
    
    # Decision boundary
    xx, yy = np.meshgrid(
        np.linspace(X[:, 0].min()-1, X[:, 0].max()+1, 300),
        np.linspace(X[:, 1].min()-1, X[:, 1].max()+1, 300)
    )
    Z = svm.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    
    ax.contourf(xx, yy, Z, alpha=0.3, cmap='RdYlBu')
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap='RdYlBu', 
               edgecolors='k', s=40)
    
    # Highlight support vectors
    sv = svm.support_vectors_
    ax.scatter(sv[:, 0], sv[:, 1], s=200, facecolors='none', 
               edgecolors='green', linewidths=2)
    
    ax.set_title(f'C = {C}\nTrain: {train_acc:.2f}, Test: {test_acc:.2f}\n'
                 f'SVs: {n_sv}', fontsize=10)
    ax.grid(True, alpha=0.3)

plt.suptitle('Pengaruh Parameter C pada SVM Linear', fontsize=14)
plt.tight_layout()
plt.show()


4. Kernel Trick & Jenis Kernel

Salah satu keunggulan terbesar SVM adalah Kernel Trick β€” kemampuan untuk menangani data yang tidak bisa dipisahkan secara linear dengan memproyeksikannya ke dimensi yang lebih tinggi tanpa secara eksplisit menghitung koordinat di dimensi tersebut.

Apa Itu Kernel Trick?

Diagram

2D (Tidak Linearly Separable): 3D (Linea...

β—‹ ● ● transform β—‹ β—‹ β—‹ β—‹

Tidak bisa dipisahkan Hyperplane m...

dengan garis lurus dengan bida...

Kernel function K(xα΅’, xβ±Ό) = Ο†(xα΅’) Β· Ο†(xβ±Ό)

Tidak perlu menghitung Ο†(x) secara eksplisit!

Hanya menghitung 'jarak' di ruang higher-dimens...

Jenis-Jenis Kernel

Kernel Formula Parameter Cocok untuk
linearK(x,y) = xΒ·yβ€”Data linearly separable, teks (high-dim)
polyK(x,y) = (Ξ³xΒ·y + r)^ddegree, gamma, coef0Polynomial patterns
rbf (Gaussian)K(x,y) = exp(-Ξ³||x-y||Β²)gammaNon-linear data (default, paling umum)
sigmoidK(x,y) = tanh(Ξ³xΒ·y + r)gamma, coef0Meniru neural network

Target (y)

Features (x)

Python β€” Support Vector Regression
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVR
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

# Generate non-linear data
np.random.seed(42)
X = np.sort(5 * np.random.rand(300, 1), axis=0)
y = np.sin(X).ravel() + 0.2 * np.random.randn(300)

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# Scale features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Bandingkan SVR dengan berbagai kernel
kernels_params = {
    'Linear SVR': {'kernel': 'linear', 'C': 1.0, 'epsilon': 0.1},
    'RBF SVR (C=1)': {'kernel': 'rbf', 'C': 1.0, 'gamma': 'scale', 'epsilon': 0.1},
    'RBF SVR (C=100)': {'kernel': 'rbf', 'C': 100.0, 'gamma': 'scale', 'epsilon': 0.1},
    'Poly SVR (degree=3)': {'kernel': 'poly', 'degree': 3, 'C': 1.0, 'epsilon': 0.1},
}

fig, axes = plt.subplots(2, 2, figsize=(14, 10))
results = {}

for ax, (name, params) in zip(axes.ravel(), kernels_params.items()):
    svr = SVR(**params)
    svr.fit(X_train_scaled, y_train)
    
    y_pred = svr.predict(X_test_scaled)
    r2 = r2_score(y_test, y_pred)
    rmse = np.sqrt(mean_squared_error(y_test, y_pred))
    mae = mean_absolute_error(y_test, y_pred)
    n_sv = len(svr.support_)
    
    results[name] = {'RΒ²': r2, 'RMSE': rmse, 'MAE': mae, 'SVs': n_sv}
    
    # Plot
    X_plot = np.linspace(X_train_scaled.min(), X_train_scaled.max(), 500).reshape(-1, 1)
    y_plot = svr.predict(X_plot)
    
    ax.scatter(X_train_scaled, y_train, c='steelblue', s=15, alpha=0.5, label='Train')
    ax.scatter(X_test_scaled, y_test, c='orange', s=15, alpha=0.5, label='Test')
    ax.plot(X_plot, y_plot, 'r-', linewidth=2, label='Prediksi')
    
    # Epsilon tube
    ax.fill_between(X_plot.ravel(), y_plot - svr.epsilon, y_plot + svr.epsilon,
                     alpha=0.15, color='red', label=f'Ξ΅-tube ({svr.epsilon})')
    
    # Support vectors
    ax.scatter(X_train_scaled[svr.support_], y_train[svr.support_], 
               s=100, facecolors='none', edgecolors='green', linewidths=2,
               label=f'SVs ({n_sv})')
    
    ax.set_title(f'{name}\nRΒ²={r2:.3f} | RMSE={rmse:.3f}', fontsize=10)
    ax.legend(fontsize=7)
    ax.grid(True, alpha=0.3)

plt.suptitle('Support Vector Regression β€” Perbandingan Kernel', fontsize=14)
plt.tight_layout()
plt.show()

# Summary table
print("\n" + "=" * 65)
print("SVR RESULTS SUMMARY")
print("=" * 65)
print(f"{'Model':<25} {'RΒ²':>8} {'RMSE':>8} {'MAE':>8} {'SVs':>6}")
print("-" * 65)
for name, metrics in results.items():
    print(f"{name:<25} {metrics['RΒ²']:>8.4f} {metrics['RMSE']:>8.4f} "
          f"{metrics['MAE']:>8.4f} {metrics['SVs']:>6d}")


8. Hyperparameter Tuning (C & Gamma)

Dua hyperparameter terpenting pada SVM dengan kernel RBF adalah C dan gamma (Ξ³). Memahami interaksi antara keduanya sangat krusial untuk mendapatkan performa terbaik.

C dan Gamma: Interaksi

Gamma Kecil Gamma Besar
C KecilBias tinggi, variance rendah β†’ UnderfittingBias rendah, variance tinggi β†’ Model kompleks
C BesarBias sedang, variance sedang β†’ Model moderatBias rendah, variance tinggi β†’ Overfitting
Python β€” Grid Search C & Gamma
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.model_selection import GridSearchCV, StratifiedKFold, train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
import warnings
warnings.filterwarnings('ignore')

# Load digits dataset
X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# Pipeline dengan scaling
pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('svm', SVC(kernel='rbf', random_state=42))
])

# Grid Search: C dan Gamma
param_grid = {
    'svm__C': [0.01, 0.1, 1, 10, 100, 1000],
    'svm__gamma': ['scale', 'auto', 0.001, 0.01, 0.1, 1, 10]
}

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

grid_search = GridSearchCV(
    pipe, param_grid,
    cv=cv,
    scoring='accuracy',
    n_jobs=-1,
    verbose=1,
    refit=True
)
grid_search.fit(X_train, y_train)

print("=" * 60)
print("GRID SEARCH RESULTS")
print("=" * 60)
print(f"Best Score (CV): {grid_search.best_score_:.4f}")
print(f"Best Parameters: {grid_search.best_params_}")
print(f"Test Score: {grid_search.best_estimator_.score(X_test, y_test):.4f}")

# Visualisasi Heatmap C vs Gamma
import pandas as pd

results = grid_search.cv_results_

# Filter hanya kombinasi numeric gamma
mask_numeric = [isinstance(p, (int, float)) for p in param_grid['svm__gamma'][:len(param_grid['svm__gamma'])]]

C_values = param_grid['svm__C']
gamma_values = ['0.001', '0.01', '0.1', '1', '10']  # numeric only
score_matrix = np.zeros((len(C_values), len(gamma_values)))

for i, c in enumerate(C_values):
    for j, g in enumerate(['0.001', '0.01', '0.1', '1', '10']):
        idx = [k for k, p in enumerate(results['params'])
               if p['svm__C'] == c and str(p['svm__gamma']) == g]
        if idx:
            score_matrix[i, j] = results['mean_test_score'][idx[0]]

plt.figure(figsize=(10, 6))
plt.imshow(score_matrix, cmap='YlOrRd', aspect='auto', interpolation='nearest')
plt.colorbar(label='CV Accuracy')
plt.xticks(range(len(gamma_values)), gamma_values)
plt.yticks(range(len(C_values)), C_values)
plt.xlabel('Gamma')
plt.ylabel('C')
plt.title('Grid Search: Accuracy Heatmap (C vs Gamma)')

# Annotate cells
for i in range(len(C_values)):
    for j in range(len(gamma_values)):
        plt.text(j, i, f'{score_matrix[i, j]:.3f}',
                 ha='center', va='center', fontsize=8,
                 color='white' if score_matrix[i, j] > 0.95 else 'black')

plt.tight_layout()
plt.show()
πŸ’‘ Tips Tuning SVM
  • Selalu scaling! SVM sangat sensitif terhadap skala fitur. Gunakan StandardScaler
  • C: Mulai dari 1.0. Besar = lebih kompleks (overfitting), kecil = lebih sederhana (underfitting)
  • Gamma: 'scale' (default sklearn) = 1/(n_features * variance(X)). Good starting point
  • RandomizedSearchCV lebih cepat daripada GridSearchCV untuk eksplorasi awal
  • SVM training O(nΒ² ~ nΒ³) β€” untuk dataset > 50k samples, pertimbangkan LinearSVC atau SGDClassifier


9. Kelebihan & Kekurangan

Kelebihan SVM

Kelebihan Penjelasan
βœ… Efektif di high dimensionPerforma bagus bahkan jika jumlah fitur > jumlah sampel (e.g., text classification)
βœ… Margin maximizationGeneralisasi baik karena margin besar β†’ robust terhadap noise
βœ… Memory efficientHanya menyimpan support vectors (subset data), bukan seluruh dataset
βœ… Versatile kernelsBerbagai kernel tersedia untuk berbagai jenis data
βœ… Global optimumConvex optimization β†’ tidak terjebak local minimum (unlike neural network)
βœ… Works well with small dataPerforma bagus bahkan dengan sedikit data

Kekurangan SVM

Kekurangan Penjelasan
❌ Scaling sensitifWAJIB melakukan feature scaling (StandardScaler)
❌ Lambat untuk data besarTraining O(nΒ²~nΒ³) β€” sangat lambat untuk dataset > 100k samples
❌ Probabilitas tidak langsungTidak memberikan probabilitas langsung (butuh probability=True dengan Platt scaling)
❌ Tuning kompleksC, gamma, kernel type, degree β€” banyak hyperparameter yang saling berinteraksi
❌ Tidak handle missing valuesPerlu imputasi sebelum training
❌ Interpretasi sulitModel sulit diinterpretasikan (terutama kernel non-linear)


10. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang SVM:

Pertanyaan 1: Apa yang dimaksud dengan "margin" dalam SVM?

a) Jumlah support vector yang digunakan
b) Jarak antara hyperplane dengan data point terdekat dari masing-masing kelas
c) Jumlah fitur yang digunakan dalam model
d) Skor akurasi dari model

Pertanyaan 2: Mengapa SVM menggunakan "Kernel Trick"?

a) Untuk mempercepat training dengan mengurangi jumlah data
b) Untuk memproyeksikan data ke dimensi lebih tinggi agar bisa dipisahkan secara linear
c) Untuk memilih fitur yang paling penting
d) Untuk menghilangkan outlier dari dataset

Pertanyaan 3: Apa efek dari parameter C yang sangat besar pada SVM?

a) Margin semakin besar, model lebih sederhana
b) Margin semakin kecil, model cenderung overfitting
c) Tidak ada efek pada model
d) Kernel otomatis berubah ke linear

Pertanyaan 4: Mengapa feature scaling sangat penting untuk SVM?

a) SVM menghitung jarak antar data points β€” fitur dengan skala besar akan mendominasi
b) Scaling mengurangi jumlah fitur
c) Scaling membuat SVM bisa menangani missing values
d) Scaling meningkatkan kecepatan training secara eksponensial

Pertanyaan 5: Kernel mana yang paling umum digunakan untuk data non-linear?

a) Linear kernel
b) Polynomial kernel
c) RBF (Gaussian) kernel
d) Sigmoid kernel
πŸ” Zoom
100%
🎨 Tema