A Support Vector Machine (SVM) doesn't just draw any line between two groups. It draws the line with the widest possible gap on both sides. With a clever trick, it can also draw curves, circles and complex shapes. SVMs were among the most powerful algorithms in machine learning for years, and they're still excellent on many problems today.
- Level: Intermediate
- Time: about 35 minutes
- Needs: Modules 1 to 8
By the end of this module you will be able to
- Explain what an SVM looks for when it draws a boundary
- Describe the margin and the support vectors
- Explain the soft margin and how the setting C controls it
- Explain the kernel trick in simple terms
- Choose between linear, polynomial and RBF kernels, and tune gamma
- Know when an SVM is a good choice and when it isn't
- Build and tune an SVM that reads handwritten digits in scikit-learn
9.1What is a Support Vector Machine?
Imagine two villages on either side of a field, and the council wants to build a road between them. They could build a narrow lane squeezed right up against one village's houses. Or they could build the widest possible road, running right down the middle, with as much space as possible on both sides. The second option is safer: there's plenty of room for error.
An SVM does exactly that with data. For a classification problem, it looks for the boundary that separates the classes with the biggest gap between them.
SVMs in one sentence
A Support Vector Machine finds the boundary that separates the classes with the widest possible margin, so new data is less likely to land on the wrong side.
SVMs are mainly used for classification, though there's also a version for regression (lesson 9.7). They work especially well when there are lots of features, such as text or images.
9.2Which line is best?
When two groups are cleanly separated, there are endless lines that could divide them. Logistic regression (Module 4) picks one based on probabilities. An SVM asks a different question: which line gives the most breathing room?
The idea is simple: if the boundary is far from all the training points, then a new point that's slightly different from what we've seen is still likely to land on the correct side. A wide gap means better generalisation, the thing we care about most (Module 5).
9.3The margin and support vectors
| Term | Meaning |
|---|---|
| Decision boundary (hyperplane) | The line that separates the classes. With 2 features it's a line, with 3 it's a flat plane, and with more it's called a hyperplane |
| Margin | The gap between the boundary and the nearest points on each side. The SVM makes it as wide as possible |
| Support vectors | The training points closest to the boundary, sitting on the edge of the margin |
Here's the surprising part: only the support vectors matter. You could delete every other point, retrain, and get exactly the same boundary. They "support" the margin like tent poles hold up a tent, which is where the algorithm gets its name.
Why this is useful
Because the boundary depends only on the tricky points near the border, SVMs aren't distracted by the thousands of "easy" examples far away. That focus is one reason they perform well even with lots of features.
9.4The soft margin and the C setting
Real data is rarely perfectly separable. There's usually some overlap: a few customers who "should" have stayed but left anyway. A strict SVM that demands every point is on the correct side would fail, or draw a terrible boundary to fit a few odd points.
The solution is a soft margin: the SVM is allowed to let some points sit inside the margin, or even on the wrong side, but it pays a penalty for each one. The setting C controls how big that penalty is.
Try it: change C
| Small C (e.g. 0.01) | Large C (e.g. 100) | |
|---|---|---|
| Attitude to mistakes | Relaxed: "a few errors are fine" | Strict: "avoid every training error" |
| Margin | Wide | Narrow |
| Support vectors | Many | Few |
| Risk | Underfitting | Overfitting to odd points |
C is a hyperparameter, just like k in KNN or max_depth in trees. As always, choose it with cross-validation. Good values to try are 0.1, 1, 10 and 100.
9.5The kernel trick
So far, SVMs draw straight lines. But what if the data looks like this: one group in the middle, the other on both sides?
That's the key idea: data that can't be separated by a straight line might become separable if you look at it in more dimensions. A straight line in the new, bigger space becomes a curve when you bring it back to the original space.
Creating all those extra features could be slow. The kernel trick is a mathematical shortcut that lets the SVM work as if it had added the extra dimensions, without ever actually creating them. You don't need to know the maths; you just choose a kernel.
An everyday picture
Imagine red and blue marbles mixed on a table, with the blue ones in the middle. You can't separate them with a ruler. Now imagine hitting the table so the blue ones jump up into the air. For a split second, you could slide a sheet of paper between them. That's what a kernel does: it "lifts" the data into a new dimension where a flat cut works.
9.6Choosing a kernel
| Kernel | Boundary shape | When to use it | scikit-learn |
|---|---|---|---|
| Linear | Straight line (hyperplane) | Many features, such as text; or data that's nearly separable by a line. Fastest | SVC(kernel="linear") |
| Polynomial | Curves of a set complexity (degree) | When you expect interactions between features. Less common | SVC(kernel="poly", degree=3) |
| RBF (radial basis function) | Flexible curves, circles, islands | The default and best starting point for most problems | SVC(kernel="rbf") |
Gamma: how curvy can the RBF boundary get?
The RBF kernel has a second setting, gamma. It controls how far each training point's influence reaches.
- Small gamma: each point influences a wide area, so the boundary is smooth and simple.
- Large gamma: each point only influences a tiny area around itself, so the boundary can wrap tightly around individual points.
C and gamma work together, so it's normal to tune them at the same time with GridSearchCV, just as you'll see in lesson 9.8.
Always scale your features
SVMs measure distances between points, just like KNN in Module 6. Features with big numbers will dominate unless you scale them first. Put a scaler and the SVM together in a Pipeline.
9.7SVMs for regression
SVMs can predict numbers too, using Support Vector Regression (SVR). It flips the idea around. Instead of the widest gap between groups, it fits a "tube" around a line or curve and tries to fit as many points as possible inside the tube.
- Points inside the tube count as "close enough": they cost nothing.
- Only points outside the tube count as errors, and they become the support vectors.
- The width of the tube is set with a setting called
epsilon.
In scikit-learn, use SVR in place of SVC. It supports the same kernels. In practice, for most number-prediction problems on table-shaped data, the gradient boosting models from Module 8 are usually a stronger choice.
9.8Reading handwriting with an SVM in Python
Before deep learning took over, SVMs were famous for recognising handwritten digits. scikit-learn includes a dataset of 1,797 small images of handwritten digits. Each image is an 8 × 8 grid of pixels, so each digit has 64 features: one for how dark each pixel is.
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# 1. 1,797 handwritten digits, each an 8x8 image = 64 pixel features
X, y = load_digits(return_X_y=True)
print("Images:", X.shape[0], "| Features per image:", X.shape[1])
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y)
# 2. Compare a linear SVM with an RBF (curved) SVM
# Pixels run from 0 to 16, so min-max scaling puts them all on 0 to 1
for kernel in ["linear", "rbf"]:
svm = Pipeline([("scale", MinMaxScaler()),
("svm", SVC(kernel=kernel))])
svm.fit(X_train, y_train)
print(f"{kernel:6} kernel accuracy: {svm.score(X_test, y_test):.3f}")
# 3. Tune C and gamma for the RBF kernel with cross-validation
grid = GridSearchCV(
Pipeline([("scale", MinMaxScaler()), ("svm", SVC(kernel="rbf"))]),
param_grid={"svm__C": [0.1, 1, 10, 100],
"svm__gamma": ["scale", 0.01, 0.1, 1]},
cv=5)
grid.fit(X_train, y_train)
print("Best settings:", grid.best_params_)
print("Cross-validation accuracy:", round(grid.best_score_, 3))
# 4. Final test
pred = grid.predict(X_test)
print("Test accuracy:", round(accuracy_score(y_test, pred), 3))
print("Mistakes:", (pred != y_test).sum(), "out of", len(y_test))
print("Support vectors used:", grid.best_estimator_["svm"].n_support_.sum())
Images: 1797 | Features per image: 64
linear kernel accuracy: 0.984
rbf kernel accuracy: 0.991
Best settings: {'svm__C': 10, 'svm__gamma': 'scale'}
Cross-validation accuracy: 0.989
Test accuracy: 0.991
Mistakes: 4 out of 450
Support vectors used: 561What the output tells us
- Even a straight-line SVM does brilliantly (98.4%), because with 64 features there's lots of room to separate the digits.
- The RBF kernel does even better (99.1%), because it can draw curved boundaries around the different ways people write each digit.
- GridSearchCV tried 16 combinations of C and gamma and picked C = 10 with gamma = "scale" (scikit-learn's sensible automatic value).
- Only 4 mistakes in 450 test images. That's a 99.1% test accuracy, very close to the 98.9% cross-validation score, so it isn't a lucky split.
- 561 support vectors out of 1,347 training images. These are the "tricky" digits, like a 1 that looks a bit like a 7, which define the boundaries.
How does an SVM handle 10 classes?
An SVM naturally separates two classes. For more, scikit-learn automatically trains one SVM for every pair of classes (0 vs 1, 0 vs 2, and so on: 45 pairs for 10 digits), and the digit that wins the most "matches" is the prediction. This is called one-vs-one.
9.9Strengths, weaknesses and real-world uses
| Strengths | Weaknesses |
|---|---|
| Very accurate on small and medium datasets | Slow on big datasets: training time grows fast beyond roughly 100,000 rows |
| Excellent with many features, even more features than rows (text, genetics) | Must scale features |
| Flexible: kernels handle complex, curved boundaries | Needs tuning of C and gamma together |
| Resistant to overfitting when C is chosen well | No probabilities by default (set probability=True, which is slower) |
| Memory efficient: only the support vectors are needed to predict | Hard to explain, especially with the RBF kernel |
| Area | Example |
|---|---|
| Text classification | Sorting news articles by topic, spam detection, sentiment analysis of reviews |
| Image recognition | Handwriting recognition, face detection (before deep learning) |
| Healthcare and biology | Classifying diseases from gene data, where there are thousands of features but few patients |
| Finance | Credit risk and fraud detection on medium-sized datasets |
| Manufacturing | Spotting faulty products from sensor readings |
Where do SVMs fit today?
For very large datasets, gradient boosting (Module 8) and neural networks have mostly taken over. But when you have a few thousand rows and lots of features, an SVM is still one of the best tools to try, and it often beats more fashionable methods.
SummaryKey takeaways
- An SVM finds the boundary with the widest margin between classes.
- The support vectors are the points on the edge of the margin; only they decide where the boundary goes.
- A soft margin allows some mistakes. Small C = wide margin, more tolerant; large C = narrow margin, stricter.
- The kernel trick lets an SVM draw curved boundaries by working in extra dimensions without creating them.
- RBF is the usual default kernel; linear is great for text and very many features.
- Gamma controls how curvy an RBF boundary can get: too large overfits.
- Always scale features and tune C and gamma together with cross-validation.
- SVMs shine on small to medium datasets with many features, but are slow on very large data.
Check your understanding
Your machine learning roadmap
- 01Introduction to Machine LearningWhat ML is and how it works
- 02Preparing Data for Machine LearningFeatures, encoding, scaling, train/test split
- 03Linear RegressionPredicting numbers
- 04Logistic RegressionPredicting yes or no
- 05Evaluating ModelsAccuracy, precision, recall, overfitting, cross-validation
- 06K-Nearest NeighboursLearning from similar examples
- 07Decision TreesFlowcharts that learn
- 08Random Forest and Gradient BoostingMany models working together
- 09Support Vector MachinesYou are here
- 10Naive BayesProbability-based classification
- 11Clustering with K-MeansFinding groups without labels
- 12Dimensionality Reduction with PCASimplifying big datasets
- 13Capstone ProjectBuild and present a full ML project
Next module
Naive Bayes