2016-11-21 19 views
2

我使用PCA來降低N維數據集的維數,但是我想要建立對大離羣值的穩健性,所以我已經一直在研究Robust PCA代碼。如何使用穩健的PCA輸出作爲來自傳統PCA的主要成分(本徵)矢量

對於傳統的PCA,我使用了python的sklearn.decomposition.PCA,它很好地將主要組件作爲向量返回,然後我可以投影我的數據(要清楚,我也使用SVD編寫了自己的版本所以我知道這個方法是如何工作的)。我發現了一些預編碼的RPCA python代碼(如https://github.com/dganguli/robust-pcahttps://github.com/jkarnows/rpcaADMM)。

第一個代碼是基於Candes et al。 (2009)方法,並返回數據集D的低秩L和稀疏S矩陣。第二個代碼使用矩陣分解的ADMM方法(Parikh,N.,& Boyd,S。2013)並返回X_1,X_2,X_3矩陣。我必須承認,我很難弄清楚如何將它們連接到由標準PCM算法返回的主軸上。任何人都可以提供指導嗎?

具體來說,在一個數據集X中,我有一個N個3-D點雲。我運行它通過主成分分析:

pca=sklean.decompose.PCA(n_components=3) 
pca.fit(X) 
comps=pca.components_ 

和這3個組件是3D矢量定義新的基礎上我投射我所有的要點。用穩健的PCA,我得到矩陣L + S = X。然後運行pca.fit(L)?我原以爲RPCA會讓我回到特徵向量,但有內部步驟來拋出異常值,作爲構建協方差矩陣或執行SVD的一部分。

也許我認爲「健壯的PCA」不是其他人如何使用/編碼它?

+0

我認爲,如果你解釋這將有助於什麼的矩陣連接的向量的問題標準的PCM算法是。 – ImportanceOfBeingErnest

+0

我加入問題更清楚。 – AstroBen

回答

2

robust-pca code因子數據矩陣D成兩個矩陣,LS即「低秩」和「疏」矩陣(見the paper細節)。 L是各種觀察值之間大多不變,而S是不同的。 the paper中的圖2和圖3給出了一個非常好的示例,它從幾個安全攝像頭中挑選出靜態背景(L)以及諸如傳遞人物(S)等可變因素。

如果您只是想要特徵向量,請將S視爲垃圾(您想要剪除的「大離羣值」),然後對L矩陣進行特徵分析。

下面是一個使用一個例子robust-pca code

L, S = RPCA(data).fit() 
    rcomp, revals, revecs = pca(L) 
    print("Normalised robust eigenvalues: %s" % (revals/np.sum(revals),)) 

這裏,pca功能是:

def pca(data, numComponents=None): 
    """Principal Components Analysis 

    From: http://stackoverflow.com/a/13224592/834250 

    Parameters 
    ---------- 
    data : `numpy.ndarray` 
     numpy array of data to analyse 
    numComponents : `int` 
     number of principal components to use 

    Returns 
    ------- 
    comps : `numpy.ndarray` 
     Principal components 
    evals : `numpy.ndarray` 
     Eigenvalues 
    evecs : `numpy.ndarray` 
     Eigenvectors 
    """ 
    m, n = data.shape 
    data -= data.mean(axis=0) 
    R = np.cov(data, rowvar=False) 
    # use 'eigh' rather than 'eig' since R is symmetric, 
    # the performance gain is substantial 
    evals, evecs = np.linalg.eigh(R) 
    idx = np.argsort(evals)[::-1] 
    evecs = evecs[:,idx] 
    evals = evals[idx] 
    if numComponents is not None: 
     evecs = evecs[:, :numComponents] 
    # carry out the transformation on the data using eigenvectors 
    # and return the re-scaled data, eigenvalues, and eigenvectors 
    return np.dot(evecs.T, data.T).T, evals, evecs