web-dev-qa-db-ja.com

sklearn PCAから固有値とベクトルを取得する

PCAアプリケーションの固有値と固有ベクトルを取得するにはどうすればよいですか?

from sklearn.decomposition import PCA
clf=PCA(0.98,whiten=True)      #converse 98% variance
X_train=clf.fit_transform(X_train)
X_test=clf.transform(X_test)

docs で見つけることができません。

1.私はここで異なる結果を理解することができません。

編集

def pca_code(data):
    #raw_implementation
    var_per=.98
    data-=np.mean(data, axis=0)
    data/=np.std(data, axis=0)
    cov_mat=np.cov(data, rowvar=False)
    evals, evecs = np.linalg.eigh(cov_mat)
    idx = np.argsort(evals)[::-1]
    evecs = evecs[:,idx]
    evals = evals[idx]
    variance_retained=np.cumsum(evals)/np.sum(evals)
    index=np.argmax(variance_retained>=var_per)
    evecs = evecs[:,:index+1]
    reduced_data=np.dot(evecs.T, data.T).T
    print(evals)
    print("_"*30)
    print(evecs)
    print("_"*30)
    #using scipy package
    clf=PCA(var_per)
    X_train=data.T
    X_train=clf.fit_transform(X_train)
    print(clf.explained_variance_)
    print("_"*30)
    print(clf.components_)
    print("__"*30)
  1. 収束条件のある簡約集合ではなく、すべての固有値と固有ベクトルを取得したいです。
28
Abhishek Bhatia

実装

相関行列の固有ベクトル、つまりnormalized変数の共分散行列を計算しています。
data/=np.std(data, axis=0)は従来のPCAの一部ではなく、変数を中央に配置するだけです。そのため、sklearn PCAは事前にデータをスケーリングしません

それとは別に、あなたが提供したコードが実行されなかったという事実を抽象化すれば、あなたは正しい軌道に乗っています;)。行/列のレイアウトと混同しているだけです。正直なところ、X = data.Tで開始し、それ以降はXでのみ作業する方がはるかに簡単だと思います。投稿の最後に「修正済み」のコードを追加しました。

固有値の取得

clf.components_を使用して固有ベクトルを取得できることは既に説明しました。

主成分があります。それらはcovariance行列$ X ^ T X $の固有ベクトルです。

そこから固有値を取得する方法は、この行列を各主成分に適用し、結果を成分に投影することです。 v_1を最初の主成分とし、lambda_1を関連する固有値とします。我々は持っています:
eq したがって、 eq2 以来 eq3 。 (x、y)ベクトルxとyのスカラー積。

戻るPythonできること:

n_samples = X.shape[0]
# We center the data and compute the sample covariance matrix.
X -= np.mean(X, axis=0)
cov_matrix = np.dot(X.T, X) / n_samples
for eigenvector in pca.components_:
    print(np.dot(eigenvector.T, np.dot(cov_matrix, eigenvector)))

そして、固有ベクトルに関連付けられた固有値を取得します。さて、私のテストでは、最後の2つの固有値で動作しないことが判明しましたが、数値安定性のスキルがないことに起因すると思います。

これは固有値を取得するbestの方法ではありませんが、それらがどこから来たかを知るのは良いことです。
固有値は、固有ベクトルの方向の分散を表します。したがって、pca.explained_variance_属性を介してそれらを取得できます。

eigenvalues = pca.explained_variance_

以下は、各メソッドで取得した固有値を出力する再現可能な例です。

import numpy as np
from sklearn.decomposition import PCA
from sklearn.datasets import make_classification


X, y = make_classification(n_samples=1000)
n_samples = X.shape[0]

pca = PCA()
X_transformed = pca.fit_transform(X)

# We center the data and compute the sample covariance matrix.
X_centered = X - np.mean(X, axis=0)
cov_matrix = np.dot(X_centered.T, X_centered) / n_samples
eigenvalues = pca.explained_variance_
for eigenvalue, eigenvector in Zip(eigenvalues, pca.components_):    
    print(np.dot(eigenvector.T, np.dot(cov_matrix, eigenvector)))
    print(eigenvalue)

元のコード、修正済み

実行すると、値が一貫していることがわかります。 numpyとscikit-learnはここでは同じアルゴリズムを使用していないため、これらは正確には等しくありません。
主なことは、前述のように、共分散ではなく相関行列を使用していたことです。また、numpyからtransposed固有ベクトルを取得していたため、非常に混乱していました。

import numpy as np
from scipy.stats.mstats import zscore
from sklearn.decomposition import PCA

def pca_code(data):
    #raw_implementation
    var_per=.98
    data-=np.mean(data, axis=0)
    # data/=np.std(data, axis=0)
    cov_mat=np.cov(data, rowvar=False)
    evals, evecs = np.linalg.eigh(cov_mat)
    idx = np.argsort(evals)[::-1]
    evecs = evecs[:,idx]
    evals = evals[idx]
    variance_retained=np.cumsum(evals)/np.sum(evals)
    index=np.argmax(variance_retained>=var_per)
    evecs = evecs[:,:index+1]
    reduced_data=np.dot(evecs.T, data.T).T
    print("evals", evals)
    print("_"*30)
    print(evecs.T[1, :])
    print("_"*30)
    #using scipy package
    clf=PCA(var_per)
    X_train=data
    X_train=clf.fit_transform(X_train)
    print(clf.explained_variance_)
    print("_"*30)
    print(clf.components_[1,:])
    print("__"*30)

これがお役に立てば幸いです。説明を求めてください。

49
ldirer

Sklearn PCA関数を使用しました。戻りパラメーター「components_」は固有ベクトルであり、「explained_variance_」は固有値です。以下は私のテストコードです。

from sklearn.decomposition import PCA
import numpy as np


def main():
    data = np.array([[2.5, 2.4], [0.5, 0.7], [2.2, 2.9], [1.9, 2.2], [3.1, 3.0], [2.3, 2.7], [2, 1.6], [1, 1.1], [1.5, 1.6], [1.1, 0.9]])
    print(data)
    pca = PCA()
    pca.fit(data)

    print(pca.components_)
    print(pca.explained_variance_)



if __name__ == "__main__":
    main()
0
Lee