奇異值分解
本篇使用到了numpy
這個筆記系列的每一篇都不會很長,適合在各種碎片時間裡閱讀。代碼部分使用的語言是Python,需要使用到的包我都會在開頭標註出來的。
在數據分析的過程中,當原數據排成的矩陣規模較大時,通過奇異值分解,可將其分為左奇異矩陣、奇異值矩陣、右奇異矩陣,三個較小的矩陣,便於儲存和傳輸。
同時奇異值分解也便於進行對矩陣的數值運算的近似操作。
奇異值分解的英文是Singular Value Discomposition,也就是通常說的SVD。
當矩陣
這裡,
奇異值分解就是將特徵值分解的方法推廣到一般的矩陣上:
簡記為
可以通過numpy.linalg.svd()進行求解,這個函數的返回值是左奇異矩陣、奇異值、右奇異矩陣。
接下來要用特徵值作成奇異值矩陣。
u,s,vt=numpy.linalg.svd(A)
sig=numpy.zeros(numpy.shape(A))
sig[:len(s),:len(s)]=numpy.diag(s)
從而我們就能通過三個小矩陣重構原矩陣。
然後我們就可以開始矩陣近似的工作。
#*給定百分比,直接進行近似
def ApproxSVD(data,percent):
U,s,VT=numpy.linalg.svd(data)
sigma=numpy.zeros(numpy.shape(data))
sigma[:len(s),:len(s)]=numpy.diag(s)
#*這裡求出選取的奇異值個數
sum_sigma=sum(s)
sum_sigma1=(int)(sum_sigma)*percent
sum_sigma2=0
k=0
while sum_sigma2 < sum_sigma1:
for i in s:
sum_sigma2 += i
k+=1
#*開始矩陣近似
D=(U[:,:k].dot(sigma[:k,:k])).dot(VT[:k,:])
return numpy.rint(D).astype("uint8")
我們選擇的確定取奇異值個數的方法是取奇異值總和對應百分比分位上的奇異值的個數。
這個系列的筆記不打算加入實際應用的部分,只記錄純理論的內容。如果時間允許的話,我會單獨再開設一個實戰開發的系列筆記。(老鴿王了)