Kernel Methods: SVM Kernel and Kernel PCA

Méthodes à Noyaux : Guide Complet — SVM Kernel et Kernel PCA

Kernel Methods

Summary

Kernel methods are one of the most elegant advances in classical machine learning. Their central idea, the kernel trick, allows solving nonlinearly separable problems by working implicitly in a large — or even infinite — dimensional space, without ever having to explicitly compute the underlying transformation. This complete guide covers the mathematical principle, geometric intuition, Python implementations with scikit-learn (Kernel SVM and Kernel PCA), hyperparameter optimization, as well as four real-world use cases in production.

Mathematical Principles

The Kernel Trick

The fundamental problem of linear machine learning is simple: many datasets are not linearly separable in their original space. One could try to project each point xᵢ into a higher-dimensional space via a transformation φ(xᵢ), then apply a linear algorithm in this enriched space. But this explicit computation of φ(x) can be prohibitive, or even impossible when the target space is infinite-dimensional.

The kernel trick solves this paradox magnificently. Instead of computing φ(xᵢ) then forming the dot product ⟨φ(xᵢ), φ(xⱼ)⟩ in the high-dimensional space, one directly computes:

K(xᵢ, xⱼ) = ⟨φ(xᵢ), φ(xⱼ)⟩

The function K is called a kernel function. It takes two vectors from the original space and returns a scalar — exactly what a dot product would do after projection, but without ever needing to know φ explicitly.

The RBF Kernel (Radial Basis Function)

The RBF kernel, also called the Gaussian kernel, is the most commonly used in practice:

K(xᵢ, xⱼ) = exp(−γ · ‖xᵢ − xⱼ‖²)

where γ (gamma) is a positive hyperparameter that controls the width of the Gaussian function. The larger γ is, the more sensitive the kernel is to small distances between points. This kernel corresponds to a projection into an infinite-dimensional space — precisely what makes it so powerful and so difficult to compute explicitly.

The RBF kernel has a remarkable property: it is universal. This means that any continuous function can be approximated arbitrarily well by a linear combination of RBF kernels centered on training points. This property is why SVMs with RBF kernels excel on a wide variety of problems.

The Polynomial Kernel

The polynomial kernel is a popular alternative:

K(xᵢ, xⱼ) = (γ · xᵢ · xⱼ + coef0)^degree

where γ is the multiplier coefficient, coef0 is a constant term (which adds flexibility), and degree (denoted d) is the polynomial degree.

For degree = 1, we get the linear kernel. For degree = 2, the kernel corresponds to a projection including all cross-products xₐ · x_b and all quadratic combinations. The higher the degree, the richer the implicit space becomes — but also the higher the risk of overfitting.

Mercer’s Theorem

Not every function can serve as a kernel. Mercer’s theorem provides the necessary and sufficient condition: a function K is a valid kernel if and only if the Gram matrix K (whose elements Kᵢⱼ = K(xᵢ, xⱼ)) is positive semi-definite for any finite set of points {x₁, …, xₙ}.

In other words, for any sequence of real coefficients c₁, …, cₙ, we must have:

Σᵢ Σⱼ cᵢ · cⱼ · K(xᵢ, xⱼ) ≥ 0

This condition guarantees that the associated optimization problem (e.g., the quadratic optimization of SVM) is convex and therefore has a unique global minimum. The RBF, polynomial, and linear kernels all satisfy this condition.

Kernel PCA (Kernel Principal Component Analysis)

Kernel Principal Component Analysis (Kernel PCA) generalizes classical PCA to nonlinear data. While standard PCA projects data onto the eigenvectors of the covariance matrix (capturing directions of greatest linear variance), Kernel PCA proceeds as follows:

  1. One computes the Gram matrix K where Kᵢⱼ = K(xᵢ, xⱼ) for a chosen kernel (RBF, polynomial, etc.)
  2. One centers this Gram matrix: K̃ = K − 1ₙK − K1ₙ + 1ₙK1ₙ, where 1ₙ is the n × n matrix whose every element is 1/n
  3. One computes the eigenvalues λₖ and eigenvectors αₖ of the centered matrix K̃
  4. The projection of a point x onto the k-th principal component is given by: zₖ = Σᵢ αₖⁱ · K(xᵢ, x)

Unlike classical PCA, Kernel PCA can capture complex nonlinear structures such as spirals, concentric circles, or curved manifolds.

Geometric Intuition: Chinese Shadows

To understand why the kernel trick works, imagine Chinese shadows projected on a wall.

You observe two silhouettes of objects on the wall, and these silhouettes are intertwined — impossible to draw a straight line to separate them. This is exactly the problem of linear separability in two dimensions: data from each class is mixed in a nonlinear way.

Now, imagine you could lift the objects into three dimensions. By adding this third dimension (the transformation φ), the two silhouettes end up at different heights. Suddenly, you could slide a flat sheet between them — a linear separation becomes possible.

That’s the essence of the kernel trick: directly computing this 3D separability without having to construct the 3D world. We stay in two dimensions, our data hasn’t moved, but thanks to the kernel K, we have the power of 3D without paying the computational cost.

It’s as if you could determine whether two silhouettes can be separated in the third dimension simply by looking at their relative distance on the wall, without ever having to manipulate the 3D object. The kernel is this magical formula that replaces explicit geometry with a similarity computation.

Python Implementation with scikit-learn

Kernel SVM on Nonlinear Data (Moons)

Let’s start with a classic example: the “moons” dataset (two intertwined half-moons), inherently nonlinearly separable.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import classification_report, accuracy_score
from sklearn.decomposition import KernelPCA
from sklearn.preprocessing import StandardScaler

# Data generation
X, y = make_moons(n_samples=1000, noise=0.15, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42
)

# Standardization (important for distance-based kernels)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# ----- Kernel comparison -----
kernels = {
    "linear": "linear",
    "polynomial (deg=3)": "poly",
    "RBF": "rbf"
}

fig, axes = plt.subplots(1, 3, figsize=(18, 5))

for idx, (name, k_type) in enumerate(kernels.items(), 1):
    # Configure SVM according to kernel type
    if k_type == "poly":
        svm = SVC(kernel=k_type, degree=3, coef0=1.0, C=1.0, random_state=42)
    else:
        svm = SVC(kernel=k_type, C=1.0, gamma="scale", random_state=42)

    svm.fit(X_train_scaled, y_train)
    y_pred = svm.predict(X_test_scaled)

    print(f"Kernel {name} — Accuracy: {accuracy_score(y_test, y_pred):.4f}")

    # Decision boundary visualization
    ax = axes[0] if idx == 1 else (axes[1] if idx == 2 else axes[2])
    h = 0.02
    x_min, x_max = X_train_scaled[:, 0].min() - 0.5, X_train_scaled[:, 0].max() + 0.5
    y_min, y_max = X_train_scaled[:, 1].min() - 0.5, X_train_scaled[:, 1].max() + 0.5
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    Z = svm.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    ax.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
    ax.scatter(X_train_scaled[:, 0], X_train_scaled[:, 1], c=y_train,
               edgecolors="k", cmap=plt.cm.coolwarm, s=30)
    ax.set_title(f"SVM — {name} kernel")
    ax.set_xlabel("x₁")
    ax.set_ylabel("x₂")

plt.tight_layout()
plt.savefig("svm_kernels_comparison.png", dpi=150)
plt.show()

The comparison is striking: the linear kernel completely fails on moon-shaped data, while the RBF and polynomial kernels perfectly capture the nonlinear structure of the two half-moons.

Kernel PCA with Visualization

Kernel PCA excels where classical PCA fails. Let’s illustrate this with spiral-shaped data:

from sklearn.decomposition import PCA

# Generate spiral data (even more nonlinear)
def make_spiral(n_points=500, noise=0.1, random_state=42):
    rng = np.random.RandomState(random_state)
    n = n_points // 2
    t1 = np.linspace(0, 3 * np.pi, n)
    t2 = np.linspace(0, 3 * np.pi, n)

    x1 = t1 * np.cos(t1) + rng.randn(n) * noise
    y1 = t1 * np.sin(t1) + rng.randn(n) * noise
    x2 = t2 * np.cos(t2 + np.pi) + rng.randn(n) * noise
    y2 = t2 * np.sin(t2 + np.pi) + rng.randn(n) * noise

    X_spiral = np.vstack([
        np.column_stack([x1, y1]),
        np.column_stack([x2, y2])
    ])
    y_spiral = np.array([0] * n + [1] * n)

    return X_spiral, y_spiral

X_sp, y_sp = make_spiral(n_points=600, noise=0.3)

# Classical PCA vs Kernel PCA
fig, axes = plt.subplots(1, 3, figsize=(18, 5))

# Original data
axes[0].scatter(X_sp[:, 0], X_sp[:, 1], c=y_sp, cmap=plt.cm.coolwarm,
                edgecolors="k", s=30, alpha=0.8)
axes[0].set_title("Original data (spirals)")
axes[0].set_xlabel("x₁")
axes[0].set_ylabel("x₂")

# Classical PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_sp)
axes[1].scatter(X_pca[:, 0], X_pca[:, 1], c=y_sp, cmap=plt.cm.coolwarm,
                edgecolors="k", s=30, alpha=0.8)
axes[1].set_title("Classical PCA (fails)")
axes[1].set_xlabel("PC1")
axes[1].set_ylabel("PC2")

# Kernel PCA with RBF kernel
kpca = KernelPCA(n_components=2, kernel="rbf", gamma=0.05, random_state=42)
X_kpca = kpca.fit_transform(X_sp)
axes[2].scatter(X_kpca[:, 0], X_kpca[:, 1], c=y_sp, cmap=plt.cm.coolwarm,
                edgecolors="k", s=30, alpha=0.8)
axes[2].set_title("Kernel PCA RBF (success)")
axes[2].set_xlabel("KPC1")
axes[2].set_ylabel("KPC2")

plt.tight_layout()
plt.savefig("kpca_vs_pca.png", dpi=150)
plt.show()

The result is unambiguous: classical PCA mixes the two spirals in the reduced space, while Kernel PCA separates them perfectly thanks to the nonlinear projection induced by the RBF kernel.

Grid Search on gamma and C

Optimizing γ and C hyperparameters is crucial for kernel SVMs. Here’s the systematic approach:

from sklearn.model_selection import GridSearchCV

# Search grid for gamma and C
param_grid = {
    "C": [0.1, 1.0, 10.0, 100.0],
    "gamma": [0.01, 0.1, 1.0, 10.0],
    "kernel": ["rbf"]
}

grid_search = GridSearchCV(
    SVC(random_state=42),
    param_grid,
    cv=5,
    scoring="accuracy",
    n_jobs=-1,
    verbose=1
)

grid_search.fit(X_train_scaled, y_train)

print(f"Best parameters: {grid_search.best_params_}")
print(f"Best accuracy (CV): {grid_search.best_score_:.4f}")

# Evaluation on test set
best_svm = grid_search.best_estimator_
y_pred_test = best_svm.predict(X_test_scaled)
print(f"Test accuracy: {accuracy_score(y_test, y_pred_test):.4f}")

# Performance surface visualization
C_values = param_grid["C"]
gamma_values = param_grid["gamma"]
scores = grid_search.cv_results_["mean_test_score"]
scores = scores.reshape(len(C_values), len(gamma_values))

plt.figure(figsize=(10, 6))
im = plt.imshow(scores, cmap="viridis", aspect="auto")
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 — Mean CV accuracy")
plt.colorbar(im, label="Accuracy")
for i in range(len(C_values)):
    for j in range(len(gamma_values)):
        plt.text(j, i, f"{scores[i, j]:.3f}",
                 ha="center", va="center", color="white")
plt.tight_layout()
plt.savefig("grid_search_heatmap.png", dpi=150)
plt.show()

Detailed Hyperparameters

The choice of hyperparameters for a kernel SVM fundamentally determines the model’s behavior. Here is a detailed guide:

Hyperparameter Role Impact Typical values
kernel Kernel type Determines the shape of the decision boundary “linear”, “poly”, “rbf”, “sigmoid”
gamma Inverse radius of influence (RBF) Low gamma = smooth boundary, high gamma = complex boundary 0.001 to 10.0
C Error penalty Low C = wide margin (underfitting), high C = narrow margin (overfitting) 0.01 to 1000
degree Polynomial degree The higher degree, the more flexible the boundary 2 to 5
coef0 Polynomial kernel constant term Influences the polynomial shape, especially for low degrees 0.0 to 1.0

Gamma: the critical RBF kernel parameter

Gamma is arguably the most important hyperparameter for the RBF kernel. The default “scale” value in scikit-learn computes γ = 1 / (n_features × variance), which is a good starting point. But depending on your data distribution, an adjustment may be needed:

  • Too low gamma: the decision boundary is too smooth, the model underfits and misses the fine structure of the data.
  • Too high gamma: each training point influences a very restricted area, creating an excessively complex boundary that overfits noise.
  • Optimal gamma: captures the true structure of the data without modeling sampling noise.

C: complexity control

The C parameter determines the margin / classification error trade-off:

  • Low C: prioritizes a wide margin, accepts more training errors. Result: simpler, more generalizable model.
  • High C: forces the model to classify every training point correctly, at the expense of margin. Result: complex boundary, risk of overfitting.

In practice, C is explored on a logarithmic scale (0.01, 0.1, 1, 10, 100) combined with gamma.

Advantages and Limitations

Advantages

  • Nonlinear power without computational cost: thanks to the kernel trick, kernel methods solve infinite-dimensional problems with computations in the original dimension. This is one of the most elegant results in machine learning.
  • Works well in low dimensions: unlike deep neural networks that require a lot of data, kernel SVMs excel with moderately sized samples (a few hundred to a few thousand observations).
  • Strong theoretical guarantees: Mercer’s theorem guarantees convexity of the optimization, and Vapnik-Chervonenkis theory provides rigorous generalization bounds.
  • Kernel flexibility: custom kernels can be designed for specific data types (graph kernels, string kernels, distribution kernels).
  • Robustness to overfitting: thanks to the C parameter and margin maximization, kernel SVMs are inherently robust, especially in high dimensions.

Limitations

  • O(n²) to O(n³) complexity: computing and storing the Gram matrix becomes prohibitive beyond 50,000 to 100,000 samples. For very large datasets, approximations like Nyström or random Fourier features are necessary.
  • Sensitivity to hyperparameters: performance depends heavily on the choice of γ and C. A bad tuning can lead to disaster — hence the critical importance of cross-validation.
  • Reduced interpretability: unlike a decision tree or linear regression, the decision boundary of an RBF kernel SVM is practically impossible for a human to interpret.
  • Costly prediction: to classify a new point, the SVM must evaluate the kernel against all support vectors. If the number of support vectors is large (which happens with a high C), prediction is slow.
  • No native probabilities: SVM produces raw decision scores. To obtain probabilities, additional calibration (Platt scaling) is needed, which adds computational cost.

Four Real-World Use Cases

1. Text Classification with Sequence Kernels

In natural language processing (NLP), documents are often represented as bags of words. But this representation loses word order. A sequence kernel (string kernel) captures common subsequences between two documents while respecting their order, significantly improving text classification, spam detection, or sentiment analysis. In practice, an SVM with a polynomial kernel of degree 2 or 3 is used, which captures interactions between adjacent words.

2. Medical Diagnosis by Imaging

In medical image analysis (X-rays, MRI, CT scans), RBF kernel SVMs are frequently used to classify benign versus malignant lesions. Extracted features (texture, shape, intensity) form a low-dimensional space where the separation is highly nonlinear. The RBF kernel captures these complex interactions without requiring thousands of examples as a deep neural network would — a crucial advantage when annotated medical data is rare and costly to obtain.

3. Anomaly Detection with One-Class SVM

One-Class SVM is a variant of kernel methods for anomaly detection. Instead of separating two classes, it learns the boundary that encompasses the normal data distribution. Any point outside this boundary is flagged as anomalous. Typical applications: banking fraud detection, industrial quality monitoring, cybersecurity surveillance. The RBF kernel is particularly well suited here because it models local data density without parametric assumptions.

4. Nonlinear Dimensionality Reduction with Kernel PCA

Kernel PCA serves as a preprocessing step before other machine learning algorithms. Imagine you have high-dimensional genomic data (thousands of genes) with an underlying nonlinear structure (interactive metabolic pathways). Classical PCA will only capture linear variance, missing gene interactions. Kernel PCA with an RBF kernel projects this data into a reduced space where nonlinear structures are preserved, subsequently improving the performance of a classifier or clustering model applied to the kernel principal components.

See Also

About Salah YAHIAOUI

Salah YAHIAOUI publie sur The Pingouin des tutoriels Python et des décryptages sur l’intelligence artificielle. Les cas pratiques récents précisent leurs données, leurs tests et leurs limites. À propos, méthode éditoriale et contact.

View all posts by Salah YAHIAOUI →