Skip to content

Support Vector Machine (SVM)

Classification Algorithms - Support Vector Machine (SVM)

Section titled “Classification Algorithms - Support Vector Machine (SVM)”

Support Vector Machines (SVMs) are powerful and versatile supervised learning algorithms used for classification, regression, and outlier detection. However, they are most widely known and used for classification tasks.

SVMs were developed in the 1990s and are particularly effective in high-dimensional spaces and situations where the number of dimensions exceeds the number of samples.

How SVM Works: The Maximum Margin Classifier

Section titled “How SVM Works: The Maximum Margin Classifier”

The core idea behind SVM for classification is to find the optimal hyperplane that best separates data points belonging to different classes in the feature space.

Key Concepts:

  • Hyperplane: A decision boundary that separates the classes. In a 2D feature space, it’s a line. In 3D, it’s a plane. In higher dimensions, it’s called a hyperplane.
  • Support Vectors: The data points from each class that lie closest to the hyperplane. These points are critical because they ‘support’ or define the position and orientation of the hyperplane. If these points were moved, the hyperplane would likely change.
  • Margin: The distance between the hyperplane and the closest support vectors from either class. SVM aims to find the hyperplane that maximizes this margin.

By maximizing the margin, SVM creates the largest possible separation (‘street’) between the classes. This maximum margin hyperplane is believed to lead to better generalization performance on unseen data, as it provides the most ‘room’ for error.

Conceptually, imagine separating two groups of dots on a piece of paper with a ruler. SVM tries to place the ruler exactly in the middle of the gap between the closest dots of each group, maximizing the distance from the ruler to these critical dots (the support vectors).

In real-world data, perfect separation is often impossible (data overlaps) or undesirable (sensitivity to outliers). SVM handles this using soft margin classification. It allows some data points to be within the margin or even on the wrong side of the hyperplane (margin violations), but penalizes them.

The hyperparameter C controls this trade-off:

  • Small C: Wider margin, allows more margin violations (higher tolerance for misclassification, more regularization, potentially underfitting).
  • Large C: Narrower margin, tries to minimize margin violations (less tolerance, less regularization, potentially overfitting).

What if the data isn’t linearly separable in the original feature space? SVM can handle this using the kernel trick.

Kernels are functions that compute the similarity between data points in a potentially much higher-dimensional space without explicitly transforming the data into that space. This avoids the computational cost of explicit transformation.

By using an appropriate kernel, SVM can find a linear hyperplane in the transformed high-dimensional space, which corresponds to a non-linear decision boundary in the original feature space.

  • Linear Kernel (kernel='linear'): Computes a simple dot product. Equivalent to finding a linear hyperplane in the original space. Use when data is likely linearly separable.
  • Polynomial Kernel (kernel='poly'): Maps data to a polynomial feature space. Requires tuning the degree hyperparameter (and coef0).
  • Radial Basis Function (RBF) Kernel (kernel='rbf'): A popular default choice. Maps data to an infinite-dimensional space. Can handle complex, non-linear relationships. Requires tuning the gamma hyperparameter, which controls the influence of individual data points (low gamma = broad influence, high gamma = local influence).
  • Sigmoid Kernel (kernel='sigmoid'): Similar to the activation function in neural networks. Often used in specific domains.

The choice of kernel and its hyperparameters (like C, gamma, degree) is crucial and typically requires tuning using techniques like Grid Search or Randomized Search.

We’ll use Scikit-learn’s SVC (Support Vector Classifier) class.

First, let’s visualize SVM on simple, linearly separable synthetic data.

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_blobs
from sklearn.svm import SVC # Support Vector Classifier
# 1. Create linearly separable data
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.60)
# 2. Create and fit the SVM model (Linear Kernel)
# Large C value enforces a stricter separation (harder margin)
model_linear = SVC(kernel='linear', C=1E10)
model_linear.fit(X, y)
# 3. Plotting function (Helper)
def plot_svc_decision_boundary(model, ax=None, plot_support=True):
"""Plot the decision function for a 2D SVC"""
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# Create grid to evaluate model
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = model.decision_function(xy).reshape(XX.shape)
# Plot decision boundary and margins
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
# Plot support vectors
if plot_support:
ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1],
s=100, linewidth=1, facecolors='none', edgecolors='k', label='Support Vectors')
ax.set_xlim(xlim)
ax.set_ylim(ylim)
# 4. Visualize the result
plt.figure(figsize=(8, 6))
sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=y, s=50, palette='viridis', legend=False)
plot_svc_decision_boundary(model_linear)
plt.title('Linear SVM Decision Boundary and Margins')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.grid(True)
plt.show()
# Print support vectors
print("Support Vectors:")
print(model_linear.support_vectors_)

(The plot shows the data points colored by class, the solid black line is the maximum margin hyperplane, the dashed lines represent the margins, and the circled points are the support vectors.)

Support Vectors:
[[0.5323772 3.31338909]
[2.11114739 3.57660449]
[1.46870582 1.86947425]]

Example 2: Non-Linearly Separable Data (Iris Dataset with RBF Kernel)

Section titled “Example 2: Non-Linearly Separable Data (Iris Dataset with RBF Kernel)”

Now let’s use the RBF kernel on the Iris dataset (using two features for visualization).

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 1. Load Iris dataset (using only Sepal features for this example)
iris = datasets.load_iris()
X = iris.data[:, :2] # Sepal length, Sepal width
y = iris.target
feature_names = iris.feature_names[:2]
# 2. Split and Scale Data (Important for SVM!)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 3. Create and Fit SVM with RBF Kernel
# C and gamma are important hyperparameters to tune
model_rbf = SVC(kernel='rbf', C=1.0, gamma='scale', probability=True) # gamma='scale' is often a good default
model_rbf.fit(X_train_scaled, y_train)
# 4. Predict and Evaluate
y_pred = model_rbf.predict(X_test_scaled)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy (RBF Kernel): {accuracy:.4f}")
# 5. Visualize Decision Boundary (Helper function needed)
def plot_decision_regions(X, y, classifier, resolution=0.02, test_idx=None):
from matplotlib.colors import ListedColormap
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
alpha=0.8, c=colors[idx],
marker=markers[idx], label=f'Class {cl}', edgecolor='black')
# Highlight test samples
if test_idx:
X_test, y_test = X[test_idx, :], y[test_idx]
plt.scatter(X_test[:, 0], X_test[:, 1],
c='', edgecolor='black', alpha=1.0,
linewidth=1, marker='o', s=100, label='Test set')
# Combine scaled training and testing data for plotting boundaries across the whole range
X_combined_scaled = np.vstack((X_train_scaled, X_test_scaled))
y_combined = np.hstack((y_train, y_test))
plt.figure(figsize=(10, 7))
plot_decision_regions(X=X_combined_scaled, y=y_combined, classifier=model_rbf)
plt.title('SVM with RBF Kernel Decision Boundary (Iris Sepal Features)')
plt.xlabel(f'{feature_names[0]} (Scaled)')
plt.ylabel(f'{feature_names[1]} (Scaled)')
plt.legend(loc='upper left')
plt.grid(True)
plt.show()
Accuracy (RBF Kernel): 0.8222

The accuracy shows the performance on the test set using the RBF kernel. The plot visualizes the non-linear decision boundaries created by the RBF kernel SVM to separate the three Iris classes based on the scaled sepal features.

  • Effective in High Dimensions: Works well even when the number of features is large.
  • Memory Efficient: Uses a subset of training points (support vectors) in the decision function.
  • Versatile: Different kernel functions can be specified for the decision function.
  • Effective with Clear Margin: Performs well when there is a clear margin of separation between classes.
  • Computationally Intensive: Can be slow to train on very large datasets (training time complexity can be between O(N²) and O(N³)).
  • Sensitivity to Hyperparameters: Performance is highly dependent on the choice of kernel and hyperparameters (C, gamma). Requires careful tuning.
  • Poor with Overlapping Classes: Doesn’t perform as well when classes heavily overlap.
  • Not Directly Probabilistic: Basic SVM doesn’t directly provide probability estimates (though Scikit-learn’s implementation can estimate them via Platt scaling, requiring probability=True).
  • Scaling Requirement: SVMs are sensitive to feature scaling; features should typically be scaled (e.g., using StandardScaler) before training.
  • Image Classification: Identifying objects in images.
  • Text Categorization: Classifying documents into topics.
  • Bioinformatics: Protein classification, cancer classification.
  • Handwriting Recognition: Identifying handwritten characters.
  • Face Detection: Detecting faces in images.