Chương 2·Bài 2.8

SVM

Khi hai lớp dữ liệu tách được bằng một đường thẳng, thường có nhiều đường thẳng làm được việc đó. SVM (Support Vector Machine) chọn đường nằm xa các điểm gần nhất của cả hai lớp nhất, để một điểm mới lệch một chút vẫn được xếp đúng. Khoảng cách đó gọi là lề (margin). Bài này tính lề bằng tay trên ví dụ nhỏ, rồi dùng kernel để SVM tách được dữ liệu cần đường cong.

Lề lớn nhất

Gán nhãn yi∈{−1,+1}y_i \in \{-1, +1\}. Một siêu phẳng w⊤x+b=0\mathbf{w}^\top\mathbf{x} + b = 0 phân loại đúng mọi điểm khi yi(w⊤xi+b)>0y_i(\mathbf{w}^\top\mathbf{x}_i + b) > 0. Khoảng cách từ xi\mathbf{x}_i đến siêu phẳng là

∣w⊤xi+b∣∥w∥.\frac{\lvert \mathbf{w}^\top\mathbf{x}_i + b\rvert}{\lVert\mathbf{w}\rVert}.

Vì nhân w\mathbf{w} và bb với cùng một số dương không đổi siêu phẳng, ta chuẩn hóa sao cho các điểm gần nhất thỏa yi(w⊤xi+b)=1y_i(\mathbf{w}^\top\mathbf{x}_i + b) = 1. Khi đó độ rộng lề (margin) giữa hai phía là 2/∥w∥2/\lVert\mathbf{w}\rVert; chẳng hạn w=(3,4)\mathbf{w} = (3, 4) có ∥w∥=5\lVert\mathbf{w}\rVert = 5, nên lề rộng 2/5=0.42/5 = 0.4. Cực đại lề tương đương

min⁡w, b 12∥w∥2thỏayi(w⊤xi+b)≥1,  i=1,…,n.\min_{\mathbf{w},\, b}\ \frac{1}{2}\lVert\mathbf{w}\rVert^2 \quad \text{thỏa}\quad y_i\left(\mathbf{w}^\top\mathbf{x}_i + b\right) \ge 1,\ \ i = 1, \dots, n.

Đây là bài toán tối ưu lồi bậc hai: khi dữ liệu tách được thì có nghiệm, và không có cực tiểu địa phương nào để mắc kẹt. Các điểm nằm đúng trên biên lề là vector hỗ trợ (support vectors): chỉ chúng quyết định vị trí vạch, bỏ các điểm khác đi thì vạch không đổi. (Với lề mềm ở mục sau, vector hỗ trợ còn gồm cả các điểm nằm trong lề hoặc bị phân loại sai.)

Chỉ các điểm nằm trên lề (khoanh tròn) quyết định vị trí vạch.f(x) = 0f(x) = ±1 (nét đứt)khoanh: support vectorlề = 2/‖w‖ = 0.62
Chỉ các điểm nằm trên lề (khoanh tròn) quyết định vị trí vạch.

Hỏi nhanh

Sau khi chuẩn hóa, hai biên lề f(x)=±1f(\mathbf x) = \pm 1 cách nhau đúng 1 đơn vị. ∥w∥\lVert\mathbf w\rVert bằng bao nhiêu?

Lề mềm và hinge loss

Dữ liệu thật hiếm khi tách được hoàn toàn. Lề mềm (soft margin) cho phép vi phạm, có trả giá:

min⁡w, b 12∥w∥2+C∑i=1nmax⁡ ⁣(0, 1−yif(xi)),f(x)=w⊤x+b.\min_{\mathbf{w},\, b}\ \frac{1}{2}\lVert\mathbf{w}\rVert^2 + C\sum_{i=1}^{n}\max\!\big(0,\ 1 - y_i f(\mathbf{x}_i)\big), \qquad f(\mathbf{x}) = \mathbf{w}^\top\mathbf{x} + b.

Số hạng thứ hai là hinge loss: bằng 0 nếu điểm nằm đúng phía và ngoài lề, tăng tuyến tính nếu lấn vào lề hoặc sang phía sai. Lại là “phạt + lỗi”, chỉ khác là hệ số đặt ở phía lỗi: CC lớn thì ít chịu vi phạm, lề hẹp, dễ overfit; CC nhỏ thì lề rộng, mô hình đơn giản hơn.

C nhỏ: lề rộng, chịu nhiều vi phạm. C lớn: lề hẹp.C = 0.01 · 72 support vectorC = 100 · 11 support vector
C nhỏ: lề rộng, chịu nhiều vi phạm. C lớn: lề hẹp.

Lấy siêu phẳng w=(3,4)\mathbf{w} = (3, 4), b=−10b = -10 và ba điểm:

  • Điểm (2,1)(2, 1): 3⋅2+4⋅1−10=03\cdot2 + 4\cdot1 - 10 = 0, nằm đúng trên siêu phẳng.
  • Điểm (3,2)(3, 2) nhãn +1+1: f=7f = 7, khoảng cách 7/5=1.47/5 = 1.4, yf=7≥1y f = 7 \ge 1, hinge loss bằng 0.
  • Điểm (2,1.1)(2, 1.1) nhãn +1+1: f=0.4f = 0.4, nằm đúng phía nhưng trong lề, hinge loss =1−0.4=0.6= 1 - 0.4 = 0.6.
Điểm (2, 1.1) đúng phía nhưng nằm trong lề nên vẫn chịu hinge 0.6.1223w = (3, 4), b = −10lề = 2/5 = 0.4(3, 2): ngoài lề, hinge 0(2, 1.1): trong lề, hinge 0.6(2, 1): ngay trên vạch
Điểm (2, 1.1) đúng phía nhưng nằm trong lề nên vẫn chịu hinge 0.6.

So với logistic regression ở bài 2.3, hai mô hình chỉ khác hàm mất mát. Log loss không bao giờ bằng 0, nên mọi điểm đều góp tiếng nói. Hinge loss bằng 0 với điểm “an toàn”, nên chỉ các điểm gần ranh giới mới quan trọng.

Hỏi nhanh

Cho CC tiến dần về 0 trong bài toán lề mềm. Nghiệm có xu hướng thế nào?

Mẹo kernel

Muốn ranh giới cong, cách thô là ánh xạ x\mathbf{x} sang không gian đặc trưng lớn hơn ϕ(x)\phi(\mathbf{x}) rồi chạy SVM tuyến tính ở đó. Điều đặc biệt là dạng đối ngẫu (dual) của bài toán SVM chỉ dùng dữ liệu qua tích vô hướng ϕ(xi)⊤ϕ(xj)\phi(\mathbf{x}_i)^\top\phi(\mathbf{x}_j). Nếu có hàm kk tính thẳng tích đó, gọi là kernel, thì không bao giờ phải tạo ϕ\phi:

k(x,z)=ϕ(x)⊤ϕ(z).k(\mathbf{x}, \mathbf{z}) = \phi(\mathbf{x})^\top \phi(\mathbf{z}).
Thêm tọa độ x² thì một đường thẳng tách được hai lớp.trên trục x: không vạch nào tách đượcxφsau φ(x) = (x, x²): một đường ngang(x, x²)
Thêm tọa độ x² thì một đường thẳng tách được hai lớp.
Nâng mười điểm từ trục x lên (x, x²): hai lớp không tách được bằng một ngưỡng trên trục lại tách được bằng một đường thẳng.

Ví dụ với x,z∈R2\mathbf{x}, \mathbf{z} \in \R^2 và ϕ(x)=(x12, 2 x1x2, x22)\phi(\mathbf{x}) = \left(x_1^2,\ \sqrt{2}\,x_1x_2,\ x_2^2\right):

ϕ(x)⊤ϕ(z)=x12z12+2x1x2z1z2+x22z22=(x⊤z)2.\phi(\mathbf{x})^\top\phi(\mathbf{z}) = x_1^2z_1^2 + 2x_1x_2z_1z_2 + x_2^2z_2^2 = \left(\mathbf{x}^\top\mathbf{z}\right)^2.

Một phép nhân vô hướng rồi bình phương thay cho việc lập và nhân hai vector ba chiều. Với kernel RBF (Gaussian)

k(x,z)=exp⁡ ⁣(−γ ∥x−z∥2),k(\mathbf{x}, \mathbf{z}) = \exp\!\left(-\gamma\,\lVert\mathbf{x} - \mathbf{z}\rVert^2\right),

không gian đặc trưng tương ứng có vô hạn chiều, vậy mà tính kernel chỉ tốn O(d)O(d).

Hỏi nhanh

Với x∈R1000\mathbf x \in \R^{1000}, kernel (x⊤z)2(\mathbf x^\top\mathbf z)^2 ứng với một ϕ\phi có khoảng bao nhiêu chiều? Tính thẳng kernel thì tốn khoảng bao nhiêu phép nhân?

Hàm dự đoán khi đó có dạng f(x)=∑i∈SVαiyi k(xi,x)+bf(\mathbf{x}) = \sum_{i \in SV} \alpha_i y_i\, k(\mathbf{x}_i, \mathbf{x}) + b: một tổng có trọng số theo độ giống giữa điểm mới và các vector hỗ trợ. Nhìn kỹ thì giống kNN có trọng số, nhưng trọng số được học bằng tối ưu. Với RBF và γ=0.1\gamma = 0.1, hai điểm (1,2)(1, 2) và (4,6)(4, 6) có ∥x−z∥2=25\lVert\mathbf{x} - \mathbf{z}\rVert^2 = 25 nên k=e−2.5≈0.082k = e^{-2.5} \approx 0.082. Một điểm test ở rất xa mọi vector hỗ trợ có mọi kk gần 0, nên ff gần bằng bb và dấu của bb quyết định nhãn.

Hai tham số C và γ

Với kernel RBF, γ\gamma quy định “tầm ảnh hưởng” của mỗi vector hỗ trợ. γ\gamma lớn thì mỗi điểm chỉ ảnh hưởng vùng rất nhỏ quanh nó, ranh giới uốn lượn theo từng điểm. γ\gamma nhỏ thì ranh giới mượt gần như tuyến tính. Cùng với CC, đây là hai núm cần dò, luôn trên lưới logarit, ví dụ C∈{0.1,1,10,100}C \in \{0.1, 1, 10, 100\} và γ∈{10−3,…,1}\gamma \in \{10^{-3}, \dots, 1\}.

γ nhỏ: gần thẳng; γ = 1: theo dáng dữ liệu; γ = 100: khoanh từng điểm.γ = 0.1γ = 1γ = 100
γ nhỏ: gần thẳng; γ = 1: theo dáng dữ liệu; γ = 100: khoanh từng điểm.
SVM kernel RBF, C = 1, trên dữ liệu trăng khuyết: tăng γ thì vùng ảnh hưởng của mỗi điểm hẹp lại, ranh giới uốn theo từng điểm (vòng tròn là support vector).

SVM RBF nhạy với khoảng cách; khi các cột khác đơn vị, hãy chuẩn hóa trong Pipeline và kiểm bằng validation.

Hỏi nhanh

SVM với kernel RBF, γ=100\gamma = 100, đúng 100% trên train nhưng cross-validation chỉ được 70%. Ta nên thử gì trước?

Chi phí và giới hạn

  • Huấn luyện SVM có kernel tốn khoảng O(n2)O(n^2) đến O(n3)O(n^3) theo số mẫu. Quá vài chục nghìn mẫu là bắt đầu đuối.
  • Với dữ liệu lớn, thưa, nhiều chiều như văn bản, dùng SVM tuyến tính (LinearSVC): rất nhanh và rất tốt.
  • SVM không cho xác suất. SVC(probability=True) hiệu chỉnh thêm bằng Platt scaling, chậm hơn và không hoàn hảo.

Hỏi nhanh

Cần phân loại 2 triệu bình luận, mỗi bình luận là một vector TF-IDF 100 000 chiều, rất thưa. Nên thử mô hình nào trước?

Đọc score trước khi đọc xác suất

Với w=(3,4)\mathbf w=(3,4), b=−10b=-10, ∥w∥=5\lVert\mathbf w\rVert=5. Mỗi điểm có score f(x)=w⊤x+bf(\mathbf x)=\mathbf w^\top\mathbf x+b; dấu quyết định phía của vạch, còn ∣f∣/5\lvert f\rvert/5 mới là khoảng cách hình học. Score 7 không có nghĩa xác suất 70%, vì score có đơn vị phụ thuộc cách đặt w\mathbf w. Hinge loss lại dùng nhãn có dấu y∈{−1,+1}y\in\{-1,+1\}; nếu lấy nhãn 0/1 nhân vào công thức, mọi mẫu lớp 0 đều có loss 1, là một lỗi âm thầm.

Python
import numpy as np

w_margin = np.array([3., 4.])
b_margin = -10.
points_margin = np.array([[2., 1.], [3., 2.], [2., 1.1]])
labels_signed = np.array([1., 1., 1.])
scores = points_margin @ w_margin + b_margin
distances = np.abs(scores) / np.linalg.norm(w_margin)
hinge = np.maximum(0., 1. - labels_signed * scores)
print("score:", scores.round(3).tolist())
print("khoảng cách:", distances.round(3).tolist())
print("hinge:", hinge.round(3).tolist())

Dòng thứ ba tách hai khái niệm: điểm score 0.4 được phân loại đúng phía nhưng vẫn chịu loss 0.6 vì nằm trong lề; điểm score 7 thì loss 0. Điểm nằm ngay trên vạch có score 0, cần quy ước phá hòa khi biến thành nhãn. Thư viện lo phần ấy, nhưng code tay cần ghi rõ.

Hinge loss bằng 0 khi y·f(x) ≥ 1; log loss thì luôn dương.0123-2-10123y·f(x)trong lềhingelog losshinge = 0
Hinge loss bằng 0 khi y·f(x) ≥ 1; log loss thì luôn dương.

Hỏi nhanh

Một mẫu có y=−1y = -1 và f(x)=−0.2f(\mathbf x) = -0.2. Hinge loss bằng bao nhiêu?

Kiểm mẹo kernel bằng số

Ta kiểm ví dụ polynomial trong bài bằng cả hai cách: dựng đặc trưng ba chiều rồi tính tích vô hướng, và bình phương tích vô hướng hai chiều.

Python
x_kernel = np.array([1., 2.])
z_kernel = np.array([3., 4.])
def phi2(v):
    a, b = v
    return np.array([a * a, np.sqrt(2.) * a * b, b * b])

print(round(float(phi2(x_kernel) @ phi2(z_kernel)), 6))
print(float((x_kernel @ z_kernel) ** 2))
assert np.allclose(phi2(x_kernel) @ phi2(z_kernel), (x_kernel @ z_kernel) ** 2)

Hai dòng cùng bằng 121. Ta tính được kernel mà không dựng từng tọa độ của không gian lớn hơn. Cái giá chuyển sang số mẫu: kernel SVM làm việc với quan hệ giữa các cặp mẫu, nên thời gian và bộ nhớ tăng nhanh theo nn. Hãy đo trên một phần nhỏ dữ liệu trước khi fit cả bộ.

Dùng thư viện

Python
from sklearn.datasets import make_moons
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

X, y = make_moons(n_samples=500, noise=0.25, random_state=0)
model = make_pipeline(StandardScaler(), SVC(kernel="rbf"))
grid = GridSearchCV(model, {"svc__C": [0.1, 1, 10, 100], "svc__gamma": [0.01, 0.1, 1, 10]}, cv=5)
grid.fit(X, y)
print(grid.best_params_, round(grid.best_score_, 3))
print("số vector hỗ trợ:", grid.best_estimator_[-1].n_support_.sum(), "trên", len(X))

Hỏi nhanh

Mô hình tốt nhất dùng 221 trên 500 điểm làm vector hỗ trợ. Con số này nói lên điều gì?

Khi đi thi

  • Chuẩn hóa các cột trong từng fold trước SVM; dò C và gamma trên thang log.
  • Văn bản thì thử TF-IDF cộng LinearSVC làm baseline.
  • Đề cần xác suất thì dùng logistic regression, hoặc hiệu chỉnh SVM trên validation.

Tóm tắt

  • SVM chọn siêu phẳng có lề lớn nhất; chỉ các vector hỗ trợ quyết định ranh giới.
  • Lề mềm cân bằng giữa lề rộng và vi phạm bằng CC; hàm mất mát là hinge loss.
  • Kernel cho phép ranh giới cong mà không cần tạo đặc trưng; RBF điều khiển bằng γ\gamma.
  • Chuẩn hóa đặc trưng; dò CC, γ\gamma trên thang log; hạn chế với dữ liệu rất lớn.

Kiểm tra cuối bài

Mười câu kiểm cả cách hiểu, phép tính và quy trình. Câu sai chỉ ra phần cần đọc lại; hãy làm trước khi mở lời giải.

Câu 1

w=(6,8)\mathbf w = (6, 8), b=−10b = -10. Khoảng cách từ điểm x=(1,1)\mathbf x = (1, 1) tới siêu phẳng w⊤x+b=0\mathbf w^\top\mathbf x + b = 0 bằng bao nhiêu?

Câu 2

Dữ liệu có bốn điểm: (0,1)(0, 1) và (1,1)(1, 1) mang nhãn −1-1, còn (3,3)(3, 3) và (4,3.5)(4, 3.5) mang nhãn +1+1. SVM lề cứng chỉ có (1,1)(1, 1) và (3,3)(3, 3) là vector hỗ trợ. Lề rộng bao nhiêu?

Câu 3

Một bài phân loại có vài điểm bị gán nhãn nhầm, nằm sâu trong vùng của lớp kia. SVM lề cứng và SVM lề mềm xử lý thế nào?

Phỏng theoNOAI 2026 Singapore · Vòng sơ loại · Câu 171

Câu 4

Một mẫu có y=−1y = -1 và f(x)=2f(\mathbf x) = 2. Hinge loss bằng bao nhiêu?

Câu 5

Một mẫu có y=1y = 1 và f(x)=0.4f(\mathbf x) = 0.4. Nhân cả w\mathbf w và bb với 2 thì siêu phẳng không đổi. Hinge loss của mẫu thay đổi thế nào?

Câu 6

Trong mục tiêu 12∥w∥2+C∑ihingei\tfrac12\lVert\mathbf w\rVert^2 + C\sum_i\text{hinge}_i, CC lớn có nghĩa là gì?

Câu 7

Nhà máy có 10 000 bản ghi máy chạy bình thường, và gần như không có bản ghi máy hỏng. Vì sao one-class SVM hợp với việc phát hiện bất thường ở đây?

Đề thiNOAI 2026 Singapore · Vòng sơ loại · Câu 170

Câu 8

SVM cho decision score bằng 2.0 ở một mẫu. Nếu đề yêu cầu xác suất để tính log loss, ta nên làm gì?

Câu 9

Tự viết hinge loss bằng np.maximum(0, 1 - y*f), trong khi y nhận giá trị 0 hoặc 1. Ở các mẫu lớp 0, chuyện gì xảy ra?

Câu 10

Kernel k(x,z)=(x⊤z+1)2k(\mathbf x, \mathbf z) = (\mathbf x^\top\mathbf z + 1)^2 với x∈R2\mathbf x \in \R^2 ứng với một ánh xạ ϕ\phi sang không gian bao nhiêu chiều?

Phỏng theoNOAI 2026 Singapore · Vòng sơ loại · Câu 161

Đọc thêm

  • Cortes, Vapnik (1995) — Support-Vector Networks, Machine Learning 20. Bài gốc của lề mềm.
  • James, Witten, Hastie, Tibshirani — An Introduction to Statistical Learning, chương 9. Lề, kernel và so sánh với logistic regression.
  • Géron — Hands-On Machine Learning, chương 5. SVM tuyến tính, kernel và mẹo chọn CC, γ\gamma bằng scikit-learn.

  • scikit-learn — Support Vector Machines. Kernel, scaling, complexity, support vectors và probability calibration.

  • ISLP — Support vector machines lab. Các thực nghiệm về C, gamma và validation.