Support Vector Machine
🎯 Binary Classification with Hyperplanes
Support Vector Machine (SVM) is a powerful supervised learning algorithm used for both classification and regression tasks. In classification, SVM finds the optimal hyperplane that best separates different classes in the feature space.
What is a Support Vector Machine?
Support Vector Machine (SVM) is a supervised learning algorithm that finds the optimal hyperplane to separate different classes in the feature space.
Core Idea: Find the hyperplane that maximizes the margin between classes
How SVM Works
SVM works by mapping input features into a high-dimensional space and finding the hyperplane that best separates the classes. The data points closest to the hyperplane are called support vectors, and they play a crucial role in defining the decision boundary.
Graphical representation of Support Vector Machine concepts
- Hyperplane: A decision boundary that separates different classes
- Margin: The distance between the hyperplane and the nearest data points from each class
- Support Vectors: Data points that are closest to the hyperplane and influence its position
Setup Rules for the Hard-Margin Derivation
To derive the mathematical formulas for the basic Hard-Margin SVM, we must first establish a strict setup where the following conditions hold true:
- Perfect Linear Separability: We assume the training data is completely clean and can be split cleanly into two groups using a straight line, with no overlapping points.
- The Hyperplane Formula: We define our center decision boundary using the linear matrix equation: $w \cdot x + b = 0$.
- The Classifier Function: We define our decision rule $h(x)$ to output a discrete label based on which side of the line a point falls on:
$$h(x) = \begin{cases} +1 & \text{if } w \cdot x + b \geq 0 \\ -1 & \text{if } w \cdot x + b < 0 \end{cases}$$
- Symmetric Safety Margins: We assume the empty safety buffer zone extends out by the exact same distance on both the positive side ($+1$) and the negative side ($-1$) of our center line.
Derivation
Calculation of Margin Distance
Let $x$ be a data point (such as a Support Vector) and $x_p$ be its orthogonal projection onto the central decision hyperplane. The vector pointing from $x_p$ to $x$ is perpendicular to the hyperplane, which means it runs perfectly parallel to the weight vector $w$.
We can express $x$ in terms of $x_p$, the unit vector of $w$ (given by $\frac{w}{\|w\|}$), and the scalar distance $r$:
$$x = x_p + r \frac{w}{\|w\|}$$
Because $x_p$ lies exactly on the separating hyperplane, it must satisfy the hyperplane equation:
$$w \cdot x_p + b = 0 \implies w \cdot x_p = -b$$
Now, we take the dot product of the weight vector $w$ across our entire structural position equation:
$$w \cdot x = w \cdot \left(x_p + r \frac{w}{\|w\|}\right)$$
$$w \cdot x = w \cdot x_p + r \frac{w \cdot w}{\|w\|}$$
Using the vector identities $w \cdot x_p = -b$ and $w \cdot w = \|w\|^2$, we can substitute these values right back into the expression:
$$w \cdot x = -b + r \frac{\|w\|^2}{\|w\|}$$
$$w \cdot x = -b + r \|w\|$$
Isolating the scalar distance $r$ gives us the exact geometric distance from any arbitrary point to the hyperplane matrix:
$$r = \frac{w \cdot x + b}{\|w\|}$$
Since geometric distance must remain strictly positive regardless of which side of the hyperplane the boundary point sits on, we express the absolute perpendicular magnitude as:
$$\|d\| = \frac{|w \cdot x + b|}{\|w\|}$$
The Optimization Strategy
Building the mathematical objective follows four simple steps: finding the closest points, maximizing their distance, scaling the math for the computer, and converting to a minimization problem.
1. Find the Closest Points
First, we find the data samples that sit closest to our decision line. These critical points are called Support Vectors:
$$\text{Minimum Perpendicular Distance} = \min \frac{|w \cdot x_i + b|}{\|w\|}$$
2. Maximize the Safety Margin
The total margin is twice the distance to these closest points. The core philosophy of SVM is to make this minimum gap as wide as possible:
$$\text{Maximize } 2 \cdot \left[ \min \frac{|w \cdot x_i + b|}{\|w\|} \right]$$
3. Scale the Baseline to 1
Because we can scale the weights ($w$) and bias ($b$) by any number without shifting the physical position of the boundary line, we pick a scale that simplifies our math. We force the raw functional output of the closest points to equal exactly $1$:
$$\min |w \cdot x_i + b| = 1$$
Plugging this baseline scale back into our maximization step allows us to drop the complex absolute value and minimization terms entirely, leaving a clean optimization problem:
$$\text{Maximize } \frac{2}{\|w\|} \quad \text{subject to } y_i(w \cdot x_i + b) \geq 1$$
4. Flip it to a Minimization Problem
Right now, our goal is to maximize $\frac{2}{\|w\|}$. But calculus tools and computer programs are much better at minimizing things rather than maximizing them.
Maximizing $\frac{2}{\|w\|}$ is the exact same thing as minimizing its flipped version, $\frac{\|w\|}{2}$. To make the math even smoother for computer programs to solve without any weird jumps, we square the norm and add a constant multiplier:
$$\text{minimize } \frac{1}{2}\|w\|^2$$
$$\text{subject to: } y_i(w \cdot x_i + b) \geq 1$$
This is the final, standard form of the SVM problem. It gives the computer a crystal-clear job: make the weights as small as possible while keeping all data points outside the safety line.
The Mathematical Bridge: Lagrange Multipliers & The Dual Form
To solve an optimization problem tied down by strict boundary constraints, mathematicians use a technique called Lagrange Multipliers ($\alpha_i \geq 0$). We combine our optimization goal and our boundaries into a single expression called the Lagrangian function ($L$):
$$L(w, b, \alpha) = \frac{1}{2}\|w\|^2 - \sum_{i=1}^{n} \alpha_i \left[ y_i(w \cdot x_i + b) - 1 \right]$$
To find the absolute best boundary line, we calculate the partial derivatives of $L$ with respect to our main variables ($w$ and $b$) and set them to zero:
$$\frac{\partial L}{\partial w} = 0 \implies w = \sum_{i=1}^{n} \alpha_i y_i x_i$$
$$\frac{\partial L}{\partial b} = 0 \implies \sum_{i=1}^{n} \alpha_i y_i = 0$$
Substituting these identities back into our original equation completely eliminates the weight vector $w$. This transforms our system into its mathematical twin, known as the Wolfe Dual Problem:
$$\text{Maximize: } W(\alpha) = \sum_{i=1}^{n} \alpha_i - \frac{1}{2} \sum_{i=1}^{n} \sum_{j=1}^{n} \alpha_i \alpha_j y_i y_j (\mathbf{x_i \cdot x_j})$$
$$\text{Subject to: } \alpha_i \geq 0 \quad \text{and} \quad \sum_{i=1}^{n} \alpha_i y_i = 0$$
The Core Realization: Look closely at the Dual equation. The data points now interact with each other only through a raw dot product $(\mathbf{x_i \cdot x_j})$. This specific interaction is the key that unlocks non-linear boundaries.
The Kernel Trick: Unlocking Higher Dimensions
When features are mixed together like a target ring, no straight line can separate them in 2D space. To fix this, we can project our coordinates into a higher dimension where a flat plane can slice them cleanly. However, calculating new coordinates for thousands of points would crash our computer's memory.
Because our Dual equation relies entirely on the dot product $(\mathbf{x_i \cdot x_j})$, we can apply the Kernel Trick. We replace the linear product with a specialized Kernel function $K(x_i, x_j)$:
$$W(\alpha) = \sum_{i=1}^{n} \alpha_i - \frac{1}{2} \sum_{i=1}^{n} \sum_{j=1}^{n} \alpha_i \alpha_j y_i y_j \, \mathbf{K(x_i, x_j)}$$
A Kernel is a mathematical shortcut. It calculates what the geometric relationship between points would be in that infinite higher-dimensional space without ever calculating or storing the complex new coordinates themselves.
Dealing with Real-World Data: Soft-Margin SVM
Up until now, we assumed our data is perfectly clean and can be split with a straight line. But in the real world, data points overlap and mix together. If we try to enforce a hard boundary, the computer will fail or create a messy line that does not generalize well.
The Slack Variable ($\xi$)
To fix this, we introduce a new variable called $\xi$ (pronounced "xi"), which acts like a penalty score for points that misbehave. It measures exactly how far a data point sneaks inside the safety zone or crosses over to the wrong side:
$$\xi_i = \begin{cases} 1 - y_i(w \cdot x_i + b) & \text{if } y_i(w \cdot x_i + b) < 1 \quad \text{(Point breaks the rule)} \\ 0 & \text{if } y_i(w \cdot x_i + b) \geq 1 \quad \text{(Point is safe)} \end{cases}$$
The New Optimization Problem
Now, our updated rule says that points are allowed to cross the margin lines slightly, but they pay a price for it. The new formula looks like this:
$$\text{minimize } \frac{1}{2}\|w\|^2 + C \sum_{i=1}^{n} \xi_i$$
$$\text{subject to: } y_i(w \cdot x_i + b) \geq 1 - \xi_i \quad \text{and } \xi_i \geq 0$$
The Tuning Knob: The $C$ Hyperparameter
The letter $C$ is a tuning knob we use to tell the computer how heavily to punish mistakes. Changing $C$ completely shifts the model's behavior:
- When $C$ is huge ($C \to \infty$): You are extremely strict. The computer will do anything to avoid mistakes, making the model behave exactly like a rigid, Hard-Margin SVM. This can lead to overfitting if the data is messy.
- When $C$ gets close to zero ($C \to 0$): You don't care about mistakes at all. The computer will only try to make the margin as wide as possible, ignoring the errors. As a result, the SVM won't be able to classify the points properly.
Connecting Optimization to Code: Primal Hinge Loss
While the Dual Form is perfect for complex non-linear kernels, implementing a fast Linear Kernel can be done directly in the Primal Form using Gradient Descent. We collapse our soft-margin constraints into a single, codeable Cost Function ($J$) using Hinge Loss and $L_2$ Regularization:
$$J(w, b) = \|w\|^2 + \frac{C}{n} \sum_{i=1}^{n} \max\left(0, 1 - y_i(w \cdot x_i + b)\right)$$
During training, the program checks if a point satisfies the safety boundary condition: $y_i(w \cdot x_i + b) \geq 1$ and compute the partial derivatives to adjust our weights and bias:
$$\text{If Safe: } \frac{\partial J}{\partial w} = 2 w, \quad \frac{\partial J}{\partial b} = 0$$
$$\text{If Violated: } \frac{\partial J}{\partial w} = 2 w - C y_i x_i, \quad \frac{\partial J}{\partial b} = -C y_i$$
NumPy Scratch Implementation
From Scratch with NumPy:
import numpy as np
class SupportVectorMachine_linear:
def __init__(self, C=1.0, learning_rate=0.01, epochs=1000):
self.lr = learning_rate
self.C = C
self.epochs = epochs
self.w = None # Weights
self.b = None
def fit(self, X, y):
# Fit the model to the training data
n_samples, n_features = X.shape
self.w = np.random.rand(n_features) * 0.1 #Randomly assigned the weights
self.b = np.random.rand(1) * 0.1 # Randomly assigned bias
for epoch in range(self.epochs):
for i in range(n_samples):
# Compute the hinge loss
condition = y[i] * (np.dot(self.w, X[i]) + self.b)
if condition >= 1:
# Update weight
self.w -= self.lr * ( 2 * self.w)
else:
# Update weights and bias
self.w -= self.lr * (2 * self.w - self.C * y[i] * X[i])
self.b += self.lr * (self.C * y[i])
def predict(self, X):
# Make predictions on new data
z = np.dot(X, self.w) + self.b
return np.sign(z)
Using scikit-learn
Quick Implementation:
from sklearn.svm import SVC
# Initialize linear kernel classifier
clf = SVC(kernel='linear', C=1.0)
# Train the model
clf.fit(X_train, y_train)
# Make class label predictions
predictions = clf.predict(X_test)
Advantages & Disadvantages
✓ Advantages: Ready to explore advanced classification? Check out Supervised Learning overview for more algorithms!
• Extremely memory efficient since decisions depend only on support vectors
✗ Disadvantages:
• Highly sensitive to feature scaling and requires proper normalization
Evaluation Metrics for Classification