Singular Value Decomposition là gì và chi tiết cách tính
Giới thiệu về Singular Value Decomposition và các khái niệm liên quan, hướng dẫn chi tiết cách tính Singular Value Decomposition và triển khai bằng Python.
Các thuật toán decomposition (phân rã) cho ma trận là một trong những thuật toán quan trọng nhất trong Machine Learning nói chung và toán ứng dụng nói riêng. Những phép phân rã này không những giúp ta giảm độ phức tạp và chi phí khi thực hiện các phép tính với các ma trận lớn mà còn có những ứng dụng đặc biệt khác.
Ở bài viết này, chúng ta sẽ cùng tìm hiểu về Singular Value Decomposition (Phân tích Suy biến) là gì và chi tiết cách tính.
Khái niệm
Singular Value Decomposition (Phân tích Suy biến) là một phương pháp phân rã một ma trận bất kì thành tích của ba ma trận U, Σ và VT, trong đó U và V là các Orthonormal Matrix (Ma trận Trực chuẩn) và Σ là một Diagonal Matrix (Ma trận Đường chéo).
Nhắc lại
Ma trận
Ma trận là một tập hợp các unit vector (vector đơn vị) được sắp xếp theo hàng hoặc cột. Một ma trận A∈Rm×n có thể được biểu diễn như sau:
Các unit vector đóng vai trò định nghĩa lại một không gian mới bằng tổ hợp tuyến tính của chúng. Ví dụ như không gian 3 chiều cơ bản được định nghĩa bởi 3 unit vector i=(1,0,0), j=(0,1,0) và k=(0,0,1):
R3=[ijk]=100010001
Ý nghĩa hình học của ma trận là nó biểu diễn một phép biến đổi tuyến tính, hay nói cách khác nó giống như một phép biến đổi một không gian này sang một không gian khác mà phép biến đổi này có thể là tổ hợp của các phép rotate (quay), stretch (co giãn), trượt (shear),...
Ma trận A∈Rm×n biểu diễn một phép biến đổi từ không gian Rn sang không gian Rm.
Linearly Dependent và Linearly Independent
Linearly Dependent
Một tập hợp các vector v1,v2,…,vn được gọi là Linearly Dependent (Phụ thuộc Tuyến tính) nếu tồn tại nghiệm là một tập hợp các hệ số c1,c2,…,cn không đồng thời bằng 0 sao cho:
c1v1+c2v2+⋯+cnvn=0(2)
Điều này có nghĩa là một trong các hệ số phải khác 0, giả sử nếu c1=0 thì:
Lúc này, ta có thể thấy v1 đã không tạo ra một chiều không gian mới mà nó chỉ nằm trong không gian của các vector khác. Nói cách khác, v1 đã phụ thuộc tuyến tính vào các vector còn lại.
Linearly Independent
Ngược lại với linear dependence, một tập hợp các vector v1,v2,…,vn được gọi là Linearly Independent (Độc lập Tuyến tính) nếu phương trình (2) chỉ có một nghiệm duy nhất là c1=c2=⋯=cn=0.
Vì lúc này các vector đều độc lập tuyến tính với nhau và phương trình chỉ bằng 0 khi và chỉ khi tất cả các hệ số đều đồng thời bằng 0.
Determinant và Singular Matrix
Determinant
Determinant (Định thức) của một ma trận vuông A∈Rn×n thể hiện độ lệch của không gian sau khi biến đổi bởi ma trận A so với không gian ban đầu.
Với không gian 3 chiều, ta sẽ tính thể tích được bao bởi 3 unit vector i=(1,0,0), j=(0,1,0) và k=(0,0,1), khi đó thể tích sẽ là 1×1×1=1. Điều này nói lên rằng không gian được tạo nên bởi các khối lập phương với thể tích bằng 1.
Khi một ma trận 3×3 biến đổi không gian 3 chiều, nó sẽ biến đổi đơn vị thể tích từ 1 thành det(A). Hay không gian này lớn hơn không gian ban đầu det(A) lần.
Nếu ma trận trên có determinant bằng 0 thì không gian mới sẽ có thể tích bằng 0, có nghĩa là nó có thể là một dấu chấm (OD), một đường thẳng (1D) hay một mặt phẳng (2D).
Tổng quát hơn, nếu:
det(A)>0: Không gian mới sẽ có cùng hướng với không gian ban đầu.
det(A)<0: Không gian mới sẽ có hướng ngược với không gian ban đầu.
det(A)=0: Không gian mới sẽ có chiều thấp hơn không gian ban đầu.
Singular Matrix
Một Singular Matrix (Ma trận Suy biến) là một ma trận vuông A có determinant bằng 0, tức là det(A)=0.
Ý nghĩa hình học của singular matrix là nó suy biến một không gian thành một không gian khác có chiều thấp hơn.
Orthogonal Matrix và Orthonormal Matrix
Orthogonal Matrix
Hai vector u và v được gọi là Orthogonal (Trực giao) khi và chỉ khi chúng vuông góc với nhau, tức là uTv=0.
Một Orthogonal Matrix (Ma Trận Trực giao) là một tập hợp các vector mà mọi cặp unit vector trong đó đều orthogonal với nhau.
Gọi A là một orthogonal matrix khi đó:
ATA=I=AAT⟹A−1=AT(4)
Orthonormal Matrix
Hai vector u và v được gọi là Orthonormal (Trực chuẩn) khi và chỉ khi chúng là orthogonal và đồng thời có độ dài bằng 1, tức là uTv=0 và ∣∣u∣∣=∣∣v∣∣=1.
Một Orthonormal Matrix (Ma trận Trực chuẩn) là một trường hợp đặc biệt của orthogonal matrix khi nó bị ràng buộc bởi điều kiện rằng mọi unit vector trong đó đều có độ dài bằng 1.
Vì các tính chất trên, nếu A là một orthonormal matrix thì nó sẽ thỏa mãn toàn bộ tính chất của một orthogonal matrix và det(A)=1.
Eigenvector và Eigenvalue
Eigenvector
Eigenvector (Vector riêng) của một ma trận vuông A là một vector v khác không thỏa mãn:
Av=λv(5)
Thông thường, sau khi biển đổi không gian bằng một ma trận, các điểm và vector sẽ bị lệch ra khỏi hướng hiện tại (tỉ lệ giữa các chiều trước và sau sẽ bị thay đổi). Trừ khi chúng nằm trên các eigenvector.
Ý nghĩa hình học của eigenvector là tìm ra các vector sao cho sau khi biến đổi một không gian bằng ma trận A, toàn bộ các điểm hoặc vector nằm trên giá của các eigenvector này sẽ chỉ trượt hoặc kéo dãn theo hướng của các eigenvector đó theo hệ số λ.
Hệ quả là eigenvector có thể giúp mô phỏng lại được phép biến đổi của ma trận A thông qua các vector và eigenvalue của nó. Điều này có thể gây nhầm lẫn với unit vector, nên nhớ rằng unit vector chỉ biểu diễn chiều không gian mới, còn eigenvector biểu diễn quá trình biển đổi không gian.
Do đó nó sẽ không thể mô phỏng được phép biến đổi rotate (quay) vì lúc này toàn bộ vector đều bị lệch ra khỏi hướng hiện tại. Tuy nhiên các ma trận xoay vẫn có các eigenvector và eigenvalue tương ứng, và chúng sẽ là các nghiệm phức thay vì nghiệm thực.
Eigenvalue
Eigenvalue (Trị riêng) của một ma trận vuông A là một số λ sao cho tồn tại một vector v khác không thỏa mãn phương trình (5).
Mỗi eigenvalue tương ứng với một eigenvector. Số cặp nghiệm (λ,v) thường sẽ bằng số chiều của ma trận A vì mỗi eigenvector sẽ biểu diễn cách biến đổi một chiều không gian tương ứng.
Nếu λ âm thì đồng nghĩa với việc không gian đã đã bị nén và lật ngược lại. Eigenvalue thể hiện độ dài của eigenvector tương ứng và cho biết không gian đã co giãn như thế nào.
Ý tưởng
Quay lại (5), ta có:
Av⟹Av−λv⟹(A−λI)v=λv=0=0(6)
Lúc này bài toán trở thành tìm ma trận C=A−λI sao cho vector ban đầu v=0 sẽ bị biến đổi về vector không.
Do đó, ma trận C phải là một singular mtrix, suy biến một không gian về một không gian có chiều thấp hơn. Để có được điều này, ta chỉ cần đưa định determinant của C về 0:
Phương trình (7) còn được gọi được gọi là Characteristic Polynomial (Phương trình Đặc trưng) của ma trận A.
Sau khi tìm được các giá trị λ thỏa mãn phương trình (7), ta sẽ có được các eigenvector tương ứng với mỗi giá trị λ bằng cách giải hệ phương trình (6).
Cách tính
Cho trước ma trận linearly independent A∈Rm×n có các unit vector a1,a2,…,an:
defsingular_value_decomposition(A: np.array)->(np.array, np.array, np.array): m, n = A.shape
# Setup V projection_A = A.T @ A
eigen = np.linalg.eig(projection_A) values, vectors = sort_eigen_by_values(eigen) V = vectors
# Setup Σ S = np.zeros((m, n),float)for i inrange(min(m, n)): S[i][i]= values[i]**0.5# Setup U pseudo_inverse_S = pseudo_inverse(S) U = A @ V @ pseudo_inverse_S
return U, S, V
Vì lười code phần tìm eigenvalues và eigenvectors của ma trận nên mình đã sử dụng hàm np.linalg.eig của thư viện numpy để tìm các giá trị này.
Các hàm phụ trợ
defsort_eigen_by_values(eigen): eigenvalues, eigenvectors = eigen
sorted_indices = np.argsort(eigenvalues)[::-1] sorted_eigenvalues = eigenvalues[sorted_indices] sorted_eigenvectors = eigenvectors[:, sorted_indices] sorted_eigen =[sorted_eigenvalues, sorted_eigenvectors]return sorted_eigen
defpseudo_inverse(A: np.array)-> np.array: m, n = A.shape
if m == n: inverse_A = inverse(A)return inverse_A
elif m < n: projection = A @ A.T
inverse_projection = inverse(projection) pseudo_inverse = A.T @ inverse_projection
return pseudo_inverse
else: projection = A.T @ A
inverse_projection = inverse(projection) pseudo_inverse = inverse_projection @ A.T
return pseudo_inverse
definverse(A: np.array)-> np.array:return np.linalg.inv(A)
Kiểm thử
A = np.array([[1,2,3],[3,2,1],[2,1,2],], dtype=float)U, S, V = singular_value_decomposition(A)print("U:", U)print("S:", S)print("V:", V)print("U @ S @ V.T:", U @ S @ V.T)