Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🟣 ML + AI  ·  Lesson 33

Support Vector Machine (SVM) in Python

In this lesson: Support Vector Machine explained — margin, kernels — with scikit-learn SVC code and accuracy output. In Hindi & English.

What is a Support Vector Machine?

A Support Vector Machine (SVM) is a classification algorithm that draws the boundary between two classes with the widest possible gap (margin). Think of a road between two villages: SVM builds the widest road that keeps every house on its own side. The houses that touch the road edges are the support vectors – only they decide where the road goes.

TermMeaning
HyperplaneThe decision boundary – a line in 2-D, a plane in 3-D
MarginDistance from the boundary to the nearest points of each class
Support vectorsThe training points closest to the boundary
CPenalty for mistakes: small C = wider, softer margin; large C = fits training data tightly
KernelA trick to draw curved boundaries (RBF, polynomial)
gammaFor RBF: how far one point’s influence reaches; large gamma = wiggly boundary

Step 1: a linear SVM you can see

Twelve students: hours studied and hours slept the night before, and whether they passed. A linear SVM finds the boundary and tells us which students are support vectors.

Python – svm_linear.py
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC

X = np.array([[1, 5], [2, 4], [2, 6], [3, 3], [3, 5], [4, 2],      # failed
              [5, 7], [6, 6], [6, 8], [7, 5], [8, 7], [8, 6]])     # passed
y = np.array([0] * 6 + [1] * 6)

model = SVC(kernel="linear", C=1.0).fit(X, y)
print("support vectors:\n", model.support_vectors_)
print("prediction for 4.5 h study, 6 h sleep:", ["fail", "pass"][model.predict([[4.5, 6]])[0]])

# draw points, boundary and margins
xx, yy = np.meshgrid(np.linspace(0, 9, 200), np.linspace(1, 9, 200))
zz = model.decision_function(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
fig, ax = plt.subplots(figsize=(7, 4.2), dpi=110)
ax.contour(xx, yy, zz, levels=[-1, 0, 1], linestyles=["--", "-", "--"], colors="#334155")
ax.scatter(X[:, 0], X[:, 1], c=np.where(y == 1, "#16a34a", "#dc2626"), s=60, edgecolor="k")
ax.scatter(*model.support_vectors_.T, s=220, facecolors="none", edgecolors="#2563eb", linewidths=2, label="support vectors")
ax.set_xlabel("hours studied"); ax.set_ylabel("hours slept"); ax.legend(loc="lower right")
ax.set_title("Linear SVM: solid = boundary, dashed = margin")
fig.tight_layout(); fig.savefig("svm_margin.png")
support vectors: [[3. 5.] [5. 7.]] prediction for 4.5 h study, 6 h sleep: pass
Linear SVM boundary with dashed margins and circled support vectors

Only the circled points matter. Delete any other point and retrain – the boundary would not move.

Step 2: kernels for curved boundaries

Real data is rarely separable by a straight line. The RBF kernel lets SVM draw curves without you creating new features by hand.

Python – svm_kernels.py
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

X, y = make_moons(n_samples=300, noise=0.2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

fig, axes = plt.subplots(1, 2, figsize=(9, 3.6), dpi=110)
xx, yy = np.meshgrid(np.linspace(-1.5, 2.5, 300), np.linspace(-1, 1.5, 300))
for ax, kernel in zip(axes, ["linear", "rbf"]):
    m = SVC(kernel=kernel, C=1, gamma="scale").fit(X_train, y_train)
    print(f"{kernel:<6} test accuracy: {m.score(X_test, y_test):.2f}")
    zz = m.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    ax.contourf(xx, yy, zz, alpha=0.25, cmap="RdYlGn")
    ax.scatter(X[:, 0], X[:, 1], c=y, cmap="RdYlGn", s=12, edgecolor="k", linewidths=0.3)
    ax.set_title(f"kernel = {kernel}")
fig.tight_layout(); fig.savefig("kernels.png")
linear test accuracy: 0.90 rbf test accuracy: 0.97
Linear vs RBF kernel decision regions on moon-shaped data

Step 3: what C and gamma do

Python – svm_c_gamma.py
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

X, y = make_moons(n_samples=300, noise=0.25, random_state=1)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=1)

print(f"{'C':>6} {'gamma':>6} {'train':>6} {'test':>6} {'#SV':>5}")
for C, gamma in [(0.1, 0.5), (1, 0.5), (1, 5), (100, 50)]:
    m = SVC(kernel="rbf", C=C, gamma=gamma).fit(X_tr, y_tr)
    print(f"{C:>6} {gamma:>6} {m.score(X_tr, y_tr):>6.2f} {m.score(X_te, y_te):>6.2f} {len(m.support_):>5}")
C gamma train test #SV 0.1 0.5 0.87 0.83 127 1 0.5 0.90 0.92 72 1 5 0.94 0.94 71 100 50 1.00 0.92 165

The last row scores almost 100% on training data but worse on test data – it memorised the noise (overfitting). Choose C and gamma with cross-validation, never by looking at training accuracy.

Step 4: a real medical dataset (with scaling)

scikit-learn includes the Wisconsin breast-cancer dataset: 569 tumour samples, 30 measurements each, labelled malignant or benign. SVM measures distances, so features with large numbers (area ≈ 1000) would dominate small ones (smoothness ≈ 0.1). Always scale features first – a Pipeline does it safely.

Python – svm_breast_cancer.py
from sklearn.datasets import load_breast_cancer
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.25, stratify=data.target, random_state=42)

unscaled = SVC().fit(X_train, y_train)
print("without scaling:", round(unscaled.score(X_test, y_test), 3))

pipe = make_pipeline(StandardScaler(), SVC())
grid = GridSearchCV(pipe, {"svc__C": [0.1, 1, 10], "svc__gamma": ["scale", 0.01, 0.1]}, cv=5)
grid.fit(X_train, y_train)
print("best params    :", grid.best_params_)
print("with scaling   :", round(grid.score(X_test, y_test), 3))

pred = grid.predict(X_test)
print(confusion_matrix(y_test, pred))
print(classification_report(y_test, pred, target_names=data.target_names, digits=3))
without scaling: 0.923 best params : {'svc__C': 1, 'svc__gamma': 0.01} with scaling : 0.972 [[50 3] [ 1 89]] precision recall f1-score support malignant 0.980 0.943 0.962 53 benign 0.967 0.989 0.978 90 accuracy 0.972 143 macro avg 0.974 0.966 0.970 143 weighted avg 0.972 0.972 0.972 143

Read the confusion matrix row by row: the first row is actual malignant tumours, the second actual benign. In medicine, missing a malignant tumour (top-right cell) is the costliest mistake, so look at malignant recall, not only accuracy.

When to use SVM

Good forNot ideal for
Small to medium datasets (hundreds to tens of thousands of rows)Millions of rows – training becomes slow
Many features, e.g. text with thousands of wordsWhen you need probabilities or easy explanations
Clear margin between classesVery noisy, overlapping classes without tuning

For a comparison with other classifiers on a real business problem, see the churn project in the Data Science course.

Practice tasks

  1. Change C to 0.01 and 100 in Step 1 and describe how the margin changes.
  2. Try kernel="poly", degree=3 on the moons data and compare test accuracy.
  3. In Step 4, add class_weight="balanced" and compare malignant recall.
  4. Use SVC(probability=True) and print the probability for the first 5 test samples.

Summary

  • SVM finds the boundary with the widest margin; support vectors define it.
  • C controls the trade-off between a wide margin and training mistakes.
  • Kernels (RBF, poly) create curved boundaries; gamma controls how curvy.
  • Always scale features (StandardScaler in a Pipeline) and tune C/gamma with cross-validation.
  • Judge with a confusion matrix and recall, not accuracy alone.

Frequently Asked Questions

Can SVM be used for regression?
Yes. scikit-learn provides SVR (Support Vector Regression), which fits a tube around the data and ignores errors inside the tube.
SVM or Random Forest?
Random Forest needs no scaling, handles mixed data and large datasets well and gives feature importance. SVM often wins on small, high-dimensional, well-scaled data such as text. Try both with cross-validation.
← Back to Python Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicComputer Vision and OpenCV Basics Your progress: 33 / 66 (50%) · Lesson 34 / 66 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free