Je travaille dans R grâce à un excellent tutoriel PCA par Lindsay I Smith et je suis coincé dans la dernière étape. Le script R ci-dessous nous amène à l'étape (à la p.19) où les données originales sont reconstruites à partir de la composante principale (singulière dans ce cas), ce qui devrait produire un tracé en ligne droite le long de l'axe PCA1 (étant donné que les données n'a que 2 dimensions, dont la seconde est intentionnellement supprimée).
d = data.frame(x=c(2.5,0.5,2.2,1.9,3.1,2.3,2.0,1.0,1.5,1.1),
y=c(2.4,0.7,2.9,2.2,3.0,2.7,1.6,1.1,1.6,0.9))
# mean-adjusted values
d$x_adj = d$x - mean(d$x)
d$y_adj = d$y - mean(d$y)
# calculate covariance matrix and eigenvectors/values
(cm = cov(d[,1:2]))
#### outputs #############
# x y
# x 0.6165556 0.6154444
# y 0.6154444 0.7165556
##########################
(e = eigen(cm))
##### outputs ##############
# $values
# [1] 1.2840277 0.0490834
#
# $vectors
# [,1] [,2]
# [1,] 0.6778734 -0.7351787
# [2,] 0.7351787 0.6778734
###########################
# principal component vector slopes
s1 = e$vectors[1,1] / e$vectors[2,1] # PC1
s2 = e$vectors[1,2] / e$vectors[2,2] # PC2
plot(d$x_adj, d$y_adj, asp=T, pch=16, xlab='x', ylab='y')
abline(a=0, b=s1, col='red')
abline(a=0, b=s2)
# PCA data = rowFeatureVector (transposed eigenvectors) * RowDataAdjust (mean adjusted, also transposed)
feat_vec = t(e$vectors)
row_data_adj = t(d[,3:4])
final_data = data.frame(t(feat_vec %*% row_data_adj)) # ?matmult for details
names(final_data) = c('x','y')
#### outputs ###############
# final_data
# x y
# 1 0.82797019 -0.17511531
# 2 -1.77758033 0.14285723
# 3 0.99219749 0.38437499
# 4 0.27421042 0.13041721
# 5 1.67580142 -0.20949846
# 6 0.91294910 0.17528244
# 7 -0.09910944 -0.34982470
# 8 -1.14457216 0.04641726
# 9 -0.43804614 0.01776463
# 10 -1.22382056 -0.16267529
############################
# final_data[[1]] = -final_data[[1]] # for some reason the x-axis data is negative the tutorial's result
plot(final_data, asp=T, xlab='PCA 1', ylab='PCA 2', pch=16)
C'est aussi loin que j'ai, et tout va bien jusqu'à présent. Mais je ne peux pas comprendre comment les données sont obtenues pour le tracé final - la variance attribuable à l'ACP 1 - que Smith trace comme:
Voici ce que j'ai essayé (qui ignore l'ajout des moyens d'origine):
trans_data = final_data
trans_data[,2] = 0
row_orig_data = t(t(feat_vec[1,]) %*% t(trans_data))
plot(row_orig_data, asp=T, pch=16)
.. et a obtenu une erreur:
.. parce que j'ai perdu une dimension de données d'une manière ou d'une autre dans la multiplication matricielle. Je serais très reconnaissant d'avoir une idée de ce qui ne va pas ici.
* Éditer *
Je me demande si c'est la bonne formule:
row_orig_data = t(t(feat_vec) %*% t(trans_data))
plot(row_orig_data, asp=T, pch=16, cex=.5)
abline(a=0, b=s1, col='red')
Mais je suis un peu confus si oui car (a) je comprends les rowVectorFeature
besoins à réduire à la dimensionnalité souhaitée (le vecteur propre pour PCA1), et (b) il ne correspond pas à l'abline PCA1:
Toutes vues très appréciées.
s1