🧠 Classical ML · Tier 2 🟡 Intermediate MODULE 03

Support Vector Machines

⏱️ 2.5 hours
📐 Geometry + Math
🧩 5 Quiz Questions
📦 4 Sections
Classical ML — Module 3 of 100%
🎯 What you'll learn: The geometric intuition behind maximising the margin between classes, what support vectors actually are, how the kernel trick transforms non-linearly separable data into higher-dimensional space where it becomes separable, the three main kernels (linear, RBF, polynomial) and their tradeoffs, using SVC and SVR in sklearn, and when SVMs outperform tree-based models.

Find the Widest Street Between Classes

For a binary classification problem, there are infinitely many hyperplanes that can separate two linearly separable classes. SVMs choose the one that maximises the margin — the distance between the hyperplane and the nearest training point from each class.

The intuition: a fatter margin means the decision boundary is further from all training points, giving more room for generalisation. Points that lie exactly on the margin boundaries are called support vectors — they are the only training points that matter for defining the boundary. Delete all other points and you'd get the same hyperplane.

📐
Only a few points define the entire boundary
A Random Forest uses all training points. An SVM uses only the support vectors — typically a small fraction of the dataset. This is why SVMs generalise well from small datasets. It also makes them memory-efficient at inference time: you only need to store the support vectors, not the full training set.

Real data is rarely perfectly separable. SVMs introduce a soft margin via the parameter C:

  • High C: penalise misclassifications heavily → narrow margin, fits training data more tightly (risks overfitting)
  • Low C: allow some misclassification → wider margin, smoother boundary (risks underfitting)
Linear SVM — effect of C on margin PYTHON
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score

# ALWAYS scale before SVM — it is distance-based
for C in [0.001, 0.1, 1, 10, 100]:
    pipe = Pipeline([
        ('scaler', StandardScaler()),
        ('svm',    SVC(kernel='linear', C=C))
    ])
    score = cross_val_score(pipe, X, y, cv=5).mean()
    print(f"C={C:6}: CV={score:.3f}")

# Number of support vectors used
svc = SVC(kernel='linear', C=1).fit(X_scaled, y)
print(f"Support vectors per class: {svc.n_support_}")

Separate Non-Linear Data Without the Computation Cost

Most real datasets are not linearly separable. The naive fix is to map data into a higher-dimensional space where it becomes separable — for example, adding a feature x² allows a parabola as the decision boundary. But explicitly computing all those new features is expensive.

The kernel trick exploits the fact that the SVM optimisation only ever needs dot products between data points — never the points themselves. A kernel function K(xᵢ, xⱼ) computes what the dot product would be in the high-dimensional space without ever going there. This gives the non-linear power at linear computational cost.

Linear
K = xᵢᵀ xⱼ
Linearly separable data, text classification, high-dimensional sparse features
RBF (Gaussian)
K = exp(−γ‖x−z‖²)
Default choice. Works on most tabular datasets. γ controls boundary smoothness
Polynomial
K = (γ xᵢᵀxⱼ + r)ᵈ
Image classification, structured data with known polynomial relationships
RBF kernel — tuning C and gamma PYTHON
from sklearn.model_selection import GridSearchCV

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('svm',    SVC(kernel='rbf', probability=True))
])

param_grid = {
    'svm__C':     [0.1, 1, 10, 100],
    'svm__gamma': ['scale', 'auto', 0.001, 0.01]
    # 'scale' = 1/(n_features * X.var())  ← usually best default
}

gs = GridSearchCV(pipe, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
gs.fit(X_train, y_train)
print(f"Best params: {gs.best_params_}")
print(f"Best CV score: {gs.best_score_:.3f}")
⚠️
Large gamma = overfitting
A very large γ makes the RBF kernel very narrow — each training point only influences its immediate neighbourhood. The result is a boundary that memorises training data perfectly but collapses around every point. Start with gamma='scale' and tune from there.

Classification and Regression with SVMs

sklearn provides SVC (classification) and SVR (regression). SVR introduces an ε-tube around the target: predictions within ε incur no penalty. Only points outside the tube become support vectors.

SVR for regression problems PYTHON
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
import numpy as np

svr_pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('svr', SVR(
        kernel='rbf',
        C=10,       # regularisation — same meaning as SVC
        epsilon=0.1 # tube width: predictions within ε are not penalised
    ))
])
svr_pipe.fit(X_train, y_train)
preds = svr_pipe.predict(X_test)
print(f"RMSE: {np.sqrt(mean_squared_error(y_test, preds)):.3f}")

# LinearSVC / LinearSVR: much faster on large datasets
# Uses liblinear solver instead of libsvm — no kernel trick
from sklearn.svm import LinearSVC
fast_svm = Pipeline([
    ('scaler', StandardScaler()),
    ('svm', LinearSVC(C=1, max_iter=2000))
])

When SVMs Are the Right Tool

ScenarioRecommendation
Small dataset (<10k samples), high-dimensional featuresSVM with RBF kernel often wins — works well when samples < features
Large dataset (>100k samples)Avoid SVC/SVR — training is O(n²) to O(n³). Use LinearSVC, gradient boosting, or neural networks
Text classification (bag of words)LinearSVC — sparse high-dimensional features, linear kernel works perfectly
Need probability estimatesUse probability=True in SVC (adds Platt scaling, slower) or switch to logistic regression
Need interpretabilityUse decision trees — SVMs do not offer feature importance or rules
Mixed numeric/categorical features, missing valuesTree-based models handle this natively. SVMs require extensive preprocessing
💡
The classic SVM sweet spot
SVMs tend to shine on small-to-medium datasets where the decision boundary is complex but the training set is too small for an ensemble to generalise well. Image classification on small datasets (before deep learning), bioinformatics, and text classification with bag-of-words features are classic examples. On tabular data with >10k rows, gradient boosting usually wins.
🎉
Module 3 Complete!
Supervised learning covered. Now turning to unsupervised — finding structure in unlabelled data.
Module 4: Clustering → 📖 Detailed Lessons Course Home
🧩 Module 3 Check
5 questions · instant feedback
1. What are "support vectors" in an SVM?
2. What is the key insight behind the "kernel trick"?
3. You forget to scale features before training an SVM. What is the most likely consequence?
4. In an RBF kernel SVM, increasing gamma (γ) from a small to a large value typically causes:
5. You have 500,000 training samples. Why should you avoid standard SVC?