Machine Learning

Support Vector Machines (SVM): maximizing the margin to classify better

October 5, 2025 14 min read Lorenzo Mascia

Support Vector Machines occupy a special place in Machine Learning. They are rigorous, geometric, and built around a very precise idea of what it means to make a good decision. Instead of trying to be right as often as possible on the training data, SVMs focus on being confidently right. They do this by maximizing the margin, the distance between the decision boundary and the closest data points from each class.

Maximizing the Margin

At a high level, an SVM tries to separate data into classes by drawing a boundary. In the simplest case, this boundary is a straight line. What makes SVMs different is how that line is chosen. Many lines could separate two classes, but the SVM selects the one that leaves the largest possible gap between the classes. This gap is called the margin, and maximizing it leads to decisions that are more stable and more resistant to noise.

The points that define this margin are called support vectors. They are the data points closest to the decision boundary, and they play a crucial role. Move or remove one of them, and the boundary may change. Points farther away from the boundary, on the other hand, barely matter. This gives SVMs a very focused view of the data: they care deeply about the hardest cases and largely ignore the easy ones.

Robust Generalization

This geometric perspective leads to strong generalization. By not hugging the training data too closely, the model avoids overfitting. It chooses a boundary that is not just correct for the examples it has seen, but robust to small variations. In many scenarios, this makes SVMs surprisingly effective even with relatively small datasets.

However, real-world data is rarely perfectly separable. Classes overlap, noise exists, and strict separation may be impossible or undesirable. SVMs address this with the concept of soft margins. Instead of enforcing perfect separation, the model allows some violations, but penalizes them. A parameter controls how harsh this penalty is, creating a trade-off between margin size and classification error. Tuning this balance is central to using SVMs effectively.

The Kernel Trick

Another defining feature of SVMs is their ability to handle non-linear boundaries through kernels. Rather than explicitly transforming the data into a higher-dimensional space, SVMs use kernel functions to compute similarities as if such a transformation had taken place. This allows the model to draw complex, curved decision boundaries while still relying on the same margin-maximization principle. The idea is elegant: change the space, not the algorithm.

Despite their mathematical sophistication, SVMs are not black boxes in spirit. Their behavior is governed by a small number of meaningful choices: how much error to tolerate, which kernel to use, and how flexible the boundary should be. Each choice reflects an assumption about the structure of the data.

To see how this works in practice, let's walk through a concrete example with Python.

A Practical Example

Imagine you want to classify customers as likely or unlikely to subscribe to a service based on two features: time spent on the website and number of visits. The classes overlap slightly, and you want a boundary that is robust rather than overly sensitive.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score

First, let's create a simple dataset.

# Features: [time_on_site (minutes), visits_per_month]
X = np.array([
    [5, 1],
    [10, 2],
    [15, 3],
    [20, 4],
    [8, 1],
    [18, 5],
    [25, 6],
    [30, 7]
])

# Labels: 0 = no subscription, 1 = subscription
y = np.array([0, 0, 0, 1, 0, 1, 1, 1])

Because SVMs are sensitive to feature scale, we standardize the data.

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

Now we split the data.

X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, y, test_size=0.25, random_state=42
)

Next, we create and train a linear SVM.

model = SVC(kernel="linear", C=1.0)
model.fit(X_train, y_train)

The parameter C controls the trade-off between margin size and classification errors. A larger C forces the model to classify training points more strictly, while a smaller C allows a wider margin with more tolerance for mistakes.

Let's evaluate the model.

y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

print("Accuracy:", accuracy)

Now let's make a prediction for a new customer.

new_customer = np.array([[12, 3]])
new_customer_scaled = scaler.transform(new_customer)

prediction = model.predict(new_customer_scaled)
print("Subscription likely:", bool(prediction[0]))

Understanding the Results

This decision is driven by the position of the point relative to the margin defined by the support vectors. The model is not averaging over all data points, nor fitting a complex curve. It is asking a precise geometric question: on which side of the widest possible boundary does this point fall?

Support Vector Machines teach an important lesson about Machine Learning. Better performance does not always come from modeling more detail, but from choosing the right criterion for decision-making. By focusing on margins instead of raw accuracy, SVMs show how strong generalization can emerge from disciplined constraints.

Even in a world dominated by ensembles and deep learning, SVMs remain a valuable tool. They sharpen intuition, reward careful preprocessing, and remind us that geometry, when used wisely, can be a powerful guide to learning.