RでPCAを使用して次元削減を実行する方法


30

大きなデータセットがあり、次元削減を実行したい。

今ではどこでも、PCAをこれに使用できると読んでいます。ただし、PCAを計算/実行した後、何をすべきかまだわかりません。Rでは、これはコマンドで簡単に行えprincompます。

しかし、PCAを計算した後はどうすればよいでしょうか?最初の主成分を使用することにした場合、データセットを正確に削減するにはどうすればよいですか?100


この質問は(100 PCは非常に明確ではないです縮小次元のデータセット)が、特に元の変数(受け入れ答えのトピック)を再構築についても参照:PCAを逆にして、いくつかの主要な構成要素から元の変数を再構築する方法は?
アメーバは、モニカを復活させる

回答:


35

質問であなたが得ているのは、少数の主成分(PC)を使用したデータの切り捨てに関するものだと思います。このような操作の場合prcomp、再構成で使用される行列乗算を視覚化する方が簡単であるという点で、この関数はより具体的であると思います。

まず、合成データセットXtを指定し、PCAを実行します(通常、共分散行列に関連するPCを記述するためにサンプルを中央に配置します。

#Generate data
m=50
n=100
frac.gaps <- 0.5 # the fraction of data with NaNs
N.S.ratio <- 0.25 # the Noise to Signal ratio for adding noise to data

x <- (seq(m)*2*pi)/m
t <- (seq(n)*2*pi)/n

#True field
Xt <- 
 outer(sin(x), sin(t)) + 
 outer(sin(2.1*x), sin(2.1*t)) + 
 outer(sin(3.1*x), sin(3.1*t)) +
 outer(tanh(x), cos(t)) + 
 outer(tanh(2*x), cos(2.1*t)) + 
 outer(tanh(4*x), cos(0.1*t)) + 
 outer(tanh(2.4*x), cos(1.1*t)) + 
 tanh(outer(x, t, FUN="+")) + 
 tanh(outer(x, 2*t, FUN="+"))

Xt <- t(Xt)

#PCA
res <- prcomp(Xt, center = TRUE, scale = FALSE)
names(res)

結果またはprcompで、PC(res$x)、固有値(res$sdev)、各PCの大きさに関する情報、および負荷(res$rotation)を確認できます。

res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)

固有値を二乗することにより、各PCによって説明される分散を取得します。

plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance

最後に、主要な(重要な)PCのみを使用して、データの切り捨てられたバージョンを作成できます。

pc.use <- 3 # explains 93% of variance
trunc <- res$x[,1:pc.use] %*% t(res$rotation[,1:pc.use])

#and add the center (and re-scale) back to data
if(res$scale != FALSE){
	trunc <- scale(trunc, center = FALSE , scale=1/res$scale)
}
if(res$center != FALSE){
    trunc <- scale(trunc, center = -1 * res$center, scale=FALSE)
}
dim(trunc); dim(Xt)

結果は、わずかに滑らかなデータマトリックスであり、小規模の機能は除外されていることがわかります。

RAN <- range(cbind(Xt, trunc))
BREAKS <- seq(RAN[1], RAN[2],,100)
COLS <- rainbow(length(BREAKS)-1)
par(mfcol=c(1,2), mar=c(1,1,2,1))
image(Xt, main="Original matrix", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()
image(trunc, main="Truncated matrix (3 PCs)", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()

ここに画像の説明を入力してください

また、prcomp関数の外部で実行できる非常に基本的なアプローチを次に示します。

#alternate approach
Xt.cen <- scale(Xt, center=TRUE, scale=FALSE)
C <- cov(Xt.cen, use="pair")
E <- svd(C)
A <- Xt.cen %*% E$u

#To remove units from principal components (A)
#function for the exponent of a matrix
"%^%" <- function(S, power)
     with(eigen(S), vectors %*% (values^power * t(vectors)))
Asc <- A %*% (diag(E$d) %^% -0.5) # scaled principal components

#Relationship between eigenvalues from both approaches
plot(res$sdev^2, E$d) #PCA via a covariance matrix - the eigenvalues now hold variance, not stdev
abline(0,1) # same results

さて、どのPCを保持するかを決定することは別の質問です- 私はしばらく前に興味を持っていました。お役に立てば幸いです。


2
マーク、センターとスケールを明示的に記録する必要はありませんが、prcompそうしてくれます。見ているres$centerres$scale。私見では、これらの(中心または/への明示的な呼び出しの間でスケーリングされていないかについての偶然の違いを使用する傾向が少ない誤差であるscaleprcompコール)。
cbeleitesは、モニカをサポートしています

1
それはおよそOPの質問に答えていないので、この答えは、拡張を必要とするwhat to do after calculating the PCAかをhow do I reduce my dataset exactly?OPが彼のサンプルでPCAを実施したことを考えると、彼の質問はそれをどうするか、そしてこのサブサンプルで実際に何が起こるかです。PCAのやり方ではありません。E <- eigen(cov(Sample)); A<- scale(scale=F, Sample) %*% E$vectorsスコアを取得する別の方法を取得することを提案することもできます(実際には、princompが実行しますstats:::princomp.default)。
usεr11852は回復モニック言う

1
@ user11852-質問は、具体的にはデータセットの削減(つまり、ここで示した切り捨て)に言及しています。これが彼が探していたものかどうかを決めるのは彼に任せます。
ボックス内のマーク

1
@Marc、応答に感謝します。上記の答えのいずれかが次元削減にどのように対処しているかに固執しているので、私は戻ってすべてをもう一度読む必要があるかもしれないと思います。示すように、dim(trunc)= dim(Xt)。それの利点は何でしたか、寸法は縮小されませんでした。
B_Miner

2
@B_Miner-切り捨ては、データの主要なパターンに焦点を当て、小規模なパターンとノイズを除去するために使用されることに注意してください。切り捨てられたデータは、ディメンションの点では小さくありませんが、「クリーン」です。ただし、少数のベクトルを使用してマトリックス全体を再構築できるため、切り捨てによりデータ量が削減されます。良い例は、画像圧縮にPCAを使用する場合です。この場合、少数のPCを使用して画像を再構築できます。このベクトルの小さなサブセットはより少ないメモリを使用しますが、再構築では小規模の詳細が多少失われます。
ボックスのマーク

3

これらの他の答えは非常によく詳細です。しかし、実際にもっと基本的な質問をしているのではないかと思っています。PCを手に入れたらどうしますか?

各PCは、単に新しい変数になります。PC1が全体の変動の60%を占め、PC2が30%を占めているとします。これは全変動の90%を占めているため、これら2つの新しい変数(PC)を元の変数の単純化されたバージョンとして単純に取得できます。これは、もしそれがあなたが興味を持っているのであれば、それらをモデルにフィットさせることを意味します。

質問の範囲を過小評価してしまった場合は申し訳ありません!


2

iλiΣk=1pλkpp=784λ

実際には、PCAを使用して、PCの投影(「スコア」)を元のサンプルの代理データとして使用しています。スコアに対してすべての分析を行い、その後、PCを使用して元のサンプルを再構築し、元のスペースで起こったことを確認します(これは基本的に主成分回帰です)。明らかに、固有ベクトル(「ローディング」)を意味のあるインタープリターにできる場合は、さらに優れた位置にいます:そのローディングを直接推論することにより、そのローディングによって提示される変化のモードでサンプルに何が起こるかを記述できます。まったく再構築を気にしません。:)

一般に、「PCAの計算後」何を行うかは、分析のターゲットによって異なります。PCAは、RSS再構成基準の下で最適な、線形に独立したデータのサブサンプルを提供します。これを分類、回帰、またはその両方に使用したり、前述したように、サンプルのバリエーションの有意な直交モードを認識したい場合があります。

コメント:保持するコンポーネントの数を決定するための最も素朴な方法は、任意の数などではなく、減少した次元のサンプルで保持するサンプル変動のしきい値に基づいて推定値を決定することです。3、100、200。user4959で説明したよう$loadingsに、によって生成されたリストオブジェクトのフィールドの下にあるリストの関連フィールドをチェックすることで、その累積変動をチェックできますprincomp


1
主成分回帰について言及したように、Rではパッケージplsによって提供されます。保持するコンポーネントの数については、%分散を決定することの利点はありません。コンポーネントの(おそらく、私は非常に異なるレベルのノイズを持つデータを使用しているためです。@ Marc-in-the-boxが述べているように、適切なPCの数を決定するためのさまざまなアプローチがあり、戦略は( )型のデータにして従うことですデータ解析の種類の両方に依存すべきである。
cbeleitesサポートモニカ

plsprincomp {stats}KKDD

1
はい、それは素朴です。説明された分散の任意の%を設定することは、他の任意のカットオフの本質的な利点があることに同意しません。しかし、a)OPはnoの選択についてアドバイスを求めたことはないので、とにかくこれについて戦う価値はありません。b)PCAモデルの適切な検査がとにかく行われるべきであることに同意すると思います。
cbeleitesサポートモニカ

問題ない; とにかく答える前に私がしたのはコメントだけでした。(私はそれが私が言いたいことを明確化するのではなくperplexesだと思う最後のように私のコメントの段落を出してあげる)
usεr11852は回復モニック言う

0

PCAを実行した後、最初の2つのコンポーネントを選択してプロットします。Rのスクリープロットを使用してコンポーネントの変動を確認できます。また、loadings = Tでサマリー関数を使用すると、コンポーネントのフィーチャの変動を特定できます。

このhttp://www.statmethods.net/advstats/factor.htmlおよび http://statmath.wu.ac.at/~hornik/QFS1/principal_component-vignette.pdfご覧ください。

あなたが望むものを考えてみてください。PCA分析から多くのことを解釈できます。

最高のアビック

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.