特徵值分解和奇異值分解以及使用numpy實現

【時間】2018.12.08

【題目】特徵值分解和奇異值分解以及使用numpy實現

目錄

一、特徵值分解(EIG)

1.1 定義

1.2 在python中實現特徵值分解

二、奇異值分解(singular Value Decomposition)

2.1、定義

2.2 在python中實現奇異值分解


一、特徵值分解(EIG)

注意:只有方陣才能進行特徵值分解

1.1 定義

 如果說一個向量v是方陣A的特徵向量,將一定可以表示成下面的形式:

    這時候λ就被稱爲特徵向量v對應的特徵值,一個矩陣的一組特徵向量是一組正交向量。特徵值分解是將一個矩陣分解成下面的形式:

    其中Q是這個矩陣A的特徵向量組成的矩陣,Σ是一個對角陣,每一個對角線上的元素就是一個特徵值。首先,要明確的是,一個矩陣其實就是一個線性變換,因爲一個矩陣乘以一個向量後得到的向量,其實就相當於將這個向量進行了線性變換。

1.2 在python中實現特徵值分解

numpy中的linalg已經實現了ELG,可以直接調用,具體爲:

e_vals,e_vecs = np.linalg.eig(a)

輸入參數:a爲需要分解的方陣

返回:

  • e_vals:由特徵值構成的向量
  • e_vecs:由特徵向量構成的矩陣

以下是測試代碼:

注意矩陣求逆可以使用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)

2.1、定義

       奇異值分解(singular Value Decomposition),簡稱SVD,線性代數中矩陣分解的方法。假如有一個矩陣A,對它進行奇異值分解,可以得到三個矩陣:

 

(情況一)這三個矩陣的大小:

 

矩陣sigma(即上圖U和V中間的矩陣)除了對角元素不爲0,其他元素都爲0,並且對角元素是從大到小排列的,前面的元素比較大,後面的很多元素接近0。這些對角元素就是奇異值

(情況二)sigma中有n個奇異值,但是由於排在後面的很多接近0,所以我們可以僅保留比較大的r個奇異值,此時奇異值分解爲:

 

實際應用中,我們僅需保留着三個比較小的矩陣,就能表示A,不僅節省存儲量,在計算的時候更是減少了計算量。

 

2.2 在python中實現奇異值分解

numpy中的linalg已經實現了SVD,可以直接調用,具體爲:

U,S,Vh= numpy.linalg.svd(a, full_matrices=True, compute_uv=True)[source]

輸入參數:

  •  a 爲要分解的矩陣 ,維數>=2,即(...,M,N)
  •  full_matrices是bool值,默認爲True,此時分解出的U和Vh矩陣的形狀分別爲 (..., M, M)和(..., N, N),即2.1中的情況一,否則爲 (..., M, K)和(..., K, N),這裏K = min(M, N),即2.1中的情況二
  • compute_uv 也是bool值, 表示除S之外s是否計算U和Vh的值,默認爲True,即結果返回3個矩陣

返回值: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