इस धागे में जेडी लॉन्ग द्वारा उत्कृष्ट पोस्ट के बाद, मैंने एक साधारण उदाहरण के लिए देखा, और पीसीए का उत्पादन करने के लिए आवश्यक आर कोड और फिर मूल डेटा पर वापस जाएं। इसने मुझे कुछ पहली-हाथ की ज्यामितीय अंतर्ज्ञान दिया, और जो मुझे मिला उसे साझा करना चाहता हूं। डेटासेट और कोड को सीधे R फॉर्म Github में कॉपी और पेस्ट किया जा सकता है ।
मैंने एक डेटा सेट का उपयोग किया जो मुझे यहां अर्धचालक पर ऑनलाइन मिला , और मैंने इसे प्लॉटिंग की सुविधा के लिए केवल दो आयामों - "परमाणु संख्या" और "गलनांक" के लिए ट्रिम किया।
एक चेतावनी के रूप में विचार विशुद्ध रूप से कम्प्यूटेशनल प्रक्रिया का उदाहरण है: पीसीए का उपयोग कुछ व्युत्पन्न प्रमुख घटकों के लिए दो से अधिक चर को कम करने के लिए किया जाता है, या कई विशेषताओं के मामले में भी संपार्श्विकता की पहचान करने के लिए किया जाता है। तो यह दो चर के मामले में अधिक आवेदन नहीं मिलेगा, और न ही सहसंबंध matrices के eigenvectors की गणना करने की आवश्यकता होगी जैसा कि @amoeba द्वारा बताया गया है।
इसके अलावा, मैंने व्यक्तिगत बिंदुओं पर नज़र रखने के कार्य को आसान बनाने के लिए 44 से 15 तक टिप्पणियों को काट दिया। अंतिम परिणाम एक कंकाल डेटा फ्रेम ( dat1
) था:
compounds atomic.no melting.point
AIN 10 498.0
AIP 14 625.0
AIAs 23 1011.5
... ... ...
"यौगिक" कॉलम अर्धचालक के रासायनिक संविधान को इंगित करता है, और पंक्ति नाम की भूमिका निभाता है।
इसे निम्नानुसार पुन: प्रस्तुत किया जा सकता है (आर कंसोल पर कॉपी और पेस्ट करने के लिए तैयार):
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]
डेटा को तब स्केल किया गया था:
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)`
रैखिक बीजगणित चरणों का पालन किया:
C <- cov(X) # Covariance matrix (centered data)
⎡⎣⎢at_nomelt_pat_no10.296melt_p0.2961⎤⎦⎥
सहसंबंध फ़ंक्शन cor(dat1)
गैर-स्केल किए गए डेटा पर समान आउटपुट देता है जो स्केल किए गए डेटा 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⎤⎦⎥
चूंकि पहला ईजनवेक्टर शुरू में लौटता है ~ [ - 0.7 , - 0.7 ] हम इसे बदलने के लिए चुनते हैं [ 0.7 , 0.7 ] इसके माध्यम से अंतर्निहित सूत्रों के अनुरूप बनाने के लिए:
e_vectors[,1] = - e_vectors[,1]; colnames(e_vectors) <- c("PC1","PC2")
परिणामी प्रतिजन थे 1.2964217 तथा 0.7035783। कम से कम न्यूनतर परिस्थितियों में, इस परिणाम से यह तय करने में मदद मिली कि कौन-से eigenvectors शामिल हैं (सबसे बड़े eigenvalues)। मिसाल के तौर पर, पहले के स्वदेशी का सापेक्ष योगदान है64.8 %: eigen(C)$values[1]/sum(eigen(C)$values) * 100
, जिसका अर्थ है कि यह हिसाब करता है∼ 65 %डेटा में परिवर्तनशीलता की। दूसरी ईजनवेक्टर की दिशा में परिवर्तनशीलता है35.2 %। यह आमतौर पर एक स्क्री प्लॉट पर दिखाया जाता है जो आइजेनवेल्स के मान को दर्शाता है:
हम दोनों eigenvectors इस खिलौना डेटा सेट उदाहरण के छोटे आकार को देखते हुए शामिल करेंगे, यह समझते हुए कि एक eigenvectors को छोड़कर आयामीता में कमी आएगी - PCA के पीछे का विचार।
स्कोर मैट्रिक्स का आव्यूह गुणन के रूप में निर्धारित किया गया था बढ़ाया डेटा ( X
) द्वारा eigenvectors (या "रोटेशन") का मैट्रिक्स :
score_matrix <- X %*% e_vectors
# Identical to the often found operation: t(t(e_vectors) %*% t(X))
अवधारणा केन्द्रित (और इस मामले में स्केल किए गए) डेटा की प्रत्येक प्रविष्टि (पंक्ति / विषय / अवलोकन / सुपरकंडक्टर) के एक रेखीय संयोजन को प्रत्येक आइजेनवेक्टर की पंक्तियों द्वारा भारित करती है , ताकि अंतिम प्रत्येक कॉलम में स्कोर मैट्रिक्स, हम डेटा (प्रत्येक) के प्रत्येक चर (कॉलम) से योगदान पाएंगे X
, लेकिन केवल संबंधित आइजनवेक्टर ने गणना में भाग लिया होगा (अर्थात पहला ईजनवेक्टर[ 0.7 , 0.7 ]टी में योगदान देगा पीसी1 (प्रमुख घटक 1) और [ 0.7 , - 0.7 ]टी सेवा पीसी2, जैसे की:
इसलिए प्रत्येक eigenvector प्रत्येक चर को अलग तरह से प्रभावित करेगा, और यह पीसीए के "लोडिंग" में परिलक्षित होगा। हमारे मामले में, दूसरे आइजनवेक्टर के दूसरे घटक में नकारात्मक संकेत[ 0.7 , - 0.7 ] PC2 का निर्माण करने वाले रैखिक संयोजनों में पिघलने बिंदु मानों के संकेत को बदल देगा, जबकि पहले eigenvector का प्रभाव लगातार सकारात्मक होगा:
आइजनवेक्टरों को बढ़ाया जाता है 1:
> apply(e_vectors, 2, function(x) sum(x^2))
PC1 PC2
1 1
जबकि ( लोडिंग ) आइगेनवैल्यूज़ द्वारा स्केल किए गए आइगेनवेक्टर हैं (इन-बिल्ट आर कार्यों में भ्रमित शब्दावली के बावजूद)। नतीजतन, लोडिंग की गणना इस प्रकार की जा सकती है:
> 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
यह ध्यान रखना दिलचस्प है कि घुमाए गए डेटा क्लाउड (स्कोर प्लॉट) में प्रत्येक घटक (पीसी) के साथ विचरण के बराबर विचरण होगा:
> apply(score_matrix, 2, function(x) var(x))
PC1 PC2
53829.7896 110.8414
> lambda
[1] 53829.7896 110.8414
अंतर्निहित कार्यों का उपयोग करके परिणामों को दोहराया जा सकता है:
# 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
वैकल्पिक रूप से, एकवचन मान अपघटन (यू Σ वीटी) पीसीए को मैन्युअल रूप से गणना करने के लिए विधि लागू किया जा सकता है; वास्तव में, यह प्रयोग की जाने वाली विधि है prcomp()
। इस कदम के रूप में वर्तनी की जा सकती है:
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
परिणाम नीचे दिखाया गया है, पहले के साथ, व्यक्तिगत अंक से पहले आइजन्वेक्टर की दूरी, और दूसरे प्लॉट पर, दूसरे आइगेनवेक्टर के लिए ऑर्थोगोनल की दूरी:
यदि इसके बजाय हमने स्कोर मैट्रिक्स (PC1 और PC2) के मानों को प्लॉट किया - अब "मेल्टिंग.पॉइंट" और "एटॉमिक.नो" नहीं है, लेकिन वास्तव में पॉइंट के आधार का एक परिवर्तन eigenvectors के साथ आधार के रूप में समन्वय करता है, तो ये दूरी दूर होंगी। संरक्षित, लेकिन स्वाभाविक रूप से xy अक्ष के लंबवत हो जाएगा:
मूल डेटा को पुनर्प्राप्त करने के लिए चाल थी । अंक एक सरल मैट्रिक्स गुणा के माध्यम से eigenvectors द्वारा बदल दिए गए थे। अब डेटा बिंदुओं के स्थान में परिणामी परिवर्तन के साथ eigenvectors के मैट्रिक्स के व्युत्क्रम से गुणा करके डेटा को वापस घुमाया गया था । उदाहरण के लिए, बाएँ ऊपरी वृत्त का चतुर्थ भाग (नीचे वाले भूखंड में काला वृत्त) में गुलाबी बिंदु "GaN" में परिवर्तन देखें, बाएँ निचले वृत्त का चतुर्थ भाग में अपनी प्रारंभिक स्थिति में लौट रहे हैं (दाएँ भूखंड में काला वृत्त, नीचे)।
अब हम अंत में इस "डी-रोटेटेड" मैट्रिक्स में मूल डेटा को बहाल कर चुके थे:
पीसीए में डेटा के रोटेशन के निर्देशांक के परिवर्तन से परे, परिणामों की व्याख्या की जानी चाहिए, और इस प्रक्रिया में एक शामिल है biplot
, जिस पर डेटा बिंदुओं को नए eigenvector निर्देशांक के संबंध में प्लॉट किया जाता है, और मूल चर को अब बदल दिया जाता है। वैक्टर। उपरोक्त रोटेशन ग्राफ़ की दूसरी पंक्ति में भूखंडों के बीच बिंदुओं की स्थिति में समानता को ध्यान में रखना दिलचस्प है ("xy एक्सिस = आइगेनवेक्टर्स के साथ स्कोर") (भूखंडों में बाईं ओर जो अनुसरण करते हैं), और biplot
(- से ) सही):
लाल तीर के रूप में मूल चर के superimposition की व्याख्या करने के लिए एक रास्ता प्रदान करता है PC1
दोनों के साथ दिशा (एक सकारात्मक संबंध या के साथ) में एक वेक्टर के रूप में atomic no
और melting point
; और PC2
एक घटक के रूप में, atomic no
लेकिन नकारात्मक रूप से सहसंबद्ध के बढ़ते मूल्यों के साथ melting point
, आइजनवेक्टर के मूल्यों के अनुरूप है:
PCA$rotation
PC1 PC2
atomic.no 0.7071068 0.7071068
melting.point 0.7071068 -0.7071068
विक्टर पॉवेल का यह इंटरएक्टिव ट्यूटोरियल डेटा क्लाउड को संशोधित करने के रूप में आइजनवेक्टर में बदलाव के रूप में तत्काल प्रतिक्रिया देता है।