Почему Эндрю Нг предпочитает использовать SVD, а не EIG ковариационной матрицы для PCA?


29

Я изучаю PCA из курса Coursera Эндрю Нг и других материалов. В первом задании Stanford NLP cs224n и в видео лекции Эндрю Нг они проводят разложение по сингулярным значениям вместо разложения по ковариационной матрице по собственным векторам, и Нг даже говорит, что SVD численно более устойчив, чем собственное разложение.

Насколько я понимаю, для PCA мы должны делать SVD матрицы данных (m,n)размера, а не ковариационной матрицы (n,n)размера. И разложение по собственным векторам ковариационной матрицы.

Почему они делают SVD ковариационной матрицы, а не матрицы данных?


8
Для квадратно-симметричной положительной полуопределенной матрицы (такой как ковариационная матрица) разложение по собственным значениям и сингулярные значения в точности совпадают.
говорит амеба, восстанови Монику

5
Я имею в виду, что они математически одинаковы. Численно они действительно могут использовать разные алгоритмы, и один может быть более устойчивым, чем другой (как говорит Нг). Было бы интересно узнать больше о +1.
говорит амеба, восстанови Монику

4
Некоторая информация об этом здесь: de.mathworks.com/matlabcentral/newsreader/view_thread/21268 . Но обратите внимание, что любое объяснение того, почему один алгоритм будет более стабильным, чем другой, будет очень техническим.
говорит амеба, восстанови Монику

2
В Matlab x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;на моей машине выводит 12s для eig () и 26s для svd (). Если он намного медленнее, он должен быть хотя бы более стабильным! :-)
говорит амеба Восстановить Монику

4
Это может быть основано на неправильном понимании: Ведение SVD матрицы данных является более стабильной , чем при использовании eigили svdна ковариационной матрице, но, насколько я знаю , нет большой разницы между использованием eigили svdна матрице ковариаций --- они оба обратно устойчивых алгоритма. Во всяком случае, я бы положил свои деньги на то, чтобы быть более стабильным, так как он делает меньше вычислений (при условии, что оба они реализованы с использованием самых современных алгоритмов).
Федерико Полони,

Ответы:


17

Amoeba уже дал хороший ответ в комментариях, но если вы хотите формальный аргумент, здесь это идет.

Разложение по сингулярным числам матрицы имеет вид , где столбцы являются собственными векторами а диагональные элементы в являются квадратными корнями из собственных значений, то есть .AA=UΣVTVATAΣσii=λi(ATA)

Как вы знаете, главными компонентами являются ортогональные проекции ваших переменных на пространство собственных векторов эмпирической ковариационной матрицы . Дисперсия компонентов задается своими собственными значениями, .1n1ATAλi(1n1ATA)

Рассмотрим любую квадратную матрицу , и вектор такой, что . затемBαRvBv=λv

  1. Bkv=λkv
  2. λ(αB)=αλ(B)

Определим . SVD будет вычислять собственное разложение чтобы получитьS=1n1ATASSTS=1(n1)2ATAATA

  1. собственные векторы , которые по свойству 1 являются собственными векторами(ATA)TATA=ATAATAATA
  2. эти квадратные корни собственных значений , который по свойству 2, затем 1, затем 2 снова, являются .1(n1)2ATAATA1(n1)2λi(ATAATA)=1(n1)2λi2(ATA)=1n1λi(ATA)=λi(1n1ATA)

Вуаля!

Что касается числовой стабильности, необходимо выяснить, что такое используемые алогриты. Если вы готовы, я считаю, что эти подпрограммы LAPACK используются numpy:

Обновление: Что касается стабильности, реализация SVD, похоже, использует подход «разделяй и властвуй», в то время как в собственной декомпозиции используется простой QR-алгоритм. Я не могу получить доступ к некоторым соответствующим документам SIAM из моего учреждения (сокращение исследований), но я нашел что-то, что могло бы поддержать оценку того, что процедура SVD является более стабильной.

В

Накацукаса, Юджи и Николас Дж. Хайам. «Стабильные и эффективные алгоритмы спектрального разделения и завоевания для симметричного разложения по собственным значениям и SVD». Журнал SIAM по научным вычислениям 35.3 (2013): A1325-A1349.

они сравнивают устойчивость различных алгоритмов на собственные значения, и кажется, что подход «разделяй и властвуй» (в одном из экспериментов они используют тот же самый, что и numpy!) более стабилен, чем алгоритм QR. Это, наряду с другими заявлениями о том, что методы D & C действительно более стабильны, поддерживает выбор Ng.


Собственные значения, которые я получил от svd по ковариации и svd по среднецентрированным данным, не совпадают.
theGD

Однако баллы, то есть X * V (где V получается из [U, S, V] = SVD (X) или SVD (COVX)), являются одинаковыми.
theGD

1
@theGD Собственные значения cov (X) и сингулярные значения (X) не идентичны, см. stats.stackexchange.com/questions/134282 .
амеба говорит восстановить Монику

не нужно отчаиваться из-за отсутствия доступа к журналам SIAM: цитируемая
Дима Пасечник,

2
@broncoAbierto технология. отчет находится здесь: cpsc.yale.edu/sites/default/files/files/tr932.pdf (вероятно, его нелегко найти из-за опечатки "Symetric" в заголовке на cpsc.yale.edu/research/technical-reports. / 1992-технические отчеты :-))
Дима Пасечник

12

@amoeba были отличные ответы на PCA вопросы, в том числе это одно по отношению к СВД PCA. Отвечая на ваш точный вопрос, я сделаю три замечания:

  • математически нет никакой разницы, вычисляете ли вы PCA по матрице данных напрямую или по ее ковариационной матрице
  • Разница исключительно в численной точности и сложности. Применение SVD непосредственно к матрице данных численно более устойчиво, чем к ковариационной матрице
  • SVD может применяться к ковариационной матрице для выполнения PCA или для получения собственных значений, фактически это мой любимый метод решения собственных задач.

Оказывается, что SVD более устойчив, чем типичные процедуры декомпозиции собственных значений, особенно для машинного обучения. В машинном обучении легко получить высоко коллинеарные регрессоры. SVD работает лучше в этих случаях.

Вот код Python для демонстрации сути. Я создал высококоллинеарную матрицу данных, получил ее ковариационную матрицу и попытался получить ее собственные значения. SVD все еще работает, в то время как обычная собственная декомпозиция терпит неудачу в этом случае.

import numpy as np
import math
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 1000
X = np.random.rand(T,2)
eps = 1e-11
X[:,1] = X[:,0] + eps*X[:,1]

C = np.cov(np.transpose(X))
print('Cov: ',C)

U, s, V = LA.svd(C)
print('SVDs: ',s)

w, v = LA.eig(C)
print('eigen vals: ',w)

Выход:

Cov:  [[ 0.08311516  0.08311516]
 [ 0.08311516  0.08311516]]
SVDs:  [  1.66230312e-01   5.66687522e-18]
eigen vals:  [ 0.          0.16623031]

Обновить

Отвечая на комментарий Федерико Полони, вот код с тестированием стабильности SVD против Eig на 1000 случайных выборок той же матрицы выше. Во многих случаях Eig показывает 0 малых собственных значений, что привело бы к сингулярности матрицы, а SVD здесь этого не делает. SVD примерно в два раза точнее при определении небольшого собственного значения, которое может или не может быть важным в зависимости от вашей проблемы.

import numpy as np
import math
from scipy.linalg import toeplitz
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 100
p = 2
eps = 1e-8

m = 1000 # simulations
err = np.ones((m,2)) # accuracy of small eig value
for j in range(m):
    u = np.random.rand(T,p)
    X = np.ones(u.shape)
    X[:,0] = u[:,0]
    for i in range(1,p):
        X[:,i] = eps*u[:,i]+u[:,0]

    C = np.cov(np.transpose(X))

    U, s, V = LA.svd(C)

    w, v = LA.eig(C)

    # true eigen values
    te = eps**2/2 * np.var(u[:,1])*(1-np.corrcoef(u,rowvar=False)[0,1]**2)
    err[j,0] = s[p-1] - te
    err[j,1] = np.amin(w) - te


print('Cov: ',C)
print('SVDs: ',s)
print('eigen vals: ',w)
print('true small eigenvals: ',te)

acc = np.mean(np.abs(err),axis=0)    
print("small eigenval, accuracy SVD, Eig: ",acc[0]/te,acc[1]/te)

Выход:

Cov:  [[ 0.09189421  0.09189421]
 [ 0.09189421  0.09189421]]
SVDs:  [ 0.18378843  0.        ]
eigen vals:  [  1.38777878e-17   1.83788428e-01]
true small eigenvals:  4.02633695086e-18
small eigenval, accuracy SVD, Eig:  2.43114702041 3.31970128319

Здесь код код работает. Вместо того, чтобы генерировать случайную ковариационную матрицу для проверки подпрограмм, я генерирую случайную матрицу данных с двумя переменными: где - независимые однородные случайные величины. Таким образом, ковариационная матрица имеет вид: где - дисперсия униформ и коэффициент корреляции между их.

x1=ux2=u+εv
u,v
(σ12σ12+ερσ1σ2σ12+ερσ1σ2σ12+2ερσ1σ2+ε2σ22σ2)
σ12,σ22,ρ

Наименьшее собственное значение: Маленькое собственное значение не может быть вычислено простым подключением в формулу из-за ограниченной точности, поэтому вам нужно Тейлор развернуть его:

λ=12(σ22ε2σ24ε4+4σ23ρσ1ε3+8σ22ρ2σ12ε2+8σ2ρσ13ε+4σ14+2σ2ρσ1ε+2σ12)
ε
λσ22ε2(1ρ2)/2

Я запускаю моделирования реализаций матрицы данных, вычисляю собственные значения моделируемой ковариационной матрицы и ошибки .j=1,,mλ^jej=λλ^j


4
Да, но здесь OP спрашивает о СВД против ГЦОС применяется как к ковариационной матрице.
говорит амеба, восстанови Монику

1
@amoeba, я уточнил связь СВД и СПС
Аксакал

Это хороший ответ. Я хотел бы, однако, упомянуть, что svd не может обнаружить отрицательные собственные значения, когда они есть, и вы хотите их увидеть (если ковариационная матрица не является оригинальной, но, скажем, сглажена или оценена каким-либо образом, или выведена из парного удаления пропущенных значений). Более того, eig on cov matrix остается немного быстрее svd на нем.
ttnphns

@ttnphns, неположительно определенная матрица - это, конечно, проблема
Аксакал

1
@FedericoPoloni, по арифметике FP и не зная точного ответа, я не согласен. В этом случае я знаю ответ с достаточной точностью для этой задачи. На 2х2 у вас есть справедливое мнение. Я что-нибудь придумаю.
Аксакал

6

Для пользователей Python я хотел бы отметить, что для симметричных матриц (таких как ковариационная матрица) лучше использовать numpy.linalg.eighфункцию вместо общей numpy.linalg.eigфункции.

eighв 9-10 раз быстрее, чем eigна моем компьютере (независимо от размера матрицы) и имеет лучшую точность (на основе теста точности @ Aksakal).

Я не убежден в демонстрации преимущества точности SVD с небольшими собственными значениями. @ Тест Аксакала на 1-2 порядка более чувствителен к случайному состоянию, чем к алгоритму (попробуйте отобразить все ошибки вместо того, чтобы свести их к одному абсолютному максимуму). Это означает, что небольшие ошибки в ковариационной матрице будут иметь большее влияние на точность, чем выбор алгоритма собственного разложения. Кроме того, это не связано с основным вопросом, который касается PCA. Самые маленькие компоненты игнорируются в PCA.

Аналогичный аргумент может быть сделан в отношении численной устойчивости. Если бы мне пришлось использовать метод ковариационной матрицы для PCA, я бы разложил его eighвместо svd. Если это не удастся (что еще не было продемонстрировано здесь), то, вероятно, стоит переосмыслить проблему, которую вы пытаетесь решить, прежде чем начинать искать лучший алгоритм.



2

Чтобы ответить на последнюю часть вашего вопроса: «Почему они делают SVD из ковариационной матрицы, а не из матрицы данных?» Я считаю, что это из-за производительности и хранения. Как правило, будет очень большим числом, и даже если большое, мы ожидаем .mnmn

Вычисление ковариационной матрицы и последующее выполнение SVD для этого значительно быстрее, чем вычисление SVD для полной матрицы данных в этих условиях для того же результата.

Даже при довольно небольших значениях прирост производительности составляет тысячи (миллисекунд против секунд). Я провел несколько тестов на моей машине, чтобы сравнить с помощью Matlab: введите описание изображения здесь

Это просто процессорное время, но потребности в памяти так же, если не больше, важны. Если вы попытаетесь использовать SVD на матрице миллион на тысячу в Matlab, то это приведет к ошибке по умолчанию, поскольку для него требуется рабочий размер массива 7,4 ТБ.


Это не отвечает на вопрос о EIG матрицы ков по сравнению с SVD ковариационной матрицы .
говорит амеба, восстанови Монику

1
Его вопрос в конце, выделенный жирным шрифтом, гласит: «Почему они делают SVD ковариационной матрицы, а не матрицы данных?» на что я ответил.
Гриф

Я отредактирую вступительное предложение, чтобы было ясно, что я отвечал на эту часть вопроса ОП. Я понимаю, как это может сбить с толку. Спасибо.
Гриф

Если вы попытаетесь использовать SVD для матрицы миллион на тысячу в Matlab, то по умолчанию произойдет ошибка. В этих случаях рекомендуется использовать тонкий SVD. Это значительно улучшит объем и производительность хранилища.
Федерико Полони
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.