Як повернути PCA та реконструювати оригінальні змінні з декількох основних компонентів?


113

Аналіз основних компонентів (PCA) може бути використаний для зменшення розмірності. Після такого зменшення розмірності, як можна приблизно реконструювати вихідні змінні / ознаки з невеликої кількості основних компонентів?

Як варіант, як можна видалити або вилучити з даних кілька основних компонентів?

Іншими словами, як повернути PCA?


Враховуючи, що PCA тісно пов'язаний з розкладанням сингулярного значення (SVD), можна задати те саме питання: як повернути SVD?


10
Я публікую цю тему запитань і запитань, тому що мені набридло бачити десятки питань, які задають цю річ, і не в змозі закрити їх як дублікати, оскільки у нас немає канонічної теми на цю тему. Є кілька подібних тем з гідними відповідями, але всі, здається, мають серйозні обмеження, як, наприклад, фокусування виключно на Р.
амеба

4
Я ціную зусилля - я думаю, що існує гостра потреба зібрати разом інформацію про PCA, що вона робить, що вона не робить, в одну або кілька високоякісних ниток. Я радий, що ти взяв на себе це зробити!
Sycorax

1
Я не переконаний, що ця канонічна відповідь «очищення» служить своєму призначенню. Ми маємо тут відмінне, загальне питання та відповідь, але кожне з питань мало деякі тонкощі щодо PCA на практиці, які тут втрачаються. По суті, ви взяли всі питання, виконали PCA на них і відкинули нижчі основні компоненти, де іноді ховається багата і важлива деталь. Більше того, ви повернулися до підручника «Лінійна алгебра», що саме робить PCA непрозорим для багатьох людей, замість того, щоб використовувати lingua franca випадкових статистиків, а саме Р.
Томас Броун

1
@Thomas Дякую Я думаю, що ми маємо незгоду, із задоволенням обговорюємо це у чаті чи в Мета. Дуже коротко: (1) Дійсно, краще відповісти на кожне питання окремо, але сувора реальність така, що цього не відбувається. Багато питань залишаються без відповіді, як, мабуть, і ваше. (2) Спільнота тут віддає перевагу загальні відповіді, корисні для багатьох людей; Ви можете подивитися на те, на які відповіді ви отримуєте найбільше голосів. (3) Погодьтеся з математикою, але саме тому я тут дав R-код! (4) Не згоден щодо lingua franca; особисто я не знаю Р.
амеба

@amoeba Боюсь, я не знаю, як знайти згаданий чат, оскільки раніше ніколи не брав участі в мета-дискусіях.
Томас Браун

Відповіді:


147

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

Xrawn×pnpμXVp×kkkn×kZ=XV

Це проілюстровано на малюнку нижче: перший субплот показує деякі центрировані дані (ті самі дані, які я використовую в своїх анімаціях у пов'язаній нитці) та його проекції на першу головну вісь. Другий субплот показує лише значення цієї проекції; розмірність знижена з двох до одного:

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

Для того, щоб можна було реконструювати вихідні дві змінні з цього одного головного компонента, ми можемо повернути його до розмірів з . Дійсно, значення кожного ПК повинні бути розміщені на тому ж векторі, який було використано для проекції; порівняйте підплоти 1 і 3. Результат дається . Я показую це на третьому субплоті вище. Щоб отримати остаточну реконструкцію , нам потрібно додати середній вектор до цього:pVX^=ZV=XVVX^rawμ

PCA reconstruction=PC scoresEigenvectors+Mean

Зауважте, що можна перейти безпосередньо від першої субплоти до третьої, множивши на матрицю ; її називають матрицею проекції . Якщо використовуються всі власні вектори, то є матрицею ідентичності (зменшення розмірності не проводиться, отже, "реконструкція" є ідеальною). Якщо використовується лише підмножина власних векторів, це не тотожність.XVVpVV

Це працює для довільної точки в просторі ПК; його можна відобразити у вихідний простір через .zx^=zV

Відмова (видалення) провідних ПК

Іноді хочеться відкинути (видалити) один або кілька провідних ПК та зберегти решту, замість того, щоб зберігати провідні ПК та відкидати решту (як вище). У цьому випадку всі формули залишаються абсолютно однаковими , але повинен складатися з усіх основних осей, крім тих, які хоче відкинути. Іншими словами, завжди повинен включати всі ПК, які потрібно зберегти.VV

Застереження про PCA на кореляцію

Коли PCA робиться на кореляційній матриці (а не на матриці коваріації), необроблені дані не лише центрируються шляхом віднімання але й масштабуються шляхом ділення кожного стовпця на його стандартне відхилення . У цьому випадку для реконструкції вихідних даних потрібно змінити масштаб стовпців допомогою і лише потім додати назад середній вектор .XrawμσiX^σiμ


Приклад обробки зображень

Ця тема часто виникає в контексті обробки зображень. Розгляньте Ленну - одне із стандартних зображень у літературі з обробки зображень (перейдіть за посиланнями, щоб знайти, звідки вона походить). Нижче зліва я показую варіант сірого масштабу цього зображення (файл доступний тут ).512×512

Дві версії зображення в градаціях сірого зображення зображення Ленни.  Той, що праворуч, зернистий, але безумовно впізнаваний.

Ми можемо трактувати це зображення масштабу сірого як матриця даних . Я виконую на ньому PCA і обчислюю використовуючи перші 50 основних компонентів. Результат відображається праворуч.512×512X сировинуXrawX^raw


Повернення SVD

PCA дуже тісно пов'язаний з розкладанням сингулярного значення (SVD), див. Зв'язок між SVD та PCA. Як використовувати SVD для виконання PCA? для отримання детальної інформації. Якщо матриця є SVD-ed як і вибирається -вимірний вектор який являє собою точку в "зменшеному" просторі з розмірів, потім, щоб повернути його до розмірів, потрібно помножити його на .X X = U S V K г U до р S 1 : K , 1 : K V : , 1 : Kn×pXX=USVkzUkpS1:k,1:kV:,1:k


Приклади в R, Matlab, Python та Stata

Я проведу PCA на даних Fisher Iris, а потім реконструюю його за допомогою перших двох основних компонентів. Я роблю PCA на коваріаційній матриці, а не на кореляційній матриці, тобто я не масштабую змінні тут. Але я все одно повинен додати середнє значення назад. Деякі пакети, як Stata, переймаються цим стандартним синтаксисом. Дякуємо @StasK та @Kodiologist за допомогу з кодом.

Ми перевіримо реконструкцію першої точки даних, а саме:

5.1        3.5         1.4        0.2

Матлаб

load fisheriris
X = meas;
mu = mean(X);

[eigenvectors, scores] = pca(X);

nComp = 2;
Xhat = scores(:,1:nComp) * eigenvectors(:,1:nComp)';
Xhat = bsxfun(@plus, Xhat, mu);

Xhat(1,:)

Вихід:

5.083      3.5174      1.4032     0.21353

R

X = iris[,1:4]
mu = colMeans(X)

Xpca = prcomp(X)

nComp = 2
Xhat = Xpca$x[,1:nComp] %*% t(Xpca$rotation[,1:nComp])
Xhat = scale(Xhat, center = -mu, scale = FALSE)

Xhat[1,]

Вихід:

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
   5.0830390    3.5174139    1.4032137    0.2135317

Для відпрацьованого прикладу реконструкції зображень PCA див. Також цю відповідь .

Пітон

import numpy as np
import sklearn.datasets, sklearn.decomposition

X = sklearn.datasets.load_iris().data
mu = np.mean(X, axis=0)

pca = sklearn.decomposition.PCA()
pca.fit(X)

nComp = 2
Xhat = np.dot(pca.transform(X)[:,:nComp], pca.components_[:nComp,:])
Xhat += mu

print(Xhat[0,])

Вихід:

[ 5.08718247  3.51315614  1.4020428   0.21105556]

Зауважимо, що це дещо відрізняється від результатів інших мов. Це тому, що версія набору даних Iris у Python містить помилки .

Stata

webuse iris, clear
pca sep* pet*, components(2) covariance
predict _seplen _sepwid _petlen _petwid, fit
list in 1

  iris   seplen   sepwid   petlen   petwid    _seplen    _sepwid    _petlen    _petwid  
setosa      5.1      3.5      1.4      0.2   5.083039   3.517414   1.403214   .2135317  

1
У MATLAB ви можете отримати mu зі стандартних висновків PCA, а також зможете подавати кількість компонентів у входах.
Аксакал

2
@Aksakal Я намагався зробити усі три уривки коду максимально схожими (і максимально зрозумілими); зокрема, я хотів обчислити вручну перед викликом pca (), а також запустити PCA з усіма компонентами та використовувати лише компоненти при виконанні крапкового продукту між балами та власними векторами. Зараз я змінив код Python, щоб той самий зразок. μnComp
амеба

3
Я б зняв усе з відповіді, яка не пов’язана з прямою відповіддю на запитання, наприклад, зображення та милі дівчата. Якщо когось не цікавлять образи, це ускладнює споживання. Пам’ятайте, що той, хто задає питання, вже сильно розгублений.
Аксакал

5
Ленна - це такий же стандартний набір даних, як і райдужка.
Стаск

2
@amoeba Я говорив про розмір, бітову глибину, навіть чорні пікселі на межі. У мене немає остаточної версії http://www.ece.rice.edu/~wakin/images/ : "Схоже, існує багато версій тестового зображення Lena (він же" Lenna "). Цю проблему зазначив Шапіро в його документі про zerotree 1993 року, і це залишається напрочуд правдою сьогодні »
Лоран Дюваль
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.