Mục lục
- Mục tiêu bài học
- Vector là gì — góc nhìn trực quan
- Notation chính thức
- Vector trong AI / ML xuất hiện ở đâu
- Phép cộng vector
- Phép trừ vector
- Phép nhân vô hướng (scalar multiplication)
- Độ lớn của vector — norm
- Khoảng cách giữa 2 vector
- Dot product — tích vô hướng
- Cosine similarity — preview semantic search
- Code Python với list thuần
- Bài tập
- Tóm tắt
Mục tiêu bài học
Sau bài học, bạn sẽ:
- Mô tả vector theo 2 góc nhìn: danh sách số và mũi tên có hướng và độ lớn.
- Đọc được notation \( \vec{v} = (v_1, v_2, \ldots, v_n) \) và biết khi nào viết in đậm \( \mathbf{v} \).
- Thực hiện phép cộng, trừ, nhân vô hướng vector cả về số học lẫn hình học.
- Tính được norm (độ lớn) và khoảng cách giữa 2 vector.
- Hiểu intuition của dot product và cosine similarity — 2 phép toán xuất hiện liên tục trong AI.
- Viết được code Python tính norm, cộng vector, tính cosine similarity bằng list thuần (chưa NumPy).
Đây là bài mở đầu Module 3. Các phép toán dưới đây sẽ tái xuất hiện trong gần như mọi model ML / DL về sau — feature vector trong KNN, gradient trong gradient descent, embedding trong LLM, weight vector trong neural network.
Vector là gì — góc nhìn trực quan
Khi mới gặp, nhiều người nghĩ vector chỉ là "danh sách số" — đúng, nhưng chưa đủ. Trong toán và trong AI, vector mang theo 2 tính chất quan trọng:
- Hướng (direction) — chỉ về phía nào trong không gian.
- Độ lớn (magnitude) — đi xa bao nhiêu theo hướng đó.
Hình ảnh dễ hình dung nhất là mũi tên trong mặt phẳng. Một vector 2 chiều \( \vec{v} = (3, 2) \) là mũi tên xuất phát từ gốc toạ độ \( (0, 0) \) và kết thúc ở điểm \( (3, 2) \): đi 3 đơn vị sang phải, rồi 2 đơn vị lên trên.
Hai vector "bằng nhau" khi chúng có cùng độ lớn và cùng hướng — không quan trọng vẽ từ đâu. Quy ước phổ biến: luôn vẽ từ gốc toạ độ để dễ so sánh.
Mở rộng sang 3 chiều: \( \vec{v} = (3, 2, 5) \) là mũi tên trong không gian. Vượt qua 3 chiều, ta không vẽ được nữa, nhưng đại số vẫn hoạt động bình thường. Embedding của một câu trong LLM thường có 768, 1024, hoặc 3072 chiều — không có hình minh hoạ, chỉ có công thức.
Notation chính thức
Một vector \( n \) chiều ghi dưới dạng:
\[ \vec{v} = (v_1, v_2, \ldots, v_n) \]
Trong đó:
- \( v_i \) là thành phần (component) thứ \( i \). Mỗi \( v_i \in \mathbb{R} \) (số thực).
- \( n \) là số chiều (dimensionality). \( \vec{v} \in \mathbb{R}^n \).
Các cách viết phổ biến trong sách và paper:
- \( \vec{v} \) — mũi tên trên đầu, hay gặp trong sách toán phổ thông.
- \( \mathbf{v} \) — chữ in đậm, hay gặp trong paper ML / DL.
- Dạng cột (column vector), mặc định trong đại số tuyến tính: \[ \mathbf{v} = \begin{pmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{pmatrix} \]
- Dạng hàng (row vector): \( \mathbf{v}^\top = (v_1, v_2, \ldots, v_n) \). Ký hiệu \( ^\top \) là transpose — sẽ học chi tiết ở Bài 19.
Trong bài này, để gọn, ta viết \( \vec{v} = (v_1, \ldots, v_n) \) như dạng hàng. Khi nào cần phân biệt với ma trận (Bài 19), ta sẽ dùng dạng cột.
Vector trong AI / ML xuất hiện ở đâu
Ba ngữ cảnh dễ gặp nhất:
Feature vector — một sample là một vector
Một căn nhà có 4 đặc trưng: diện tích, số phòng ngủ, số tầng, năm xây. Ta biểu diễn nó là vector 4 chiều:
\[ \mathbf{x} = (120, \; 3, \; 2, \; 2018) \]
Dataset 1000 căn nhà → 1000 vector 4 chiều. Model dự đoán giá nhà nhận vào các vector này.
Embedding — text trở thành vector
Các model như text-embedding-3-small (OpenAI) hay voyage-3 (Voyage AI) ánh xạ một đoạn text thành vector cố định, thường 384 / 768 / 1024 / 3072 chiều. Vector này gọi là embedding. Hai câu có nghĩa gần nhau → 2 vector gần nhau trong không gian. Đây là cơ chế cốt lõi của RAG và semantic search (Bài cuối Module RAG sẽ đi sâu).
Weight vector — mỗi neuron có một vector
Một neuron đơn giản nhận đầu vào \( \mathbf{x} \in \mathbb{R}^n \) và có vector trọng số (weight) \( \mathbf{w} \in \mathbb{R}^n \). Đầu ra là:
\[ y = \mathbf{w} \cdot \mathbf{x} + b = \sum_{i=1}^{n} w_i x_i + b \]
Phép \( \mathbf{w} \cdot \mathbf{x} \) chính là dot product (mục 10). Quá trình "training" của neural network thực chất là tìm các giá trị \( w_i \) phù hợp.
Phép cộng vector
Cộng 2 vector cùng số chiều: cộng từng thành phần tương ứng.
\[ \vec{u} + \vec{v} = (u_1 + v_1, \; u_2 + v_2, \; \ldots, \; u_n + v_n) \]
Ví dụ với \( \vec{u} = (1, 2) \) và \( \vec{v} = (3, 1) \):
\[ \vec{u} + \vec{v} = (1 + 3, \; 2 + 1) = (4, 3) \]
Hình học (quy tắc nối đuôi): đặt gốc của \( \vec{v} \) tại điểm cuối của \( \vec{u} \). Vector tổng \( \vec{u} + \vec{v} \) là mũi tên đi thẳng từ gốc của \( \vec{u} \) tới ngọn của \( \vec{v} \).
Hai tính chất hay dùng:
- Giao hoán: \( \vec{u} + \vec{v} = \vec{v} + \vec{u} \).
- Kết hợp: \( (\vec{u} + \vec{v}) + \vec{w} = \vec{u} + (\vec{v} + \vec{w}) \).
Lưu ý: chỉ cộng được khi 2 vector cùng số chiều. Cộng vector 3 chiều với vector 4 chiều không có định nghĩa.
Phép trừ vector
Tương tự cộng, trừ là trừ từng thành phần:
\[ \vec{u} - \vec{v} = (u_1 - v_1, \; u_2 - v_2, \; \ldots, \; u_n - v_n) \]
Ý nghĩa hình học: \( \vec{u} - \vec{v} \) là mũi tên đi từ ngọn của \( \vec{v} \) tới ngọn của \( \vec{u} \) (giả sử cả hai cùng xuất phát từ gốc). Nói cách khác, đó là "khoảng cách có hướng" để đi từ điểm \( \vec{v} \) đến điểm \( \vec{u} \).
Ví dụ với \( \vec{u} = (4, 3) \) và \( \vec{v} = (1, 2) \):
\[ \vec{u} - \vec{v} = (3, 1) \]
Vector hiệu chỉ về hướng từ điểm \( (1, 2) \) đến điểm \( (4, 3) \). Đây là intuition đứng sau công thức khoảng cách ở mục 9.
Phép nhân vô hướng (scalar multiplication)
Nhân một số (scalar) \( c \in \mathbb{R} \) với một vector: nhân số đó với từng thành phần.
\[ c \cdot \vec{v} = (c \, v_1, \; c \, v_2, \; \ldots, \; c \, v_n) \]
Ví dụ với \( \vec{v} = (2, 3) \):
- \( 2 \cdot \vec{v} = (4, 6) \) — dài gấp đôi, cùng hướng.
- \( 0.5 \cdot \vec{v} = (1, 1.5) \) — ngắn lại một nửa, cùng hướng.
- \( -1 \cdot \vec{v} = (-2, -3) \) — cùng độ dài nhưng ngược hướng.
- \( 0 \cdot \vec{v} = (0, 0) \) — vector không.
Trực quan: scalar multiplication chỉ scale (kéo dài / co lại / lật chiều) chứ không thay đổi đường thẳng mà mũi tên nằm trên. Đây cũng là phép dùng để chuẩn hoá vector ở mục 8.
Trong training neural network, mỗi bước gradient descent có dạng \( \mathbf{w} \leftarrow \mathbf{w} - \eta \cdot \vec{g} \) với \( \eta \) là learning rate (scalar) và \( \vec{g} \) là gradient (vector) — chính là scalar multiplication. Bài 27 sẽ đi sâu.
Độ lớn của vector — norm
Độ lớn (magnitude) hay norm của vector là độ dài của mũi tên. Norm phổ biến nhất là L2 norm (Euclidean norm), suy ra từ định lý Pythagoras:
\[ \|\vec{v}\|_2 = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2} = \sqrt{\sum_{i=1}^{n} v_i^2} \]
Khi viết \( \|\vec{v}\| \) không kèm chỉ số, mặc định là L2.
Ví dụ với \( \vec{v} = (3, 4) \):
\[ \|\vec{v}\| = \sqrt{3^2 + 4^2} = \sqrt{25} = 5 \]
Hai họ norm khác hay gặp:
- L1 norm (Manhattan): \( \|\vec{v}\|_1 = |v_1| + |v_2| + \cdots + |v_n| \). Dùng trong regularization Lasso, đo "khoảng cách taxi" trên lưới phố.
- \( L_\infty \) norm (max norm): \( \|\vec{v}\|_\infty = \max_i |v_i| \). Lấy thành phần tuyệt đối lớn nhất.
Chuẩn hoá vector (normalize): chia một vector cho norm của nó để được vector cùng hướng có độ dài 1, gọi là unit vector:
\[ \hat{v} = \frac{\vec{v}}{\|\vec{v}\|} \]
Embedding trả về từ nhiều model (vd text-embedding-3-small) đã được normalize sẵn để \( \|\vec{v}\| = 1 \) — giúp tính cosine similarity rẻ hơn (xem mục 11).
Khoảng cách giữa 2 vector
Kết hợp phép trừ (mục 6) và norm (mục 8): khoảng cách Euclid giữa 2 vector cùng số chiều là norm của hiệu:
\[ d(\vec{u}, \vec{v}) = \|\vec{u} - \vec{v}\| = \sqrt{\sum_{i=1}^{n} (u_i - v_i)^2} \]
Ví dụ với \( \vec{u} = (1, 2) \) và \( \vec{v} = (4, 6) \):
\[ d(\vec{u}, \vec{v}) = \sqrt{(1-4)^2 + (2-6)^2} = \sqrt{9 + 16} = 5 \]
Khoảng cách Euclid xuất hiện ở những thuật toán bạn sẽ gặp ngay từ Module 2 series ML:
- K-Nearest Neighbors (KNN): phân loại một điểm bằng cách tìm \( k \) điểm gần nhất theo \( d(\vec{u}, \vec{v}) \).
- K-Means clustering: mỗi điểm thuộc về cluster có centroid gần nhất.
- Loss MSE (Mean Squared Error): \( \frac{1}{N} \sum_i (y_i - \hat{y}_i)^2 \) — bình phương của khoảng cách Euclid trung bình giữa vector dự đoán và vector ground truth.
Với embedding cao chiều, khoảng cách Euclid vẫn dùng được, nhưng cosine similarity (mục 11) thường phù hợp hơn vì không nhạy với độ dài, chỉ quan tâm hướng.
Dot product — tích vô hướng
Dot product (tích vô hướng, inner product) lấy 2 vector cùng số chiều và trả về một số (scalar):
\[ \vec{u} \cdot \vec{v} = \sum_{i=1}^{n} u_i v_i = u_1 v_1 + u_2 v_2 + \cdots + u_n v_n \]
Ví dụ với \( \vec{u} = (1, 2, 3) \) và \( \vec{v} = (4, -5, 6) \):
\[ \vec{u} \cdot \vec{v} = 1 \cdot 4 + 2 \cdot (-5) + 3 \cdot 6 = 4 - 10 + 18 = 12 \]
Có một công thức hình học tương đương:
\[ \vec{u} \cdot \vec{v} = \|\vec{u}\| \cdot \|\vec{v}\| \cdot \cos \theta \]
với \( \theta \) là góc giữa 2 vector. Một số trường hợp đặc biệt đáng nhớ:
- \( \vec{u} \cdot \vec{v} > 0 \): góc nhọn (\( \theta < 90^\circ \)) — hướng "tương đồng".
- \( \vec{u} \cdot \vec{v} = 0 \): vuông góc (\( \theta = 90^\circ \)) — hai vector trực giao (orthogonal).
- \( \vec{u} \cdot \vec{v} < 0 \): góc tù (\( \theta > 90^\circ \)) — hướng "ngược nhau".
Dot product là viên gạch nền cho nhân ma trận ở Bài 19: mỗi phần tử của tích \( AB \) là dot product giữa 1 hàng của \( A \) và 1 cột của \( B \). Khi mở rộng lên ma trận, ta có thể tính song song hàng nghìn dot product cùng lúc trên GPU — chính là lý do ma trận quan trọng cho neural network.
Cosine similarity — preview semantic search
Từ công thức hình học của dot product, ta rút \( \cos \theta \) ra để đo "độ tương đồng về hướng" giữa 2 vector, gọi là cosine similarity:
\[ \cos \theta = \frac{\vec{u} \cdot \vec{v}}{\|\vec{u}\| \, \|\vec{v}\|} \]
Giá trị nằm trong \( [-1, 1] \):
- \( \cos \theta = 1 \): cùng hướng — rất giống nhau về nghĩa.
- \( \cos \theta = 0 \): trực giao — không liên quan.
- \( \cos \theta = -1 \): ngược hướng — đối lập (hiếm khi gặp với embedding của text vì các thành phần thường không âm sau xử lý).
Cosine similarity là metric mặc định trong semantic search và RAG: tìm các đoạn text mà embedding của chúng có cosine similarity cao nhất với embedding của câu truy vấn. Vector database (pgvector, Qdrant, Pinecone, Weaviate) đều có operator chuyên cho phép so sánh này.
Khi vector đã được normalize (\( \|\vec{u}\| = \|\vec{v}\| = 1 \)), cosine similarity rút gọn về:
\[ \cos \theta = \vec{u} \cdot \vec{v} \]
— chỉ cần một phép dot product. Đây là lý do nhiều provider trả về embedding đã normalize sẵn.
Code Python với list thuần
Để tập trung vào ý nghĩa, ta dùng list Python thuần và module math. Module 4 sẽ chuyển sang NumPy — nhanh và gọn hơn nhiều.
import math
def vec_add(u, v):
if len(u) != len(v):
raise ValueError("Hai vector phải cùng số chiều")
return [u_i + v_i for u_i, v_i in zip(u, v)]
def vec_sub(u, v):
if len(u) != len(v):
raise ValueError("Hai vector phải cùng số chiều")
return [u_i - v_i for u_i, v_i in zip(u, v)]
def scalar_mul(c, v):
return [c * v_i for v_i in v]
def norm(v):
return math.sqrt(sum(v_i * v_i for v_i in v))
def distance(u, v):
return norm(vec_sub(u, v))
def dot(u, v):
if len(u) != len(v):
raise ValueError("Hai vector phải cùng số chiều")
return sum(u_i * v_i for u_i, v_i in zip(u, v))
def cosine_similarity(u, v):
denom = norm(u) * norm(v)
if denom == 0:
raise ValueError("Không định nghĩa cosine cho vector không")
return dot(u, v) / denom
u = [1, 2, 3]
v = [4, -5, 6]
print(vec_add(u, v)) # [5, -3, 9]
print(scalar_mul(2, u)) # [2, 4, 6]
print(norm([3, 4])) # 5.0
print(distance([1, 2], [4, 6])) # 5.0
print(dot(u, v)) # 12
print(cosine_similarity(u, v)) # ~0.2826
Một số lưu ý đọc code:
zip(u, v)ghép từng cặp \( (u_i, v_i) \). Ngắn gọn hơn vòngforqua chỉ số.normdùngsum(v_i * v_i ...)thay vìv_i ** 2— kết quả y như nhau nhưng dạng nhân thường nhanh hơn cho float.- Kiểm tra số chiều khớp nhau giúp báo lỗi sớm. Khi sang NumPy, broadcasting có quy tắc riêng (Bài 33).
- Cosine similarity của
uvàvở đây là \( 12 / (\sqrt{14} \cdot \sqrt{77}) \approx 0.2826 \) — góc khoảng \( 73.6^\circ \).
Bài tập
- Tính bằng tay (không code) norm của vector \( \vec{a} = (2, 3) \). Trả lời ở dạng căn thức và số thập phân làm tròn 2 chữ số.
- Cho \( \vec{u} = (1, -2, 4) \) và \( \vec{v} = (3, 0, -1) \). Tính \( \vec{u} + \vec{v} \), \( \vec{u} - \vec{v} \), và \( 2 \vec{u} - 3 \vec{v} \).
- Viết hàm
cosine_similarity(u, v)ở mục 12 lại từ đầu mà không nhìn đáp án. Kiểm thử với \( \vec{u} = (1, 0) \), \( \vec{v} = (0, 1) \) — kết quả phải là 0 (vuông góc). - Cho 3 embedding giả định 4 chiều:
q = [0.1, 0.3, -0.2, 0.5](query),d1 = [0.2, 0.4, -0.1, 0.6],d2 = [-0.5, 0.1, 0.3, 0.0]. Tính cosine similarity giữaqvà mỗi document. Document nào gần nghĩa hơn với query? - Chứng minh bằng tay: nếu \( \hat{u} = \vec{u} / \|\vec{u}\| \) và \( \hat{v} = \vec{v} / \|\vec{v}\| \) thì \( \hat{u} \cdot \hat{v} = \cos \theta \). (Gợi ý: thay vào công thức cosine similarity ở mục 11.)
Đáp án ngắn
- \( \|\vec{a}\| = \sqrt{2^2 + 3^2} = \sqrt{13} \approx 3.61 \).
- \( \vec{u} + \vec{v} = (4, -2, 3) \); \( \vec{u} - \vec{v} = (-2, -2, 5) \); \( 2\vec{u} - 3\vec{v} = (2 - 9, -4 - 0, 8 + 3) = (-7, -4, 11) \).
- Với \( \vec{u} = (1, 0), \vec{v} = (0, 1) \): dot product = 0, mỗi norm = 1 → cosine = 0.
- cos(q, d1) \( \approx \) 0.985 (rất gần nhau); cos(q, d2) \( \approx \) -0.236 (gần như ngược hướng).
d1sát nghĩa với query hơn. - \( \hat{u} \cdot \hat{v} = \frac{\vec{u}}{\|\vec{u}\|} \cdot \frac{\vec{v}}{\|\vec{v}\|} = \frac{\vec{u} \cdot \vec{v}}{\|\vec{u}\| \|\vec{v}\|} = \cos \theta \).
Tóm tắt
- Vector \( \vec{v} = (v_1, \ldots, v_n) \in \mathbb{R}^n \) vừa là danh sách số, vừa là đại lượng có hướng và độ lớn.
- Vector xuất hiện ở 3 chỗ chính trong AI: feature vector của 1 sample, embedding của text / ảnh, weight vector của neuron.
- Cộng / trừ vector: element-wise; hình học là quy tắc nối đuôi và "mũi tên giữa 2 điểm".
- Scalar multiplication \( c \vec{v} \): scale độ dài, đổi chiều nếu \( c < 0 \).
- Norm L2: \( \|\vec{v}\| = \sqrt{\sum v_i^2} \). Có thêm L1 và \( L_\infty \) cho các bài toán khác.
- Khoảng cách Euclid \( d(\vec{u}, \vec{v}) = \|\vec{u} - \vec{v}\| \) — nền cho KNN, K-Means, MSE.
- Dot product \( \vec{u} \cdot \vec{v} = \sum u_i v_i = \|\vec{u}\|\|\vec{v}\|\cos\theta \) — sẽ generalize lên ma trận ở Bài 19.
- Cosine similarity \( \cos \theta = \frac{\vec{u} \cdot \vec{v}}{\|\vec{u}\|\|\vec{v}\|} \) — metric chuẩn cho semantic search và RAG.
- Python Docs - math module (sqrt, fsum)
- NumPy Docs - numpy.linalg.norm (L1, L2, L∞)
- NumPy Docs - numpy.dot
- OpenAI Docs - Embeddings (text-embedding-3-small / large)
- pgvector - Postgres extension cho vector similarity (cosine, L2, inner product)
- Wikipedia - Euclidean vector
- Wikipedia - Dot product
- Wikipedia - Cosine similarity
- Wikipedia - Norm (mathematics)
