Kernel SVMs from Scratch

Fall 2025 • Machine Learning Course

Kernel SVMs from Scratch

Support vector machines are one of the most important classical classifiers, and kernels are what let a linear method learn curved decision boundaries without ever computing the curved features directly. Calling a library hides all of that. In this assignment we built binary SVM classifiers from scratch in NumPy, writing every objective, constraint matrix, and kernel by hand. CVXOPT was used only as the quadratic program solver and SciPy only for unconstrained minimization, with no scikit-learn anywhere.

What We Built

  • Primal form. A linear classifier with L2 regularization, trained two ways: the hinge loss written as a quadratic program for CVXOPT, and the smooth ExpLinear loss minimized directly with SciPy.
  • Adjoint form. The same two losses rewritten in terms of the training points, so any kernel can be plugged in: linear, polynomial of degree 2 and 3, and Gaussian of several widths.
  • Dual form. The classic SVM dual with the hinge loss, solved as a quadratic program over the kernel matrix, with its own classifier for new points.
  • Model selection. 5 fold cross validation over the regularization strength λ and seven kernels, run on handwritten 4s and 9s from MNIST.

The synthetic tests used three datasets of increasing difficulty: Model 1 is linearly separable, Model 2 needs an oval boundary, and Model 3 is two interleaving moons.

Results

Test accuracy by kernel (adjoint form)

KernelExpLinear M1ExpLinear M2ExpLinear M3Hinge M1Hinge M2Hinge M3
Linear0.98890.56950.88400.98630.60340.8802
Poly (d = 2)0.98590.97950.88260.98310.97130.8793
Poly (d = 3)0.97510.96380.99290.96990.96000.9862
Gauss (σ = 1)0.97230.96720.99770.96370.96570.9946
Gauss (σ = 0.5)0.95870.96250.99820.95960.95880.9981

A linear boundary is close to guessing on the oval dataset (57% to 60%), while polynomial and Gaussian kernels lift it to about 96% to 98%.

Best kernel and loss for each dataset

DatasetBest kernelBest lossTest accuracy
Model 1 (linear)LinearExpLinear0.989
Model 2 (oval)Poly (d = 2)ExpLinear0.979
Model 3 (moons)Gauss (σ = 0.5)Hinge0.998

MNIST 4 vs 9: 5 fold cross validated accuracy (dual form)

λLinearPoly 2Poly 3Gauss 1Gauss 3Gauss 5Gauss 8
0.0010.9580.9760.9740.4680.9720.9790.974
0.010.9580.9760.9740.4680.9720.9790.974
0.10.9580.9750.9750.4680.9720.9790.977
10.9580.9750.9750.4640.9700.9790.971
100.9680.9750.9740.4620.8400.9470.944

We chose a Gaussian kernel with σ = 5 and λ = 0.1: it ties for the best accuracy, 97.9%, while keeping enough regularization to avoid overfitting to unusual samples.

What We Learned

  • The kernel matters far more than the loss: ExpLinear and hinge stayed within about 3 points of each other everywhere, while switching kernels moved accuracy by as much as 41 points.
  • Match the kernel to the data. The linear kernel won on linearly separable data, and Gaussian kernels won on the moons, reaching 99.8% test accuracy.
  • Flexible kernels overfit. A narrow Gaussian (σ = 0.5) hit 100% training accuracy on every dataset but lost up to 4.1 points on the test set.
  • On clean data, more regularization is not free: raising λ slightly lowered accuracy, because there was little noise to protect against.

Completed as a pair assignment with a teammate. The code stays private since it is graded coursework.

Technologies

PythonNumPyCVXOPTSciPypandas