← back

Implement Kernel PCA with RBF Kernel

#349 · Machine Learning · Hard

⊣ Solve on deep-ml.com

Problem

Implement Kernel PCA using the RBF (Radial Basis Function) kernel. Project data into a higher-dimensional feature space implicitly through the kernel trick, then perform PCA in that space.

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import numpy as np
from typing import Dict

def rbf_kernel(X: np.ndarray, Y: np.ndarray, gamma: float) -> np.ndarray:
    # ||x - y||^2 = ||x||^2 + ||y||^2 - 2 * x.y
    X_sq = np.sum(X ** 2, axis=1).reshape(-1, 1)
    Y_sq = np.sum(Y ** 2, axis=1).reshape(1, -1)
    dist_sq = X_sq + Y_sq - 2 * X @ Y.T
    return np.exp(-gamma * dist_sq)

def kernel_pca(
    X: np.ndarray,
    n_components: int = 2,
    gamma: float = 1.0
) -> Dict:
    n = X.shape[0]

    # Compute kernel matrix
    K = rbf_kernel(X, X, gamma)

    # Center the kernel matrix
    one_n = np.ones((n, n)) / n
    K_centered = K - one_n @ K - K @ one_n + one_n @ K @ one_n

    # Eigendecomposition
    eigenvalues, eigenvectors = np.linalg.eigh(K_centered)

    # Sort by descending eigenvalue
    idx = np.argsort(eigenvalues)[::-1]
    eigenvalues = eigenvalues[idx]
    eigenvectors = eigenvectors[:, idx]

    # Select top components and normalize
    top_eigenvalues = eigenvalues[:n_components]
    top_eigenvectors = eigenvectors[:, :n_components]

    # Project: alpha_i / sqrt(lambda_i)
    for i in range(n_components):
        if top_eigenvalues[i] > 1e-10:
            top_eigenvectors[:, i] /= np.sqrt(top_eigenvalues[i])

    X_transformed = K_centered @ top_eigenvectors

    return {
        "transformed": X_transformed.tolist(),
        "eigenvalues": top_eigenvalues.tolist(),
        "n_components": n_components,
        "gamma": gamma
    }

Explanation

  1. Compute the RBF kernel matrix K where K[i,j] = exp(-gamma * ||x_i - x_j||^2).
  2. Center the kernel matrix using the double-centering formula: K_c = K - 1_nK - K1_n + 1_nK1_n.
  3. Perform eigendecomposition on the centered kernel matrix. The top eigenvectors correspond to the principal components in the kernel feature space.
  4. Normalize eigenvectors by 1/sqrt(eigenvalue) and project data to get the reduced representation.

Complexity

  • Time: O(n^3) for eigendecomposition of the n x n kernel matrix
  • Space: O(n^2) for the kernel matrix