Чому PCA даних за допомогою SVD даних?


22

Це питання стосується ефективного способу обчислення основних компонентів.

  1. Багато текстів на лінійній PCA пропонують використовувати сингулярне розкладання значення випадкових даних . Тобто, якщо ми маємо дані і хочемо замінити змінні (її стовпці ) основними компонентами, ми робимо SVD: , сингулярні значення (квадратні корені власних значень), що займають основну діагональ , праві власні вектори - ортогональна матриця обертання осей-змінних на осі-компоненти, ліві власні вектори подібні , лише для випадків. Тоді ми можемо обчислити значення компонентів як .X = U S V S V U V C = X V = U SХХ=USV'SVUVС=ХV=US

  2. Інший спосіб зробити PCA змінних - це шляхом розкладання квадратної матриці (тобто може бути кореляціями або коваріаціями тощо, між змінними). Розкладання може бути власне-декомпозицією або сингулярним розкладанням: з квадратною симетричною позитивною напівфінітною матрицею вони дадуть такий самий результат з власними значеннями, як діагональ , і як описано раніше. Значення компонентів будуть .RR=Х'ХR L V C = X VR=VLV'LVС=ХV

Тепер моє запитання: якщо дані є великою матрицею, а кількість випадків (що часто буває) набагато більше, ніж кількість змінних, тоді очікується , що шлях (1) буде набагато повільніше, ніж спосіб (2 ), оскільки спосіб (1) застосовує досить великий алгоритм (наприклад, SVD) до великої матриці; він обчислює і зберігає величезну матрицю яка нам насправді не потрібна в нашому випадку (PCA змінних). Якщо так, то чому так багато підручників здається, що вони виступають або просто згадують лише спосіб (1)? Може бути , це є ефективним і я що - то НЕ вистачає?ХU


2
Як правило, нас цікавлять лише декілька основних компонентів, які пояснюють більшість дисперсій. Можна зробити знижений SVD; наприклад , якщо має розмірність N × р , де р < < Н , то «и функція буде обчислювати тільки перше р ліві і праві сингулярні вектори за замовчуванням. ХN×pp<<NRsvdp
М. Берк

1
@ M.Berk: , однаково, в обох підходах однаково: вони дають еквівалентні результати (рівні до змін знаків). Також, наприклад, R обчислює C, лише якщо вимагається. pС
cbeleites підтримує Моніку

Чи є у вас посилання на спосіб (1)? Мені відомо лише, що PCA реалізується за допомогою SVD на матриці коваріації (тобто спосіб 2), оскільки це дозволяє уникнути численних проблем і, очевидно, масштабує розмірність, а не розмір набору даних. Шлях (1) Я б назвав SVD, а не PCA взагалі. Я бачив це лише в чистому SVD-контексті, де фактично не було б повного розкладання.
Аноні-Мус

@ Аноні-Мусс, лише одне зазначити, Joliffe, Principal component analysis, 2nd ed.насправді Джоліфф описує обидва способи, але в основному розділі про PCA він говорить про просто шлях 1, наскільки я пам'ятаю.
ttnphns

@ Anonymous-Mousse, Шлях 1 для мене важливий з теоретичної точки зору, оскільки він чітко показує, як PCA безпосередньо пов'язаний з простим аналізом листування .
ttnphns

Відповіді:


7

Ось мій 2кт на цю тему

  • Лекція з хіміометрії, де я вперше вивчила PCA, використовувала рішення (2), але вона не була орієнтована на числові показники, і моя лекція з чисельності була лише вступом і не обговорювала SVD, наскільки я пам'ятаю.

  • Якщо я розумію Холмса: Швидкий SVD для великомасштабних матриць правильно, ваша ідея була використана для обчислювально швидкого SVD довгих матриць.
    Це означає, що хороша реалізація SVD може слідувати внутрішньо (2), якщо вона зустріне відповідні матриці (я не знаю, чи є ще кращі можливості). Це означатиме, що для впровадження на високому рівні краще використовувати SVD (1) і залишити його BLAS, щоб подбати про те, який алгоритм використовувати внутрішньо.

  • Швидка практична перевірка: SVD OpenBLAS, схоже, не робить цього розрізнення на матриці 5e4 x 100, svd (X, nu = 0)займає медіану 3,5 с, тоді як svd (crossprod (X), nu = 0)займає 54 мс (викликається з R з microbenchmark).
    Звільнення власних значень звичайно швидко, і до цього результати обох викликів рівносильні.

    timing  <- microbenchmark (svd (X, nu = 0), svd (crossprod (X), nu = 0), times = 10)
    timing
    # Unit: milliseconds
    #                      expr        min         lq    median         uq        max neval
    #            svd(X, nu = 0) 3383.77710 3422.68455 3507.2597 3542.91083 3724.24130    10
    # svd(crossprod(X), nu = 0)   48.49297   50.16464   53.6881   56.28776   59.21218    10
    

оновлення: Погляньте на Wu, W .; Massart, D. & de Jong, S .: Алгоритми PCA ядра для широких даних. Частина I: Теорія та алгоритми, Хімеметрія та інтелектуальні лабораторні системи, 36, 165 - 172 (1997). DOI: http://dx.doi.org/10.1016/S0169-7439(97)00010-5

У даній роботі розглянуто числові та обчислювальні властивості чотирьох різних алгоритмів PCA: SVD, власне розкладання (EVD), NIPALS та POWER.

Вони пов'язані так:

computes on      extract all PCs at once       sequential extraction    
X                SVD                           NIPALS    
X'X              EVD                           POWER

Контекст статті є широким , і вони працюють на X X (ядро PCA) - це якраз протилежна ситуація, як про ту, про яку ви питаєте. Отже, щоб відповісти на ваше запитання про довгу поведінку матриці, вам потрібно обмінятися значенням "ядро" та "класичне".X(30×500)XX

порівняння продуктивності

Не дивно, що EVD та SVD змінюють місця залежно від того, використовуються класичні або алгоритми ядра. У контексті цього питання це означає, що те чи інше може бути кращим залежно від форми матриці.

Але з їх обговорення «класичних» SVD та EVD видно, що розкладання - це звичайний спосіб обчислення PCA. Однак вони не вказують, який алгоритм SVD використовується, крім того, що вони використовують функцію Matlab .XХsvd ()


    > sessionInfo ()
    R version 3.0.2 (2013-09-25)
    Platform: x86_64-pc-linux-gnu (64-bit)

    locale:
     [1] LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C               LC_TIME=de_DE.UTF-8        LC_COLLATE=de_DE.UTF-8     LC_MONETARY=de_DE.UTF-8   
     [6] LC_MESSAGES=de_DE.UTF-8    LC_PAPER=de_DE.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
    [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       

    attached base packages:
    [1] stats     graphics  grDevices utils     datasets  methods   base     

    other attached packages:
    [1] microbenchmark_1.3-0

loaded via a namespace (and not attached):
[1] tools_3.0.2

$ dpkg --list libopenblas*
[...]
ii  libopenblas-base              0.1alpha2.2-3                 Optimized BLAS (linear algebra) library based on GotoBLAS2
ii  libopenblas-dev               0.1alpha2.2-3                 Optimized BLAS (linear algebra) library based on GotoBLAS2

Отже, ваше тестування (3,5 сек проти 54 мсек) підтримує мою лінію, що "шлях 1" значно повільніше. Правильно?
ttnphns

1
@ttnphns: так. Але оскільки SVD надається BLAS, це може бути різним із іншим BLAS. Я б очікував, що хороший оптимізований BLAS робить щось подібне. Однак, схоже, це не так з OpenBLAS. Я занадто лінивий, щоб перевірити інші BLAS, але, можливо, кілька людей могли перевірити свої інші BLAS, щоб ми з'ясували, які з них оптимізовані для цього випадку, а які - ні. (Я надіслав електронною поштою розробника OpenBLAS і надіслав йому посилання на це запитання, тому, можливо, він може додати якусь інформацію, наприклад, причини svd (X'X)
невключення

Деякі моменти потребують уточнення (мені). Чи можна «методи ядра» узагальнити як «робота над замість X, коли n < p »? якщо так, то це зовсім банально. Я не знаю POWER, але я знаю NIPALS, який обчислює власні вектори X X шляхом ітерації u n + 1 = X X u n / | | X X u n | | (він сходиться до 1-го власного вектора v 1 , тоді вам доведеться оновити XХ'Хн<pХ'Хун+1=Х'Хун/||Х'Хун||v1Хдля обчислення другого тощо). Є два способи виконання NIPALS, (1) ви можете попередньо обчислити , або (2) ви можете виконати продукт як X × ( X u n ) , який спосіб тут використовується? Я здогадуюсь (1), що може бути несправедливо. Х'ХХ'×(Хун)
Елвіс

ХХТ

Я говорив про ваше оновлення, де бере участь Nipals. Я підтверджую, що Nipals не бере участі в SVD Лапака. Щодо експерименту з орієнтиром, щось подібне microbenchmark(X <- matrix(rnorm(5e6), ncol=100), Y <- t(X), svd(X), svd(Y), control=list(order="inorder"), times = 5)може бути цікавим.
Елвіс

18

SVD повільніше, але його часто вважають кращим методом через його більш високу числову точність.

Х1н-1ХХХХнp

Ось що написано у довідці щодо pca()функції MATLAB :

Алгоритм основних компонентів, який pcaвикористовується для аналізу основного компонента [...]:

'svd' - за замовчуванням. Сингулярне розкладання величини (SVD) X.

нp

Останнє речення підкреслює вирішальну компроміс із швидкістю точності, який тут грає.

1000×100

X = randn([1000 100]);

tic; svd(X); toc         %// Elapsed time is 0.004075 seconds.
tic; svd(X'); toc        %// Elapsed time is 0.011194 seconds.
tic; eig(X'*X); toc      %// Elapsed time is 0.001620 seconds.
tic; eig(X*X'); toc;     %// Elapsed time is 0.126723 seconds.

нpХХ

ХХХХ

Х=(111ϵ000ϵ000ϵ),
3+ϵ2ϵ2ϵ2ϵ=10-5
eps = 1e-5;
X = [1 1 1; eye(3)*eps];
display(['Squared sing. values of X: ' num2str(sort(svd(X),'descend').^2')])
display(['Eigenvalues of X''*X:       ' num2str(sort(eig(X'*X),'descend')')])

отримання однакових результатів:

Squared sing. values of X: 3       1e-10       1e-10
Eigenvalues of X'*X:       3       1e-10       1e-10

ϵ=10-10

Squared sing. values of X: 3       1e-20       1e-20
Eigenvalues of X'*X:       3           0 -3.3307e-16

ХХ має деякі майже колінеарних колонки (тобто деякі дуже малі сингулярні значень), перший обчислювальний ковариационную матрицю , а потім обчислення його eigendecomposition призведе у втраті точності порівняно з прямим СВД.

Додам, що часто радимо ігнорувати цю потенційну [крихітну] втрату точності і скоріше використовувати швидший метод.


1
ХТХ

Дякуємо за відповідь та за ретельний розгляд плюсів і мінусів.
ttnphns

Амеба, може, це те, що ви знайдете час, щоб показати конкретний приклад, коли числова стабільність страждає від eig()підходу? (Читачі принесуть користь: між швидкістю та стабільністю існує точка компромісу. Як можна вирішити конкретну практичну ситуацію?)
ttnphns

@ttnphns я переписав всю відповідь, наводячи конкретний приклад. Поглянь.
Амеба каже, що поверніть Моніку

1
@amoeba, велике спасибі за те, що повернувся та подав приклад! Я спробував обидва приклади epsilon у SPSS і отримав такі результати, як ваш, за винятком останнього рядка: замість 3 0 -3.3307e-16eigen у spss повернув мене 3 0 0. Схоже, що функція має деяке вбудоване та фіксоване значення допуску, за яким воно не відключається. У цьому прикладі функція виявилася так, ніби зламати вузол числової нестабільності шляхом обнулення обох крихітних власних значень, "0" та "-16".
ttnphns
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.