JD Long'un bu konudaki mükemmel mesajından sonra, basit bir örnek aradım ve PCA'yı üretmek için gerekli olan R kodu ve ardından orijinal verilere geri döndüm. Bana bazı ilk elden geometrik sezgiler verdi ve bende olanı paylaşmak istiyorum. Veri kümesi ve kod doğrudan kopyalanabilir ve R form Github'a yapıştırılabilir .
Burada yarı iletkenlerde çevrimiçi olarak bulduğum bir veri setini kullandım ve grafiği çizmeyi kolaylaştırmak için sadece iki boyuta ("atom numarası" ve "erime noktası") kestim.
Bir uyarı olarak, fikir yalnızca hesaplama sürecini açıklar. PCA ikiden fazla değişkeni birkaç türetilmiş ana bileşene indirgemek veya çoklu özellikler söz konusu olduğunda eşdüzeliği tanımlamak için kullanılır. Dolayısıyla iki değişken durumunda çok fazla uygulama bulamazdı, ne de @amoeba'nın işaret ettiği gibi korelasyon matrislerinin özvektörlerini hesaplamaya gerek kalmazdı.
Ayrıca, bireysel noktaları izleme görevini kolaylaştırmak için gözlemleri 44'ten 15'e düşürdüm. Nihai sonuç iskelet veri çerçevesi ( dat1
) idi:
compounds atomic.no melting.point
AIN 10 498.0
AIP 14 625.0
AIAs 23 1011.5
... ... ...
"Bileşikler" sütunu, yarı iletkenlerin kimyasal yapılarını gösterir ve sıra adının rolünü oynar.
Bu, şu şekilde çoğaltılabilir (R konsolunda kopyalayıp yapıştırmaya hazır):
dat <- read.csv(url("http://rinterested.github.io/datasets/semiconductors"))
colnames(dat)[2] <- "atomic.no"
dat1 <- subset(dat[1:15,1:3])
row.names(dat1) <- dat1$compounds
dat1 <- dat1[,-1]
Veriler daha sonra ölçeklendi:
X <- apply(dat1, 2, function(x) (x - mean(x)) / sd(x))
# This centers data points around the mean and standardizes by dividing by SD.
# It is the equivalent to `X <- scale(dat1, center = T, scale = T)`
Doğrusal cebir adımlarını takip etti:
C <- cov(X) # Covariance matrix (centered data)
⎡⎣⎢at_nomelt_pat_no10.296melt_p0.2961⎤⎦⎥
Korelasyon işlevi cor(dat1)
, ölçeklenmemiş verilerdeki aynı çıktıyı ölçeklenen verilerdeki işlevle verir cov(X)
.
lambda <- eigen(C)$values # Eigenvalues
lambda_matrix <- diag(2)*eigen(C)$values # Eigenvalues matrix
⎡⎣⎢λPC11.2964220λPC200.7035783⎤⎦⎥
e_vectors <- eigen(C)$vectors # Eigenvectors
12√⎡⎣⎢PC111PC21−1⎤⎦⎥
İlk özvektör başlangıçta olarak döndüğünden , aşağıdaki formülleri yerleşik formüllerle tutarlı hale getirmek için olarak değiştirmeyi seçiyoruz :∼[−0.7,−0.7][0.7,0.7]
e_vectors[,1] = - e_vectors[,1]; colnames(e_vectors) <- c("PC1","PC2")
Elde edilen özdeğerler ve . Daha az minimalist koşullar altında, bu sonuç hangi özvektörlerin dahil edileceğine karar verilmesine yardımcı olacaktı (en büyük özdeğerler). Örneğin, ilk özdeğerin göreceli katkısı : yani değişkenliğin oluşturur. İkinci özvektörün yönündeki değişkenlik . Bu genellikle, özdeğerlerin değerini gösteren bir kayşat grafiği üzerinde gösterilmektedir:1.29642170.703578364.8%eigen(C)$values[1]/sum(eigen(C)$values) * 100
∼65%35.2%
PCA'nın ardındaki fikir, bu oyuncak veri kümesi örneğinin küçük boyutu göz önüne alındığında her iki özvektörü de içereceğiz;
Puanı matrisi matris çarpımı olarak tayin edildi ölçekli veriler ( X
göre) özvektör (veya "rotasyon") matrisi :
score_matrix <- X %*% e_vectors
# Identical to the often found operation: t(t(e_vectors) %*% t(X))
Konsept , her bir özvektörün sıralarının ağırlıklandırdığı ortalanmış (ve bu durumda ölçeklendirilmiş) verilerin her bir girişinin (bu durumda sıra / konu / gözlem / süper iletken) doğrusal bir kombinasyonunu gerektirir ; puanı matrisi, biz (tüm verilerin her bir değişken (sütun) bir katkı bulacaksınız ), ama sadece karşılık gelen özvektör (hesaplama yer almış olur yani birinci özvektör olacak katkıda (Ana Bileşen 1) ve için olduğu gibi,:X
PC[0.7,0.7]T[ 0.7 , - 0.7 ] T PCPC1[0.7,−0.7]TPC2
Bu nedenle, her bir özvektör, her değişkeni farklı şekilde etkileyecek ve bu, PCA'nın "yüklemelerine" yansıyacaktır. Bizim durumumuzda, ikinci özvektörün ikinci bileşenindeki negatif işaret, PC2'yi üreten doğrusal kombinasyonlardaki erime noktası değerlerinin işaretini değiştirecek, oysa birinci özvektörün etkisi sürekli olarak pozitif olacaktır: [0.7,−0.7]
Özvektörler ölçeklendirilir :1
> apply(e_vectors, 2, function(x) sum(x^2))
PC1 PC2
1 1
oysa ( yükler ) özdeğerler tarafından ölçeklendirilen özvektörlerdir (aşağıda gösterilen yerleşik R fonksiyonlarındaki kafa karıştırıcı terminolojiye rağmen). Sonuç olarak, yükler şu şekilde hesaplanabilir:
> e_vectors %*% lambda_matrix
[,1] [,2]
[1,] 0.9167086 0.497505
[2,] 0.9167086 -0.497505
> prcomp(X)$rotation %*% diag(princomp(covmat = C)$sd^2)
[,1] [,2]
atomic.no 0.9167086 0.497505
melting.point 0.9167086 -0.497505
Döndürülmüş veri bulutunun (puan grafiği) her bir bileşen (PC) boyunca özdeğerlere eşit olarak farklılık göstereceğini not etmek ilginçtir:
> apply(score_matrix, 2, function(x) var(x))
PC1 PC2
53829.7896 110.8414
> lambda
[1] 53829.7896 110.8414
Yerleşik işlevler kullanılarak sonuçlar tekrarlanabilir:
# For the SCORE MATRIX:
prcomp(X)$x
# or...
princomp(X)$scores # The signs of the PC 1 column will be reversed.
# and for EIGENVECTOR MATRIX:
prcomp(X)$rotation
# or...
princomp(X)$loadings
# and for EIGENVALUES:
prcomp(X)$sdev^2
# or...
princomp(covmat = C)$sd^2
Alternatif olarak, PCA'yı manuel olarak hesaplamak için tekil değer ayrıştırma ( ) yöntemi uygulanabilir; Aslında, bu kullanılan yöntemdir . Adımlar şöyle yazılabilir:UΣVTprcomp()
svd_scaled_dat <-svd(scale(dat1))
eigen_vectors <- svd_scaled_dat$v
eigen_values <- (svd_scaled_dat$d/sqrt(nrow(dat1) - 1))^2
scores<-scale(dat1) %*% eigen_vectors
Sonuç, ilk olarak, tek tek noktalardan birinci özvektöre olan mesafeler ve ikinci bir arsa üzerinde, ortogonal ikinci özvektöre olan uzaklıklar:
Bunun yerine, skor matrisinin (PC1 ve PC2) değerlerini çizersek - artık "melting.point" ve "atomic.no" değil, gerçekte özvektörlerle nokta koordinatlarının temelindeki bir değişiklik, bu mesafeler olacaktır. korunmuş, ancak doğal olarak xy eksenine dik olur:
Püf noktası şimdi orijinal verileri kurtarmaktı . Noktalar, özvektörler tarafından basit bir matris çarpımı ile dönüştürüldü. Şimdi veri, özvektörlerin matrisinin tersi ile çarpılarak veri noktalarının bulunduğu yerde meydana gelen belirgin bir değişiklik ile geri döndürüldü . Örneğin, sol üst kadrandaki (aşağıda soldaki siyah daire) pembe nokta "GaN" 'daki değişikliğe dikkat edin, sol alt kadrandaki ilk konumuna geri dönün (aşağıdaki sağdaki siyah daire).
Şimdi nihayet "döndürülmüş" matriste orijinal veriler geri yüklendi:
PCA'da verinin dönme koordinatlarının değişmesinin ötesinde, sonuçların yorumlanması gerekir ve bu işlem biplot
, yeni özvektör koordinatlarına göre veri noktalarının çizildiği ve orijinal değişkenlerin şimdi üst üste getirildiği bir a'yı içerir. vektörler. Yukarıdaki ikinci dönme grafik sırasındaki grafikler arasındaki noktaların pozisyonundaki denkliği not etmek ilginçtir ("xy Eksenli Skorlar = Özvektörler") (takip eden grafiklerde sola) ve biplot
( sağ):
Kırmızı oklar olarak orijinal değişkenlerin süperimpozisyon yorumlanması için bir yol sunar PC1
hem (pozitif korelasyon veya birlikte) yönde bir vektörü olarak atomic no
ve melting point
; ve PC2
artan değerlerin bir bileşeni olarak, atomic no
ancak melting point
özvektörlerin değerleriyle tutarlı olarak negatif bir korelasyon gösterir :
PCA$rotation
PC1 PC2
atomic.no 0.7071068 0.7071068
melting.point 0.7071068 -0.7071068
Victor Powell'ın bu etkileşimli öğreticisi , veri bulutu değiştirilirken özvektörlerdeki değişiklikler hakkında anında geri bildirim veriyor.