Как изменить порядок SVD с помощью numpy python - PullRequest
0 голосов
/ 08 сентября 2018

Я использую разложение по сингулярным числам (SVD) для анализа основных компонентов (PCA) изображений.

У меня 17 изображений размером 20 на 20 поэтому я создал изображения матрицы

M =  dim(400 X 17)

и когда я применяю SVD (M = u @ d @ v), это дает мне

u = dim(400 X 17)
d = dim(17 X 17)   
v = dim(17 X 17)

но я хочу найти u = dim(400 X 400) и d =(400 X 400) и v =(400 X 17), потому что будет 400 собственных векторов и 400 собственных значений.

Я даже пытался сделать транспонирование, но не повезло

Я знаю, что, возможно, название вопроса не очень понятно, поэтому, пожалуйста, измените его, как вам угодно, и вот некоторая информация, связанная с данными

  1. Я централизовал данные путем вычитания среднего лица

  2. Я пытался обойти, найдя собственные векторы ковариационной матрицы (MM '), но когда я попытался показать PCA1, он показывает только черное изображение

Пожалуйста, помогите мне

1 Ответ

0 голосов
/ 08 сентября 2018

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

SVD относится к разложению по собственным значениям MM' и M'M

  • M'M = V (S'S) V'
  • MM' = U (SS') U'

сейчас

  • Столбцы V являются собственными векторами M'M, который имеет размер (17 x 17) в вашем случае. Следовательно, V равно (17 x 17)
  • Столбцы U являются собственными векторами MM', что в вашем случае имеет размер (400 x 400). Следовательно, U равно (400 x 400)

Каков размер S? Ненулевые элементы S (особые значения) являются квадратными корнями ненулевых собственных значений M'M и MM'. Можно показать, что эти два имеют одинаковые наборы ненулевых собственных значений, поэтому в первом случае S равен (17 x 17), а во втором случае (400 x 400). Как мы можем согласовать это с тем фактом, что у нас SVD M = USV'? Мы строим прямоугольную диагональную матрицу (400 x 17) с квадратными корнями из 17 ненулевых собственных значений.

Вы можете использовать SVD с scipy:

import scipy

u, s, vh = scipy.linalg.svd(M, full_matrices=True)
print(u.shape, s.shape, vh.shape)

что дает

((400, 400), (17,), (17, 17))

Чтобы получить S до (400 x 17):

s = np.concatenate([np.diag(s), np.zeros((400-17, 17))], axis=0)

Проверьте правильность SVD:

res = u@s@vh
np.allclose(res, a)

True

аппроксимация матрицы низкого ранга

Иногда вы хотите приблизить вашу матрицу M с низким рангом M_tilde ранга r, в этом случае, если вы хотите минимизировать норму Фробениуса между двумя, вы просто сохраняйте r наибольшие сингулярные значения (теорема Экхарта-Юнга). Размеры U, S, V становятся: (400 x r), (r x r), (r x 17), где S - диагональ.

Я не знаю, какую функцию вы используете, но это то, что происходит: нулевые единичные значения отбрасываются, поскольку матрица (m x n) может иметь не более ранга min(m, n) (в вашем случае 17) .

...