I. Giới thiệu
- Trong Machine Learning, chúng ta thường xử lý dữ liệu được biểu diễn dưới dạng ma trận, thường các ma trận này có kích thước lớn. Rất nhiều các bài toán học máy được giải quyết bằng cách sử dụng các phương pháp của Đại số tuyến tính. Trong các bài này mình sẽ trình bày về các phương pháp phân tích ma trận (hay Phân rã ma trận) (Matrix Decomposition).
- Việc phân tích một ma trận là đưa ma trận đó về tích của 2 hay nhiều ma trận đặc biệt khác, thường là ma trận đường chéo và ma trận tam giác. Việc phân tích này nhằm mục đích dễ dàng tính định thức, tìm ma trận nghịch đảo, giải hệ phương trình tuyến tính, giảm chiều dữ liệu,… Matrix Decomposition cũng được ứng dụng trong bài toán về Hệ thống khuyến nghị (Recommendation System).
- Một số phương pháp phân tích ma trận phổ biến như LU, QR, Cholesky, Eigen Decomposition (Chéo hóa ma trận), SVD,… Trong đó, SVD được sử dụng nhiều trong các thuật toán Học máy và Thị giác máy tính. Trong phần này mình sẽ trình bày một phương pháp đơn giản nhất là phân tích LU. (LU là viết tắt của Lower Triangular Matrix và Upper Triangular Matrix).
II. LU Decomposition
1. Định nghĩa
- Cho là một ma trận vuông, phân tích LU của là cách viết thành tích của 2 ma trận có dạng trong đó là các ma trận tam giác dưới và tam giác trên có cùng kích thước với . Người ta chứng minh được rằng mọi ma trận cấp thỏa mãn phân tích khi và chỉ khi các định thức con chính khác , phân tích sẽ duy nhất nếu thêm điều kiện các phần tử trên đường chéo chính của ma trận (hoặc ) đều bằng .
- Ví dụ với ma trận vuông
- Vể mặt toán học, tìm phân tích này ta làm như sau:
Bước 1: Biến đổi sơ cấp ma trận thành ma trận tam giác trên . Bản chất của quá trình này là nhân với dãy ma trận không suy biến dạng tam giác dưới, giả sử dãy đó là , ta có
Bước 2: Do nên tìm được bằng công thức
Ví dụ: Phân tích ma trận
2. Thuật toán tìm LU Decomposition
- Ta có thể biểu diễn như sau:
(Kí hiệu biểu diễn ma trận con lấy từ ma trận với hàng từ đến và các cột từ đến )
Suy ra
Từ đây ta có
Đặt ta có
là phân tích của . ( được gọi là Schur complement)
Thuật toán tìm phân tích được mô tả bởi:
Ví dụ: Tìm phân tích của
Ta có
Áp dụng các công thức ở trên ta được
Thuật toán ở trên có thể thể hiện mã giả (peusedocode) như sau
- Code Python
import numpy as np
def LU_Decomposition(A):
n=A.shape[0]
U=A.copy()
L=np.zeros((n,n))
for i in range(n):
L[i,i]=1
for k in range(n-1):
for j in range(k+1, n):
L[j,k]=U[j,k]/U[k,k]
U[j, k:n]=U[j,k:n]-L[j,k]*U[k, k:n]
return L,U
- Kết quả chạy thử:
A=np.array([[8.,2.,9.],[4.,9.,4.],[6.,7.,9.]]) print(A) L,U=LU_Decomposition(A) print("L=",L) print("U=",U)
L= [[1. 0. 0. ] [0.5 1. 0. ] [0.75 0.6875 1. ]] U= [[ 8. 2. 9. ] [ 0. 8. -0.5 ] [ 0. 0. 2.59375]]
Kết quả cho ra đúng với ta làm ở trên.
- Một cài đặt khác của thuật toán trên
import numpy as np def LU_Decomposition(A): n= A.shape[0] L=np.zeros((n,n)) U=np.zeros((n,n)) M=A.copy() for i in range(n): U[i,i:]=M[i,i:] L[i:,i]=M[i:,i]/U[i,i] M[i+1:, i+1:]-=np.outer(L[i+1:,i], U[i, i+1:]) return L,U
Kết quả cho ra hoàn toàn tương tự.
III. LU Decomposition with pivoting
- Tổng quát hơn với ma trận vuông khả nghịch ta có phân tích , đó là phân tích có dạng trong đó là các ma trận tam giác như trên, là ma trận nhận được trong biến đổi sơ cấp hàng, hay được gọi là ma trận hoán vị (permutation matrix).
- Ma trận chỉ có các phần tử . Ví dụ với ma trận
- Ta có thể sử dụng hàm trong thư viện
import numpy as np
from scipy.linalg import lu
A=np.array([[0,5,5],[2,3,0],[6,9,8]])
P,L,U=lu(A)
print("P=",P.T) #Trong hàm lu cho kết quả của A=PLU
print("L=", L)
print("U=", U)
print(P.T @ A)
print(L @ U)
Kết quả chạy
P= [[0. 0. 1.]
[1. 0. 0.]
[0. 1. 0.]]
L= [[1. 0. 0. ]
[0. 1. 0. ]
[0.33333333 0. 1. ]]
U= [[ 6. 9. 8. ]
[ 0. 5. 5. ]
[ 0. 0. -2.66666667]]
[[6. 9. 8.]
[0. 5. 5.]
[2. 3. 0.]]
[[6. 9. 8.]
[0. 5. 5.]
[2. 3. 0.]]
III. Ứng dụng LU Decomposition
1. Giải hệ phương trình tuyến tính
Cho hệ phương phương trình tuyến tính biểu diễn dưới dạng ma trận trong đó .
Cài đặt bằng Python, sử dụng hàm LU_Decomposition() đã viết ở trên.
def solve_system_equation(A,b):
L,U=LU_Decomposition(A)
x=np.linalg.inv(U).dot((np.linalg.inv(L).dot(b)))
return x
A=np.array([[3,2,-1],[2,-2,4],[-1, 0.5, -1]], dtype=np.float32)
b=np.array([1,-2,0])
x=solve_system_equation(A,b)
print("x=",x)
Kết quả chạy
Hệ có nghiệm
x= [ 1.00000057 -2.00000129 -2.00000103]
2. Tính định thức
Với ma trận vuông khả nghịch ta có
Mà là các ma trận tam giác nên định thức bằng tích các phần tử trên đường chéo chính và đường chéo chính của đều là số nên
Do đó
Ví dụ với ma trận , như đã làm ở trên thì có phân tích là
Khi đó
Kiểm tra lại bằng Python
def determinant_of_matrix(A):
L,U=LU_Decomposition(A)
det=np.linalg.det(U)
print("U=",U)
return det
A=np.array([[8.,2.,9.],[4.,9.,4.],[6.,7.,9.]])
print("Det by library: ",np.linalg.det(A))
print("Det by LU Decomposition: ",determinant_of_matrix(A))
Kết quả chạy
Det by library: 165.99999999999991
U= [[ 8. 2. 9. ]
[ 0. 8. -0.5 ]
[ 0. 0. 2.59375]]
Det by LU Decomposition: 165.99999999999991
Trong trường hợp là ma trận xác định dương (positive definite matrix) và với là ma trận tam giác dưới với các thành phần trên đường chéo chính là các số thực dương thì ta có phân tích Cholesky, mình sẽ trình bày ở bài sau.
IV. Tài liệu tham khảo
- https://courses.grainger.illinois.edu/cs357/sp2020/notes/ref-9-linsys.html
- https://vi.wikipedia.org/wiki/Ph%C3%A2n_t%C3%ADch_LU
- https://fit.mta.edu.vn/files/DanhSach/BaigiangDSTT_16.pdf
- http://www.seas.ucla.edu/~vandenbe/133A/133A-notes.pdf
- http://www.math.iit.edu/~fass/477577_Chapter_7.pdf
- https://machinelearningmastery.com/introduction-to-matrix-decompositions-for-machine-learning/