numpyとsklearnのPCAは異なる結果を生成します


20

私は何かを誤解していますか。これは私のコードです

sklearnを使用する

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import decomposition
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

pca = decomposition.PCA(n_components=3)

x = np.array([
        [0.387,4878, 5.42],
        [0.723,12104,5.25],
        [1,12756,5.52],
        [1.524,6787,3.94],
    ])
pca.fit_transform(x)

出力:

array([[ -4.25324997e+03,  -8.41288672e-01,  -8.37858943e-03],
   [  2.97275001e+03,  -1.25977271e-01,   1.82476780e-01],
   [  3.62475003e+03,  -1.56843494e-01,  -1.65224286e-01],
   [ -2.34425007e+03,   1.12410944e+00,  -8.87390454e-03]])

numpyメソッドを使用する

x_std = StandardScaler().fit_transform(x)
cov = np.cov(x_std.T)
ev , eig = np.linalg.eig(cov)
a = eig.dot(x_std.T)

出力

array([[ 0.06406894,  0.94063993, -1.62373172],
   [-0.35357757,  0.7509653 ,  0.63365168],
   [ 0.29312477,  0.6710958 ,  1.11766206],
   [-0.00361615, -2.36270102, -0.12758202]])
I have kept all 3 components but it doesnt seem to allow me to retain my original data.

なぜそうなのか知っていますか?

元のマトリックスを取得したい場合はどうすればよいですか?


あなたのnumpyコードは間違っています(また、X定義されていないものを使用しています)。あなたの数学を再確認してください。
アノニムース

ipythonノートブックを使用しているので、セル単位でしかコピーできません。私の数学は間違っていますか?どの部分@ Anony-Mousse
aceminer

Anony-ムースはい@私は私のエラーを実現し、それはまだdoesntの一致
aceminer

@aceminer x_stdではなくx_std.Tの共分散行列を計算する理由を知りたいですか?
エフゲニー・ナボコフ

@EvgeniNabokov長すぎました。SRY私はまだ覚えていないことができます
aceminer

回答:


21

違いは、decomposition.PCAPCAを実行する前に変数を標準化しないのに対して、手動計算でStandardScalerは標準化を行うために呼び出すためです。したがって、この違いを観察しています:相関または共分散のPCA?

交換する場合

pca.fit_transform(x)

x_std = StandardScaler().fit_transform(x)
pca.fit_transform(x_std)

手動計算と同じ結果が得られます...

...ただし、PCの順序までです。それはあなたが走るとき

ev , eig = np.linalg.eig(cov)

固有値は必ずしも降順ではありません。私は得る

array([ 0.07168571,  2.49382602,  1.43448827])

そのため、手動で注文する必要があります。Sklearnはあなたのためにそれをします。


元の変数の再構築については、PCAを逆にして、いくつかの主成分から元の変数を再構築する方法を参照してください


確認したいだけです。行列を標準偏差で標準化することは本当に必要ですか?彼らがそれをしない例を見ました
aceminer

それは必要ではありません、それを行うためのただ一つの方法です。最初の段落に置いたリンクをご覧ください:stats.stackexchange.com/questions/53-それは本当にこの質問に関するすべてです。標準化する場合、相関についてPCAを実行します。そうでない場合は、共分散でPCAを行います。
アメーバは、モニカーを復活させる

9

ここでのpythonでの議論とPCAの説明と素敵な実装があります。この実装により、scikit PCAと同じ結果が得られます。これは、PCAが間違っていることを示す別の指標です。

import numpy as np
from scipy import linalg as LA

x = np.array([
        [0.387,4878, 5.42],
        [0.723,12104,5.25],
        [1,12756,5.52],
        [1.524,6787,3.94],
    ])

#centering the data
x -= np.mean(x, axis = 0)  

cov = np.cov(x, rowvar = False)

evals , evecs = LA.eigh(cov)

固有値(および固有ベクトル)を降順に並べ替える必要があります

idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]

a = np.dot(x, evecs) 

一般に、単純な例を実装して(できるだけ単純に)コードをチェックし、正しい結果(および中間結果)を手動で計算することをお勧めします。これは、問題を特定するのに役立ちます。


1
この答えが大好きです。それは私の問題を解決しました!
金華王
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.