Чому Ендрю Нг вважає за краще використовувати SVD, а не EIG коваріаційної матриці для PCA?


29

Я вивчаю PCA з курсу Coursera Ендрю Нґ та інших матеріалів. У першому завданні курсу Stanford NLP cs224n , а в лекційному відео від Ендрю Нг вони роблять сингулярне розкладання значення замість власного вектора розкладання коваріаційної матриці, і Ng навіть говорить, що SVD чисельно стабільніше, ніж ейгендекомпозиція.

З мого розуміння, для PCA ми повинні робити SVD матриці даних (m,n)розміру, а не коваріаційної матриці (n,n)розміру. І власне векторне розкладання матриці коваріації.

Чому вони роблять SVD матриці коваріації, а не матрицю даних?


8
Для квадратної симетричної позитивної напівфінітової матриці (наприклад, матриці коваріації) власне значення та розклади сингулярних значень точно однакові.
Амеба каже, що повернеться Моніка

5
Я маю на увазі, що вони математично однакові. Числово вони дійсно можуть використовувати різні алгоритми, і один може бути більш стійким, ніж інший (як говорить Ng). Про це було б цікаво дізнатися більше, +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на матриці ковариаций --- вони обидва відсталі стабільні алгоритми. У всякому разі, я б поставив гроші на EiG будучи більш стабільною, так як він робить менше обчислень (припускаючи , як реалізуються з державою в найсучасніших алгоритмів).
Федеріко Полоні

Відповіді:


17

Амеба вже дав хорошу відповідь у коментарях, але якщо ви хочете формального аргументу, ось це йде.

Синулярне розкладання матриці дорівнює , де стовпці є власними векторами а діагональні записи - квадратні корені її власних значень, тобто .A = U Σ V T V A T A Σ σ i i = AA=UΣVTVATAΣσii=λi(ATA)

Як відомо, основними компонентами є ортогональні проекції змінних на простір власних векторів емпіричної матриці коваріації . Варіантність компонентів задається його власними значеннями, .λi(11n1ATAλi(1n1ATA)

Розглянемо будь-яку квадратну матрицю , та вектор такий, що . Потімα R v B v = λ vBαRvBv=λv

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

Давайте визначимо . SVD of обчислить ейгендекомпозицію щоб отриматиSSTS=1S=1n1ATASSTS=1(n1)2ATAATA

  1. власних векторів , які за властивістю 1 є тимиA T A(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, як видається, використовує підхід «ділити і перемогти», тоді як для eigendecomposition використовується звичайний QR-алгоритм. Я не можу отримати доступ до якихось відповідних паперів SIAM від мого закладу (звинувачення у винах дослідження), але я знайшов щось, що могло б підтримати оцінку того, що звичайна програма SVD є більш стабільною.

В

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

вони порівнюють стійкість різних алгоритмів власного значення, і здається, що підхід ділити і перемогти (вони використовують те саме, що і numpy в одному з експериментів!) є більш стійким, ніж алгоритм QR. Це разом із твердженнями в іншому місці про те, що методи науково-дослідної роботи дійсно більш стабільні, підтримує вибір 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: документ, який ви цитуєте, знаходиться тут: opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
Діма Пасечник

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

12

@amoeba отримав відмінні відповіді на питання PCA, включаючи цю щодо відношення SVD до 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
Так, але тут ОП запитує про SVD проти EIG, застосованому як до коваріаційної матриці.
Амеба каже: Відновити Моніку

1
@amoeba, я уточнив зв’язок SVD та PCA
Аксакал

Це хороша відповідь. Хочеться зазначити, однак, що svd не може виявити негативні власні значення, коли такі є, і ви хочете їх побачити (якщо матриця коваріації не є оригінальною, але є, скажімо, згладженою чи оціненою якось або виведеною або виходить з парного видалення пропущених значень). Більше того, eig на cov матриці залишається трохи швидше, ніж svd на ній.
ttnphns

@ttnphns, непозитивна визначена матриця - це питання, звичайно,
Аксакал

1
@FedericoPoloni, по арифметиці FP і не знаючи точної відповіді, я не згоден. У цьому випадку я знаю відповідь досить точно для цього завдання. На 2x2 у вас є справедлива точка. Я щось придумаю.
Аксакал

6

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

eighв 9-10 разів швидше, ніж eigна моєму комп’ютері (незалежно від розміру матриці) і має кращу точність (на основі тесту на @ Aksakal на точність).

Я не переконаний у демонстрації переваги точності SVD з малими власними значеннями. @ Тест Аксакала на 1-2 порядки більш чутливий до випадкового стану, ніж до алгоритму (спробуйте скласти всі помилки, а не зменшити їх до одного абсолютного максимуму). Це означає, що невеликі помилки в матриці коваріації матимуть більший вплив на точність, ніж вибір алгоритму ейгендекомпозиції. Також це не пов'язане з головним питанням, яке стосується PCA. Найменші компоненти ігноруються в PCA.

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



2

mnmn

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

Навіть для досить малих значень підвищення продуктивності - це тисячі факторів (мілісекунд проти секунд). Я провів кілька тестів на своїй машині для порівняння за допомогою Matlab: введіть тут опис зображення

Це просто час процесора, але потреби в сховищі так само важливі, якщо не більше. Якщо ви спробуєте SVD на матриці на мільйон на тисячу в Matlab, він за замовчуванням помилиться, оскільки йому потрібен розмір робочого масиву 7,4 ТБ.


Це не дає відповіді на питання, що стосується EIG матриці cov проти SVD матриці коваріації .
Амеба каже, що поверніть Моніку

1
Його питання в кінці, виділене жирним шрифтом, говорить: "Чому вони роблять SVD матриці коваріації, а не матрицю даних?" на що я відповів.
Gruff

Я відредагую вступне речення, щоб було зрозуміло, що я відповідав на ту частину питання ОП. Я бачу, як це може бути заплутаним. Спасибі.
Груф

Якщо ви спробуєте SVD на матриці на мільйон на тисячу в Matlab, це помилка за замовчуванням. У цих випадках хороша чисельна практика використовує тонку SVD. Це значно покращить розмір та продуктивність пам’яті.
Федеріко Полоні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.