大家好,我是章北海
废话少说,极简介绍奇异值分解(SVD)
SVD 原理
奇异值分解(Singular Value Decomposition)是线性代数中一种重要的矩阵分解,也是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域。
有一个𝑚×𝑛的实数矩阵𝐴,我们想要把它分解成如下的形式:
其中𝑈和𝑉均为单位正交阵,即有和,𝑈称为左奇异矩阵,𝑉称为右奇异矩阵,Σ仅在主对角线上有值,我们称它为奇异值,其它元素均为0。
求解U, Σ, V
SVD算法
输入:样本数据
输出:左奇异矩阵,奇异值矩阵,右奇异矩阵
1 计算特征值:特征值分解,其中为原始样本数据
得到左奇异矩阵和奇异值矩阵
2 间接求部分右奇异矩阵:求
利用A=UΣ′V′可得
3 返回U, Σ′, V′,分别为左奇异矩阵,奇异值矩阵,右奇异矩阵。
Python 求解SVD
from numpy import array from numpy import diag from numpy import zeros from scipy.linalg import svd # define a matrix A = array([ [1,2,3,4,5,6,7,8,9,10], [11,12,13,14,15,16,17,18,19,20], [21,22,23,24,25,26,27,28,29,30]]) print(A)
>>> A array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]])
# Singular-value decomposition U, s, VT = svd(A) # create m x n Sigma matrix Sigma = zeros((A.shape[0], A.shape[1])) # populate Sigma with n x n diagonal matrix Sigma[:A.shape[0], :A.shape[0]] = diag(s) # select n_elements = 2 Sigma = Sigma[:, :n_elements] VT = VT[:n_elements, :] # reconstruct B = U.dot(Sigma.dot(VT)) print(B)
>>> B array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.], [11., 12., 13., 14., 15., 16., 17., 18., 19., 20.], [21., 22., 23., 24., 25., 26., 27., 28., 29., 30.]])
# transform T = U.dot(Sigma) print(T)
>>> T array([[-18.52157747, 6.47697214], [-49.81310011, 1.91182038], [-81.10462276, -2.65333138]])
T = A.dot(VT.T) print(T)
[[-18.52157747 6.47697214] [-49.81310011 1.91182038] [-81.10462276 -2.65333138]]