Как выполнить уменьшение размерности с PCA в R

30

У меня большой набор данных, и я хочу уменьшить размерность.

Сейчас везде читаю, что могу использовать для этого PCA. Тем не менее, я все еще не понимаю, что делать после вычисления / выполнения PCA. В R это легко сделать с помощью команды princomp.

Но что делать после расчета СПС? Если я решил, что хочу использовать первые основных компонентов, как мне точно сократить мой набор данных?100

Флорис Девриендт
источник
Этот вопрос не очень ясен (100 компьютеров - это ваш набор данных с уменьшенной размерностью), но конкретно о восстановлении исходных переменных (тема принятого ответа) см. Также: Как отменить PCA и восстановить исходные переменные из нескольких основных компонентов?
говорит амеба: восстанови Монику

Ответы:

35

Я полагаю, что то, что вы получаете в своем вопросе, касается усечения данных с использованием меньшего числа основных компонентов (ПК). Для таких операций, я думаю, эта функция prcompболее наглядна, так как проще визуализировать умножение матриц, использованное при реконструкции.

Во-первых, дайте синтетический набор данных, Xtвы выполняете PCA (обычно вы центрируете выборки, чтобы описать ПК, относящиеся к ковариационной матрице:

#Generate data
m=50
n=100
frac.gaps <- 0.5 # the fraction of data with NaNs
N.S.ratio <- 0.25 # the Noise to Signal ratio for adding noise to data

x <- (seq(m)*2*pi)/m
t <- (seq(n)*2*pi)/n

#True field
Xt <- 
 outer(sin(x), sin(t)) + 
 outer(sin(2.1*x), sin(2.1*t)) + 
 outer(sin(3.1*x), sin(3.1*t)) +
 outer(tanh(x), cos(t)) + 
 outer(tanh(2*x), cos(2.1*t)) + 
 outer(tanh(4*x), cos(0.1*t)) + 
 outer(tanh(2.4*x), cos(1.1*t)) + 
 tanh(outer(x, t, FUN="+")) + 
 tanh(outer(x, 2*t, FUN="+"))

Xt <- t(Xt)

#PCA
res <- prcomp(Xt, center = TRUE, scale = FALSE)
names(res)

В результатах или prcompвы можете видеть ПК ( res$x), собственные значения ( res$sdev), дающие информацию о величине каждого ПК и нагрузках ( res$rotation).

res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)

Возводя в квадрат собственные значения, вы получаете дисперсию, объясняемую каждым компьютером:

plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance

Наконец, вы можете создать усеченную версию ваших данных, используя только ведущие (важные) ПК:

pc.use <- 3 # explains 93% of variance
trunc <- res$x[,1:pc.use] %*% t(res$rotation[,1:pc.use])

#and add the center (and re-scale) back to data
if(res$scale != FALSE){
	trunc <- scale(trunc, center = FALSE , scale=1/res$scale)
}
if(res$center != FALSE){
    trunc <- scale(trunc, center = -1 * res$center, scale=FALSE)
}
dim(trunc); dim(Xt)

Вы можете видеть, что в результате получается немного более гладкая матрица данных с отфильтрованными мелкими объектами:

RAN <- range(cbind(Xt, trunc))
BREAKS <- seq(RAN[1], RAN[2],,100)
COLS <- rainbow(length(BREAKS)-1)
par(mfcol=c(1,2), mar=c(1,1,2,1))
image(Xt, main="Original matrix", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()
image(trunc, main="Truncated matrix (3 PCs)", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()

введите описание изображения здесь

И вот очень простой подход, который вы можете использовать вне функции prcomp:

#alternate approach
Xt.cen <- scale(Xt, center=TRUE, scale=FALSE)
C <- cov(Xt.cen, use="pair")
E <- svd(C)
A <- Xt.cen %*% E$u

#To remove units from principal components (A)
#function for the exponent of a matrix
"%^%" <- function(S, power)
     with(eigen(S), vectors %*% (values^power * t(vectors)))
Asc <- A %*% (diag(E$d) %^% -0.5) # scaled principal components

#Relationship between eigenvalues from both approaches
plot(res$sdev^2, E$d) #PCA via a covariance matrix - the eigenvalues now hold variance, not stdev
abline(0,1) # same results

Теперь решение о том, какие ПК оставить, - это отдельный вопрос, который меня интересовал некоторое время назад . Надеюсь, это поможет.

Марк в коробке
источник
2
Марк, тебе не нужно явно записывать центр и масштабировать, это prcompделает для тебя. Посмотрите на res$centerи res$scale. ИМХО, они менее подвержены ошибкам (нет случайных различий относительно центрирования или нет / масштабирования или нет между явным вызовом scaleи prcompвызовом).
cbeleites поддерживает Монику
1
Этот ответ нуждается в расширении, потому что он не отвечает на вопросы ОП о what to do after calculating the PCAили how do I reduce my dataset exactly? Учитывая, что ОП провел PCA на своем образце, его вопрос состоит в том, что с ним делать, и что на самом деле происходит с этими подвыборками; не как делать спс. Мы могли бы также предложить сделать E <- eigen(cov(Sample)); A<- scale(scale=F, Sample) %*% E$vectorsеще один способ получить оценки (что на самом деле и делает princomp stats:::princomp.default).
usεr11852 говорит восстановить Monic
1
@ user11852 - в вопросе конкретно упоминается сокращение набора данных (то есть усечение, которое я продемонстрировал здесь). Я оставлю это на его усмотрение, чтобы решить, было ли это то, что он искал.
Марк в коробке
1
@Marc, спасибо за ответ. Я думаю, что мне, возможно, придется сделать шаг назад и перечитать все заново, потому что я застрял на том, как любой из ответов выше имеет дело с уменьшением размерности. Потому что, как вы показываете, dim (trunc) = dim (Xt). Какая польза от этого, размеры не уменьшались.
B_Miner
2
@B_Miner - просто имейте в виду, что усечение используется для фокусировки на основных шаблонах в данных и для фильтрации мелкомасштабных шаблонов и шума. Усеченные данные не меньше по своим размерам, но и «чище». Однако усечение сокращает объем данных, поскольку вся матрица может быть восстановлена ​​с помощью всего нескольких векторов. Хорошим примером является использование PCA для сжатия изображений, когда для реконструкции изображения можно использовать меньшее количество компьютеров. Это меньшее подмножество векторов занимает меньше памяти, но реконструкция будет иметь некоторые потери в мелкомасштабных деталях.
Марк в коробке
3

Эти другие ответы очень хорошие и подробные, но мне интересно, действительно ли вы задаете гораздо более простой вопрос: что вы делаете, когда у вас есть ПК?

Каждый ПК просто становится новой переменной. Скажем, ПК1 составляет 60% от общего отклонения, а ПК2 - 30%. Поскольку это составляет 90% от общей вариации, вы можете просто принять эти две новые переменные (ПК) в качестве упрощенной версии ваших исходных переменных. Это означает подгонку их к моделям, если это то, что вас интересует. Когда приходит время интерпретировать ваши результаты, вы делаете это в контексте исходных переменных, которые коррелируют с каждым ПК.

Извините, если я недооценил суть вопроса!

atrichornis
источник
2

iλiΣk=1pλkpp=784λ

Практически с PCA вы используете прогнозы ПК («баллы») в качестве суррогатных данных для вашего исходного образца. Вы делаете весь свой анализ на счетах, и после этого вы восстанавливаете свой оригинальный образец, используя ПК, чтобы выяснить, что произошло на вашем первоначальном пространстве (это в основном регрессия основных компонентов ). Ясно, что если вы в состоянии осмысленно интерпретировать свои собственные векторы («нагрузки»), то вы находитесь в еще лучшем положении: вы можете описать, что происходит с вашей выборкой в ​​режиме изменения, представленном этой загрузкой, сделав непосредственный вывод об этой загрузке и не заботиться о реконструкции вообще. :)

В общем, что вы «после расчета PCA» зависит от цели вашего анализа. PCA просто дает вам линейно независимую подвыборку ваших данных, которая является оптимальной по критерию реконструкции RSS. Вы можете использовать его для классификации, или регрессии, или для того и другого, или, как я уже упоминал, вы можете распознавать значимые ортогональные варианты вариаций в вашей выборке.

Комментарий : я думаю, что лучший наивный способ определить количество компонентов, которые следует сохранить, - это основывать свою оценку на некотором пороге изменения выборки, который вы хотели бы сохранить в своей выборке с уменьшенной размерностью, а не на каком-то произвольном числе, например. 3, 100, 200. Как объяснил пользователь 4959, вы можете проверить это кумулятивное отклонение, проверив соответствующее поле списка под $loadingsполем в объекте списка, созданного princomp.

usεr11852 говорит восстановить Monic
источник
1
Как вы упомянули регрессию главных компонентов, в R это предоставляется пакетом PLS. Что касается количества сохраняемых компонентов, я не вижу реального преимущества в определении% дисперсии по сравнению с нет. компонентов (возможно, это связано с тем, что я работаю с данными, которые имеют очень разные уровни шума. Как упоминает @ Marc-in-the-box, существует множество различных подходов для определения подходящего количества ПК, и стратегия будет ( должен) зависеть как от типа данных, так и от типа последующего анализа данных
cbeleites поддерживает Monica
plsprincomp {stats}KKDD
1
да, это наивно. Я не согласен с тем, что установка произвольного% объясненной дисперсии имеет внутреннее преимущество по сравнению с любым другим произвольным отсечением. Но в любом случае не стоит с этим бороться, поскольку а) ОП никогда не спрашивал совета по поводу выбора «нет». ПК и б) я думаю, мы согласны с тем, что в любом случае следует провести надлежащую проверку модели СПС.
cbeleites поддерживает Монику
Нет проблем; это был только комментарий, который я сделал перед тем, как ответить. (Я поставлю свой абзац комментария последним, так как думаю, что это
сбивает с толку,
0

После выполнения PCA вы можете выбрать первые два компонента и построить график. Вы можете увидеть изменение компонентов, используя график осыпания в R. Кроме того, используя функцию итога с loadings = T, вы можете связать изменение компонентов с компонентами.

Вы также можете посмотреть эти http://www.statmethods.net/advstats/factor.html и http://statmath.wu.ac.at/~hornik/QFS1/principal_component-vignette.pdf

Попробуй думать, что ты хочешь. Вы можете интерпретировать многое из анализа PCA.

Лучший Абхик

user4959
источник