【時間】2018.12.08
【題目】特徵值分解和奇異值分解以及使用numpy實現
目錄
二、奇異值分解(singular Value Decomposition)
注意:只有方陣才能進行特徵值分解
如果說一個向量v是方陣A的特徵向量,將一定可以表示成下面的形式:
這時候λ就被稱爲特徵向量v對應的特徵值,一個矩陣的一組特徵向量是一組正交向量。特徵值分解是將一個矩陣分解成下面的形式:
其中Q是這個矩陣A的特徵向量組成的矩陣,Σ是一個對角陣,每一個對角線上的元素就是一個特徵值。首先,要明確的是,一個矩陣其實就是一個線性變換,因爲一個矩陣乘以一個向量後得到的向量,其實就相當於將這個向量進行了線性變換。
numpy中的linalg已經實現了ELG,可以直接調用,具體爲:
e_vals,e_vecs = np.linalg.eig(a)
輸入參數:a爲需要分解的方陣
返回:
以下是測試代碼:
注意矩陣求逆可以使用np.linalg.inv(a)
【代碼】
import numpy as np a = np.random.randn(4, 4) e_vals,e_vecs = np.linalg.eig(a) print('分解得到的形狀:\n',e_vals.shape,e_vecs.shape ) print('特徵值:\n',e_vals) print('特徵向量矩陣:\n',e_vecs) smat=np.zeros((4,4)) smat= np.diag(e_vals) #驗證特徵值分解 result=np.allclose( a, np.dot(e_vecs, np.dot(smat, np.linalg.inv(e_vecs))))#對比兩個矩陣的各個元素,若一致則返回True print('驗證特徵值分解:\n',result)
【運行結果】
奇異值分解(singular Value Decomposition),簡稱SVD,線性代數中矩陣分解的方法。假如有一個矩陣A,對它進行奇異值分解,可以得到三個矩陣:
(情況一)這三個矩陣的大小:
矩陣sigma(即上圖U和V中間的矩陣)除了對角元素不爲0,其他元素都爲0,並且對角元素是從大到小排列的,前面的元素比較大,後面的很多元素接近0。這些對角元素就是奇異值。
(情況二)sigma中有n個奇異值,但是由於排在後面的很多接近0,所以我們可以僅保留比較大的r個奇異值,此時奇異值分解爲:
實際應用中,我們僅需保留着三個比較小的矩陣,就能表示A,不僅節省存儲量,在計算的時候更是減少了計算量。
numpy中的linalg已經實現了SVD,可以直接調用,具體爲:
U,S,Vh= numpy.linalg.svd(a, full_matrices=True, compute_uv=True)[source]
輸入參數:
返回值:2.1中的3個矩陣
注意: 無論何種情況,返回的奇異矩陣都只是由奇異值組成的一個向量(而且是省略零值的),如果想要獲得對應的奇異矩陣,可以使用np.diag(s)進行構建。詳細用法請查閱:https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.svd.html#numpy.linalg.svd
以下是測試代碼:
(1)情況一(默認full_matrices=True)
【代碼】
import numpy as np a = np.random.randn(9, 6) u, s, vh = np.linalg.svd(a) print('分解得到矩陣的形狀:\n',u.shape,s.shape,vh.shape) print('奇異值:\n',s) smat=np.zeros((9,6)) smat[:6,:6]= np.diag(s) print('奇異矩陣:\n',smat) #驗證奇異值分解 result=np.allclose(a, np.dot(u, np.dot(smat, vh)))#對比兩個矩陣的各個元素,若一致則返回True print(result)
【運行結果】
(2)情況二( full_matrices=False)
【代碼】
import numpy as np a = np.random.randn(9, 6) u, s, vh = np.linalg.svd(a, full_matrices=False) print('分解得到矩陣的形狀:\n',u.shape,s.shape,vh.shape) smat = np.zeros((6, 6)) print('奇異值:\n',s) smat= np.diag(s) print('奇異矩陣:\n',smat) #驗證奇異值分解 result=np.allclose(a, np.dot(u, np.dot(smat, vh)))#對比兩個矩陣的各個元素,若一致則返回True print(result)
【運行結果】
參考文獻
http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-and-applications.html