Действительно ли компоненты PCA представляют собой процент дисперсии? Могут ли они составить более 100%?

13

«Машинное обучение для хакеров» О'Рейли говорит, что каждый основной компонент представляет собой процент дисперсии. Я процитировал соответствующую часть страницы ниже (глава 8, с.207). Говоря с другим экспертом, они согласились, что это процент.

Однако 24 компонента составляют 133,2095%. Как это может быть?

Убедившись в том, что мы можем использовать PCA, как мы это делаем в R? Опять же, это место, где R сияет: весь PCA может быть сделан в одной строке кода. Мы используем функцию princomp для запуска PCA:

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])

Если мы просто введем pca в R, мы увидим краткое описание основных компонентов:

Call:
princomp(x = date.stock.matrix[, 2:ncol(date.stock.matrix)])
Standard deviations:
Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6 Comp.7
29.1001249 20.4403404 12.6726924 11.4636450 8.4963820 8.1969345 5.5438308
Comp.8 Comp.9 Comp.10 Comp.11 Comp.12 Comp.13 Comp.14
5.1300931 4.7786752 4.2575099 3.3050931 2.6197715 2.4986181 2.1746125
Comp.15 Comp.16 Comp.17 Comp.18 Comp.19 Comp.20 Comp.21
1.9469475 1.8706240 1.6984043 1.6344116 1.2327471 1.1280913 0.9877634
Comp.22 Comp.23 Comp.24
0.8583681 0.7390626 0.4347983
24 variables and 2366 observations.

В этом обзоре стандартные отклонения говорят нам, сколько из дисперсии в наборе данных приходится на различные основные компоненты. На первый компонент, называемый Comp.1, приходится 29% дисперсии, в то время как на следующий компонент приходится 20%. К концу, последний компонент, Comp.24, составляет менее 1% дисперсии. Это говорит о том, что мы можем многое узнать о наших данных, просто взглянув на первый основной компонент.

[Код и данные можно найти на github .]

Даррен Кук
источник
6
Я думаю, что авторская интерпретация Standard deviationsслегка отклонена. Поскольку стандартные отклонения на самом деле являются стандартными отклонениями, мы должны возвести их в квадрат, чтобы увидеть, какова дисперсия каждого компонента. Первый компонент будет представлять процента от общей дисперсии. 100×29.1001249229.10012492++0.43479832
принято нормальным
4
Боюсь, этот вопрос возникает из-за двух основных ошибок: (1) он пропускает заголовок, объявляющий, что числа являются «стандартными отклонениями», и ошибочно принимает их за отклонения, и (2) он предполагает, что эти числа являются процентами, но это не так. (Их единицы - это то, в чем измеряются акции: доллары или процентное изменение в год или что-то в этом роде.) Здесь нет никакой ошибки: комментарий @Max объясняет, как найти процент от общей дисперсии.
whuber
1
@whuber Может быть, я должен был использовать «опечатка» вместо «ошибка»? :-) " Comp.1, составляет 29% дисперсии " неправильно и должен читать " Comp.1, составляет 46% дисперсии "
Даррен Кук
1
Спасибо, Даррен: я неправильно понял, что в книге была путаница, и я взял «ошибку», чтобы сослаться на само Rпрограммное обеспечение. Обнаружение этой ошибки было хорошим уловом (надеюсь, вам было полезно узнать, что на самом деле происходит с PCA)!
whuber
5
Да, это, несомненно, ошибка в книге. Есть несколько мест, где я неправильно использовал стандартные отклонения вместо отклонений. (Например, есть точка, в которой мы используем RMSE вместо MSE для вычисления R-квадрата.) Я надеюсь, что у нас будет время сесть и исправить подобные ошибки в ближайшем будущем.
Джон Майлс Уайт

Ответы:

11

Используйте summary.princompдля просмотра «Соотношение дисперсии» и «Совокупное соотношение».

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])
summary(pca)
Джошуа Ульрих
источник
1
Спасибо, Джошуа. Таким образом, первый компонент на самом деле составляет 46% дисперсии. Я отправлю отчет об ошибке в книгу.
Даррен Кук
Как рассчитывается «коэффициент дисперсии»? Показанное число составляет 0,4600083. Но sqrt(pca$sdev[1]/sum(pca$sdev))(примерно sqrt(29.1/133.2)) дает 0,4673904.
Даррен Кук
3
@DarrenCook: sdevподразумевает, что вы смотрите на стандартное отклонение , то есть квадратный корень из дисперсии (или , используя обозначения из моего ответа), который должен объяснить разницу. Попробуйвместо этого. λяpca$sdev[1]^2/sum(pca$sdev^2)
MånsT
2
@DarrenCook: использовать источник ... stats:::print.summary.princompпоказывает, что он возводит в квадрат sdevкомпонент, который stats:::princomp.defaultпоказывает это sqrtиз собственных значений.
Джошуа Ульрих
11

Они должны составить до 100 %,

Полная дисперсия вариативной случайной величины X с ковариационной матрицей Σ определяется как t r ( Σ ) = σ 11 + σ 22 + + σ p p .пИксΣ

Tр(Σ)знак равноσ11+σ22++σпп,

Теперь след симметричной матрицы является суммой ее собственных значений Таким образом, полная дисперсия равна t r ( Σ ) = λ 1 + + λ p, если мы используем λ i для обозначения собственных значений Σ . Обратите внимание, что λ p0, поскольку ковариационные матрицы положительно-полуопределены , поэтому полная дисперсия неотрицательна.λ1λ2...λп,

Tр(Σ)знак равноλ1++λп
λяΣλп0

Но главные компоненты задаются как , где e i - i- й собственный вектор (стандартизированный для длины 1 ), соответствующий собственному значению λ i . Его дисперсия V a r ( e i X ) = e i Σ e i = λ i e i e i = λ i, и, следовательно, первые k главных компонентов составляют ( λеяИксеяя1λя

Вaр(еяИкс)знак равноея'Σеязнак равноλяея'еязнак равноλя
К от общей дисперсии. В частности, они составляют100%от общей дисперсии приk=p.
(λ1++λКλ1++λп100) %
100 %Кзнак равноп
MånsT
источник
1
Вы видели (более свежий) комментарий @Max к вопросу? Он прибил ответ.
whuber
@whuber: я этого не видел, так что спасибо. Я сделал подобное замечание в комментарии к ответу Иисуса Навина.
MånsT
4

Вот некоторый R-код для дополнения предыдущих ответов ( pca[["sdev"]]обычно пишется pca$sdev, но это приводит к неправильному форматированию в фрагменте ниже).

# Generate a dummy dataset.
set.seed(123)
x <- matrix(rnorm(400, sd=3), ncol=4)
# Note that princomp performs an unscaled PCA.
pca1 <- princomp(x)
# Show the fraction variance of each PC.
pca1[["sdev"]]^2
cumsum(pca1[["sdev"]]^2)/sum(pca1[["sdev"]]^2)
# Perform a scaled PCA.
pca2 <- princomp(x, cor=TRUE)
pca2[["sdev"]]^2
cumsum(pca2[["sdev"]]^2)/sum(pca2[["sdev"]]^2)

Таким образом, как указывает @Max, решение этой проблемы решает работа с дисперсией вместо стандартного отклонения и не забывая делить ее на общую дисперсию.

gui11aume
источник