@ अमीबा और @ttnphns की पोस्ट पर विचार करें । आपकी मदद और विचारों दोनों के लिए धन्यवाद।
निम्नलिखित आर में आइरिस डेटासेट पर निर्भर करता है , और विशेष रूप से पहले तीन चर (कॉलम) Sepal.Length, Sepal.Width, Petal.Length
:।
एक बिप्लॉट एक लोडिंग प्लॉट (अनस्टेन्डाइज्ड आईजेनवेक्टर) को जोड़ती है - कंक्रीट में, पहले दो लोडिंग और एक स्कोर प्लॉट (प्रमुख घटकों के संबंध में प्लॉट किए गए और पतले डेटा बिंदु)। एक ही डेटासेट का उपयोग करते हुए, @amoeba पहले और दूसरे प्रमुख घटकों के स्कोर प्लॉट के 3 संभावित सामान्यीकरणों पर आधारित पीसीए बाइप्लॉट के 9 संभावित संयोजनों का वर्णन करता है , और प्रारंभिक चर के लोडिंग प्लॉट (तीर) के 3 सामान्यीकरण । यह देखने के लिए कि आर इन संभावित संयोजनों को कैसे संभालता है, यह biplot()
विधि को देखना दिलचस्प है :
पहले रेखीय बीजगणित कॉपी और पेस्ट करने के लिए तैयार:
X = as.matrix(iris[,1:3]) # Three first variables of Iris dataset
CEN = scale(X, center = T, scale = T) # Centering and scaling the data
PCA = prcomp(CEN)
# EIGENVECTORS:
(evecs.ei = eigen(cor(CEN))$vectors) # Using eigen() method
(evecs.svd = svd(CEN)$v) # PCA with SVD...
(evecs = prcomp(CEN)$rotation) # Confirming with prcomp()
# EIGENVALUES:
(evals.ei = eigen(cor(CEN))$values) # Using the eigen() method
(evals.svd = svd(CEN)$d^2/(nrow(X) - 1)) # and SVD: sing.values^2/n - 1
(evals = prcomp(CEN)$sdev^2) # with prcomp() (needs squaring)
# SCORES:
scr.svd = svd(CEN)$u %*% diag(svd(CEN)$d) # with SVD
scr = prcomp(CEN)$x # with prcomp()
scr.mm = CEN %*% prcomp(CEN)$rotation # "Manually" [data] [eigvecs]
# LOADINGS:
loaded = evecs %*% diag(prcomp(CEN)$sdev) # [E-vectors] [sqrt(E-values)]
1. लोडिंग प्लॉट (तीर) को पुन: प्रस्तुत करना:
यहाँ @ttnphns द्वारा इस पोस्ट पर ज्यामितीय व्याख्या बहुत मदद करती है। पोस्ट में आरेख की धारणा को बनाए रखा गया है: विषय स्थान में चर के लिए खड़ा है । अंत में प्लॉट किए गए संबंधित तीर है; और निर्देशांक और हैं घटक एक चर को और संबंध में लोड करते हैं :एच ' एक 1 एक 2 वी पीसी 1 पीसी 2VSepal L.
h′a1a2VPC1PC2
चर के घटक Sepal L.
के संबंध में तो हो जाएगा:PC1
a1=h⋅cos(ϕ)
जो, अगर स्कोर के संबंध में - चलो उन्हें फोन - ताकि मानकीकृत कर रहे हैं उनकेएस 1PC1S1
∥S1∥=∑n1scores21−−−−−−−−−√=1 , ऊपर दिया गया समीकरण डॉट उत्पाद के बराबर है :V⋅S1
a1=V⋅S1=∥V∥∥S1∥cos(ϕ)=h×1×⋅cos(ϕ)(1)
चूँकि ,∥V∥=∑x2−−−−√
Var(V)−−−−−√=∑x2−−−−√n−1−−−−−√=∥V∥n−1−−−−−√⟹∥V∥=h=var(V)−−−−−√n−1−−−−−√.
इसी तरह,
∥S1∥=1=var(S1)−−−−−√n−1−−−−−√.
वापस ईक पर जा रहे हैं। ,(1)
a1=h×1×⋅cos(ϕ)=var(V)−−−−−√var(S1)−−−−−√cos(θ)(n−1)
cos(ϕ) , इसलिए, माना जा सकता है एक पियर्सन की सहसंबंध गुणांक , , चेतावनी है कि मैं की शिकन समझ में नहीं आता के साथ कारक।rn−1
नीले रंग के लाल तीर में डुप्लिकेट और अतिव्यापी biplot()
par(mfrow = c(1,2)); par(mar=c(1.2,1.2,1.2,1.2))
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) # R biplot
# R biplot with overlapping (reproduced) arrows in blue completely covering red arrows:
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01)
arrows(0, 0,
cor(X[,1], scr[,1]) * 0.8 * sqrt(nrow(X) - 1),
cor(X[,1], scr[,2]) * 0.8 * sqrt(nrow(X) - 1),
lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
cor(X[,2], scr[,1]) * 0.8 * sqrt(nrow(X) - 1),
cor(X[,2], scr[,2]) * 0.8 * sqrt(nrow(X) - 1),
lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
cor(X[,3], scr[,1]) * 0.8 * sqrt(nrow(X) - 1),
cor(X[,3], scr[,2]) * 0.8 * sqrt(nrow(X) - 1),
lwd = 1, angle = 30, length = 0.1, col = 4)
रूचि के बिंदु:
- तीर को पहले दो प्रमुख घटकों द्वारा उत्पन्न अंकों के साथ मूल चर के सहसंबंध के रूप में पुन: पेश किया जा सकता है।
- वैकल्पिक रूप से, इसे दूसरी पंक्ति में पहले प्लॉट की तरह हासिल किया जा सकता है, @ अमीबा के पद में लेबल किया गया है :V∗S
या आर कोड में:
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) # R biplot
# R biplot with overlapping arrows in blue completely covering red arrows:
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01)
arrows(0, 0,
(svd(CEN)$v %*% diag(svd(CEN)$d))[1,1] * 0.8,
(svd(CEN)$v %*% diag(svd(CEN)$d))[1,2] * 0.8,
lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
(svd(CEN)$v %*% diag(svd(CEN)$d))[2,1] * 0.8,
(svd(CEN)$v %*% diag(svd(CEN)$d))[2,2] * 0.8,
lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
(svd(CEN)$v %*% diag(svd(CEN)$d))[3,1] * 0.8,
(svd(CEN)$v %*% diag(svd(CEN)$d))[3,2] * 0.8,
lwd = 1, angle = 30, length = 0.1, col = 4)
या अभी तक ...
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) # R biplot
# R biplot with overlapping (reproduced) arrows in blue completely covering red arrows:
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01)
arrows(0, 0,
(loaded)[1,1] * 0.8 * sqrt(nrow(X) - 1),
(loaded)[1,2] * 0.8 * sqrt(nrow(X) - 1),
lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
(loaded)[2,1] * 0.8 * sqrt(nrow(X) - 1),
(loaded)[2,2] * 0.8 * sqrt(nrow(X) - 1),
lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
(loaded)[3,1] * 0.8 * sqrt(nrow(X) - 1),
(loaded)[3,2] * 0.8 * sqrt(nrow(X) - 1),
lwd = 1, angle = 30, length = 0.1, col = 4)
@ttnphns , या इस अन्य जानकारीपूर्ण पोस्ट द्वारा @ttnphns द्वारा लोडिंग के ज्यामितीय स्पष्टीकरण के साथ जुड़ना ।
इसके अलावा, किसी को यह कहना चाहिए कि तीर को ऐसे प्लॉट किए गए हैं कि टेक्स्ट लेबल का केंद्र वह जगह है जहां यह होना चाहिए! तीर को फिर से साजिश रचने से पहले 0.80.8 से गुणा किया जाता है, यानी सभी तीर पाठ लेबल के साथ ओवरलैपिंग को रोकने के लिए संभवतया छोटे होते हैं, (biplot.default के लिए कोड देखें)। मुझे लगता है कि यह बहुत भ्रामक है। - अमीबा 19 मार्च को 10:06 बजे
2. प्लॉट biplot()
स्कोर (और तीर एक साथ):
कुल्हाड़ियों को इकाई के वर्ग योग में बढ़ाया जाता है , जो @ अमीबा के पद पर पहली पंक्ति के पहले भूखंड के समान होता है , जिसे svd अपघटन के मैट्रिक्स (बाद में) पर पुन: प्लॉट किया जा सकता है - " Columns of : ये मुख्य घटक हैं जो इकाई राशि के वर्ग में स्केल किए जाते हैं। "UU
बिप्लॉट निर्माण में नीचे और ऊपर क्षैतिज कुल्हाड़ियों पर खेलने के दो अलग-अलग पैमाने हैं:
हालांकि सापेक्ष पैमाने तुरंत स्पष्ट नहीं है, कार्यों और विधियों में देरी की आवश्यकता है:
biplot()
एसवीडी में कॉलम के रूप में प्लॉट स्कोर , जो ऑर्थोगोनल यूनिट वैक्टर हैं:U
> scr.svd = svd(CEN)$u %*% diag(svd(CEN)$d)
> U = svd(CEN)$u
> apply(U, 2, function(x) sum(x^2))
[1] 1 1 1
जबकि prcomp()
R में फ़ंक्शन उनके आइगेनवैल्यूज़ को प्राप्त स्कोर को लौटाता है:
> apply(scr, 2, function(x) var(x)) # pr.comp() scores scaled to evals
PC1 PC2 PC3
2.02142986 0.90743458 0.07113557
> evals #... here is the proof:
[1] 2.02142986 0.90743458 0.07113557
इसलिए हम eigenvalues द्वारा विभाजित करके से भिन्नता को माप सकते हैं:1
> scr_var_one = scr/sqrt(evals)[col(scr)] # to scale to var = 1
> apply(scr_var_one, 2, function(x) var(x)) # proved!
[1] 1 1 1
लेकिन चूंकि हम चाहते हैं कि वर्गों का योग , इसलिए हमें से विभाजित करना होगा क्योंकि:1n−1−−−−−√
var(scr_var_one)=1=∑n1scr_var_onen−1
> scr_sum_sqrs_one = scr_var_one / sqrt(nrow(scr) - 1) # We / by sqrt n - 1.
> apply(scr_sum_sqrs_one, 2, function(x) sum(x^2)) #... proving it...
PC1 PC2 PC3
1 1 1
ध्यान दें कि स्केलिंग फैक्टर , बाद में बदलकर पर कर दिया जाता है, जब स्पष्टीकरण को परिभाषित करना इस तथ्य में झूठ लगता है किn−1−−−−−√n−−√lan
prcomp
का उपयोग करता है : "प्रिंट के विपरीत, variances की गणना सामान्य भाजक साथ की जाती है "।n−1n−1
उन्हें सभी if
बयानों और अन्य घर biplot()
वापसी के फुलाने के बाद, निम्नानुसार आगे बढ़ता है:
X = as.matrix(iris[,1:3]) # The original dataset
CEN = scale(X, center = T, scale = T) # Centered and scaled
PCA = prcomp(CEN) # PCA analysis
par(mfrow = c(1,2)) # Splitting the plot in 2.
biplot(PCA) # In-built biplot() R func.
# Following getAnywhere(biplot.prcomp):
choices = 1:2 # Selecting first two PC's
scale = 1 # Default
scores= PCA$x # The scores
lam = PCA$sdev[choices] # Sqrt e-vals (lambda) 2 PC's
n = nrow(scores) # no. rows scores
lam = lam * sqrt(n) # See below.
# at this point the following is called...
# biplot.default(t(t(scores[,choices]) / lam),
# t(t(x$rotation[,choices]) * lam))
# Following from now on getAnywhere(biplot.default):
x = t(t(scores[,choices]) / lam) # scaled scores
# "Scores that you get out of prcomp are scaled to have variance equal to
# the eigenvalue. So dividing by the sq root of the eigenvalue (lam in
# biplot) will scale them to unit variance. But if you want unit sum of
# squares, instead of unit variance, you need to scale by sqrt(n)" (see comments).
# > colSums(x^2)
# PC1 PC2
# 0.9933333 0.9933333 # It turns out that the it's scaled to sqrt(n/(n-1)),
# ...rather than 1 (?) - 0.9933333=149/150
y = t(t(PCA$rotation[,choices]) * lam) # scaled eigenvecs (loadings)
n = nrow(x) # Same as dataset (150)
p = nrow(y) # Three var -> 3 rows
# Names for the plotting:
xlabs = 1L:n
xlabs = as.character(xlabs) # no. from 1 to 150
dimnames(x) = list(xlabs, dimnames(x)[[2L]]) # no's and PC1 / PC2
ylabs = dimnames(y)[[1L]] # Iris species
ylabs = as.character(ylabs)
dimnames(y) <- list(ylabs, dimnames(y)[[2L]]) # Species and PC1/PC2
# Function to get the range:
unsigned.range = function(x) c(-abs(min(x, na.rm = TRUE)),
abs(max(x, na.rm = TRUE)))
rangx1 = unsigned.range(x[, 1L]) # Range first col x
# -0.1418269 0.1731236
rangx2 = unsigned.range(x[, 2L]) # Range second col x
# -0.2330564 0.2255037
rangy1 = unsigned.range(y[, 1L]) # Range 1st scaled evec
# -6.288626 11.986589
rangy2 = unsigned.range(y[, 2L]) # Range 2nd scaled evec
# -10.4776155 0.8761695
(xlim = ylim = rangx1 = rangx2 = range(rangx1, rangx2))
# range(rangx1, rangx2) = -0.2330564 0.2255037
# And the critical value is the maximum of the ratios of ranges of
# scaled e-vectors / scaled scores:
(ratio = max(rangy1/rangx1, rangy2/rangx2))
# rangy1/rangx1 = 26.98328 53.15472
# rangy2/rangx2 = 44.957418 3.885388
# ratio = 53.15472
par(pty = "s") # Calling a square plot
# Plotting a box with x and y limits -0.2330564 0.2255037
# for the scaled scores:
plot(x, type = "n", xlim = xlim, ylim = ylim) # No points
# Filling in the points as no's and the PC1 and PC2 labels:
text(x, xlabs)
par(new = TRUE) # Avoids plotting what follows separately
# Setting now x and y limits for the arrows:
(xlim = xlim * ratio) # We multiply the original limits x ratio
# -16.13617 15.61324
(ylim = ylim * ratio) # ... for both the x and y axis
# -16.13617 15.61324
# The following doesn't change the plot intially...
plot(y, axes = FALSE, type = "n",
xlim = xlim,
ylim = ylim, xlab = "", ylab = "")
# ... but it does now by plotting the ticks and new limits...
# ... along the top margin (3) and the right margin (4)
axis(3); axis(4)
text(y, labels = ylabs, col = 2) # This just prints the species
arrow.len = 0.1 # Length of the arrows about to plot.
# The scaled e-vecs are further reduced to 80% of their value
arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8,
length = arrow.len, col = 2)
जैसा कि अपेक्षित था, biplot()
आउटपुट (नीचे दी गई छवि), जैसा कि biplot(PCA)
इसके सभी अछूते सौंदर्य संबंधी कमियों में सीधे (बाएं प्लॉट से नीचे) आउटपुट कहा जाता है :
रूचि के बिंदु:
- तीर दो प्रमुख घटकों और उनके संबंधित स्केल किए गए अंकों (
ratio
) में से हर एक के स्केल किए गए आइजन्वेक्टर के बीच अधिकतम अनुपात से संबंधित पैमाने पर प्लॉट किए जाते हैं । AS @amoeba टिप्पणी:
स्कैटर प्लॉट और "एरो प्लॉट" को ऐसे स्केल किया जाता है कि सबसे बड़ा (निरपेक्ष मान में) x या y एरो कोआर्डिनेशन एरो के बराबर होता है (बिखरे हुए डेटा पॉइंट्स का x या y कोऑर्डिनेशन)
- जैसा कि ऊपर अनुमान है, अंक सीधे SVD के मैट्रिक्स में स्कोर के रूप में दिए जा सकते हैं :U