PCA降维算法原理及代码实现(python和matlab)
?
常見的數(shù)據(jù)降維算法有:奇異值分解(SVD)、主成分分析(PCA)、因子分析(FA)、獨(dú)立成分分析(ICA)。
PCA降維的基本思想:通過計(jì)算數(shù)據(jù)矩陣的協(xié)方差矩陣,然后得到協(xié)方差矩陣的特征值、特征向量、選擇特征值最大(即方差最大)的K個(gè)特征所對(duì)應(yīng)的特征向量組成的矩陣,這樣可以將數(shù)據(jù)矩陣轉(zhuǎn)換到新的空間當(dāng)中,實(shí)現(xiàn)數(shù)據(jù)特征的降維。
PCA降維有兩種思路:一種是特征值分解協(xié)方差矩陣,一種是奇異值分解協(xié)方差矩陣。下面介紹基于奇異值分解的方法
一:關(guān)于特征值分解
a)特征值與特征向量
如果一個(gè)向量v是矩陣A的特征向量,將一定可以表示成下面的形式
其中,λ是特征向量v對(duì)應(yīng)的特征值,一個(gè)矩陣的一組特征向量是一組正交向量。
b)特征值分解矩陣
對(duì)于矩陣A,有一組特征向量v,將這組向量進(jìn)行正交化單位化,就能得到一組正交單位向量。特征值分解,就是將矩陣A分解為如下式:
其中,Q是矩陣A的特征向量組成的矩陣,則是一個(gè)對(duì)角陣,對(duì)角線上的元素就是特征值。
二:SVD分解矩陣原理
奇異值分解是一個(gè)能適用于任意矩陣的一種分解的方法,對(duì)于任意矩陣A總是存在一個(gè)奇異值分解:
假設(shè)A是一個(gè)m*n的矩陣,那么得到的U是一個(gè)m*m的方陣,U里面的正交向量被稱為左奇異向量。Σ是一個(gè)m*n的矩陣,Σ除了對(duì)角線其它元素都為0,對(duì)角線上的元素稱為奇異值,是v的轉(zhuǎn)置矩陣,是一個(gè)n*n的矩陣,它里面的正交向量被稱為右奇異值向量。而且一般來講,我們會(huì)將Σ上的值按從大到小的順序排列。
SVD分解矩陣A的步驟:
(1) 求的特征值和特征向量,用單位化的特征向量構(gòu)成 U。
(2) 求的特征值和特征向量,用單位化的特征向量構(gòu)成 V。
(3) 將或者的特征值求平方根,然后構(gòu)成 Σ
三:實(shí)現(xiàn)PCA算法的步驟:
(1)去均值(即去中心化)每一位特征減去各自的平均值。
(2)計(jì)算協(xié)方差矩陣1/n*xx'
?? (3) ? 用奇異值分解法求協(xié)方差矩陣1/n*xx'的特征值與特征向量
(4)對(duì)特征值從大到小排序,選擇其中最大的k個(gè),然后將其對(duì)應(yīng)的k個(gè)特征向量分別作為行向量組成特征向量矩陣P
(5)將數(shù)據(jù)轉(zhuǎn)換到K個(gè)特征向量構(gòu)建的新空間中即Y=PX
如何選擇主成分個(gè)數(shù)K
1- ? ?<=t
Sii為SVD分解時(shí)產(chǎn)生的S矩陣
t的值可以自己設(shè)置,t取0.01則代表PCA保留了99%的信息。
最好的K維特征是將n維樣本點(diǎn)轉(zhuǎn)換為K維后,每一維上的樣本方差都很大。
?
補(bǔ):matlab自帶的mean函數(shù)用法。mean(x)默認(rèn)求矩陣列的平均值。mean(x,2)求矩陣行的平均值。
std函數(shù):求矩陣的標(biāo)準(zhǔn)差
std(A)是最常見的求標(biāo)準(zhǔn)差的函數(shù),除以的是N-1
std(A,flag)代表的是用哪一個(gè)標(biāo)準(zhǔn)差函數(shù),如果取0則代表除以N-1,如果1代表的是除以N
std(A,flag,dim)第三個(gè)參數(shù)代表的是按照列求標(biāo)準(zhǔn)差,還是按照行求標(biāo)準(zhǔn)差。
repmat函數(shù)處理大矩陣且內(nèi)容重復(fù)時(shí)會(huì)用到
eg? B=repmat([1 2;3 4],2,3)
B= 1 2? 1 2 1 2
? ? ? 3 4? 3 4 3 4
? ? ??1 2? 1 2 1 2
? ? ? 3 4? 3 4 3 4 ?
length(x)矩陣 ? M行N列返回M和N這兩個(gè)數(shù)的最大值。
歸一化(按列減均值)
標(biāo)準(zhǔn)化(按列縮放到指定范圍)
正則化(范數(shù))
eig函數(shù)的用法
a=[-1,1,0;-4,3,0;1,0,2]
eig(a)= [2,1,1]'
[v,d]=eig(a)
v =
? ? ? ? ?0 ? ?0.4082 ? ?0.4082
? ? ? ? ?0 ? ?0.8165 ? ?0.8165
? ? 1.0000 ? -0.4082 ? -0.4082
d =
? ? ?2 ? ? 0 ? ? 0
? ? ?0 ? ? 1 ? ? 0
? ? ?0 ? ? 0 ? ? 1
v是特征向量對(duì)應(yīng)的特征矩陣。d是特征向量組成的矩陣。
rot函數(shù)的用法
b=rot90(a)逆時(shí)針旋轉(zhuǎn)90度
b=rot90(a,-1)順時(shí)針旋轉(zhuǎn)90度
matlab代碼實(shí)現(xiàn)(待改進(jìn):此方法采用的是基于特征值分解的方法,改進(jìn)為用奇異值分解的方法)
function S=princa(X) [m,n]=size(X); %計(jì)算矩陣的行m和列n%-------------第一步:標(biāo)準(zhǔn)化矩陣-----------------% mv=mean(X); %計(jì)算各變量的均值 st=std(X); %計(jì)算各變量的標(biāo)準(zhǔn)差 X=X-repmat(mv,m,1); %標(biāo)準(zhǔn)化矩陣X%-------------第二步:計(jì)算相關(guān)系數(shù)矩陣-----------------% % R1=X'*X/(m-1); %方法一:協(xié)方差矩陣計(jì)算公式 % R2=cov(X); %方法二:協(xié)方差矩陣計(jì)算函數(shù) R=corrcoef(X); %方法三:相關(guān)系數(shù)矩陣函數(shù)%-------------第三步:計(jì)算特征向量和特征值-----------------% [V,D]=eig(R); %計(jì)算矩陣R的特征向量矩陣V和特征值矩陣D,特征值由小到大%將特征向量矩陣V從大到小排序%將特征值矩陣由大到小排序 E=diag(D); %將特征值矩陣轉(zhuǎn)換為特征值向量%-------------第四步:計(jì)算貢獻(xiàn)率和累計(jì)貢獻(xiàn)率-----------------% ratio=0; %累計(jì)貢獻(xiàn)率 for k=1:nr=E(k)/sum(E); %第k主成份貢獻(xiàn)率ratio=ratio+r; %累計(jì)貢獻(xiàn)率if(ratio>=0.8) %取累計(jì)貢獻(xiàn)率大于等于90%的主成分q=k;break;end end%-------------第五步:計(jì)算得分-----------------% V=V(:,1:q); S=X*V;python代碼實(shí)現(xiàn)
import numpy as np def pca(X,k):n_samples, n_features = X.shapemean=np.array([np.mean(X[:,i]) for i in range(n_features)])norm_X=X-meanscatter_matrix=np.dot(np.transpose(norm_X),norm_X)eig_val, eig_vec = np.linalg.eig(scatter_matrix)eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)]eig_pairs.sort(reverse=True)feature=np.array([ele[1] for ele in eig_pairs[:k]])data=np.dot(norm_X,np.transpose(feature))return data#print(eig_pairs) X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) print(pca(X,1))利用sklearn中的PCA函數(shù)實(shí)現(xiàn)
from sklearn.decomposition import PCA import numpy as np X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) pca=PCA(n_components=1) pca.fit(X) print(pca.transform(X)) #ske參考資料:寫得巨好超級(jí)推薦https://blog.csdn.net/program_developer/article/details/80632779
總結(jié)
以上是生活随笔為你收集整理的PCA降维算法原理及代码实现(python和matlab)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux跨ip拷贝,Linux的虚拟机
- 下一篇: websocket python爬虫_p