Я работаю в R с помощью превосходного учебника по PCA Линдси и Смита, и застреваю на последнем этапе. Сценарий R, приведенный ниже, выводит нас на этап (на стр.19), на котором исходные данные восстанавливаются из (в данном случае, единственного) основного компонента, который должен давать прямую линию вдоль оси PCA1 (учитывая, что данные имеет только 2 измерения, второе из которых намеренно отбрасывается).
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)
Это насколько я знаю, и пока все в порядке. Но я не могу понять, как данные получены для окончательного графика - дисперсия, относящаяся к PCA 1 - которую Смит готовит как:
Это то, что я пробовал (что игнорирует добавление оригинальных средств):
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)
.. и получил ошибочный
.. потому что я как-то потерял измерение данных в умножении матриц. Я был бы очень благодарен за идею, что здесь происходит не так.
* Редактировать *
Интересно, это правильная формула:
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')
Но я немного сбит с толку, если это так, потому что (а) я понимаю, что rowVectorFeature
необходимо уменьшить до желаемой размерности (собственный вектор для PCA1), и (b) он не совпадает с абзацем PCA1:
Любые мнения высоко ценятся.
s1
уклон был вычислен с ошибкой (должно быть , а не ), поэтому красная линия не идеально согласуется с данными на первом рисунке и с реконструкцией на последнем.