Почему я не могу получить действительный SVD X через разложение по собственным значениям XX 'и X'X?


9

Я пытаюсь сделать SVD вручную:

m<-matrix(c(1,0,1,2,1,1,1,0,0),byrow=TRUE,nrow=3)

U=eigen(m%*%t(m))$vector
V=eigen(t(m)%*%m)$vector
D=sqrt(diag(eigen(m%*%t(m))$values))

U1=svd(m)$u
V1=svd(m)$v
D1=diag(svd(m)$d)

U1%*%D1%*%t(V1)
U%*%D%*%t(V)

Но последняя строка не возвращается mобратно. Почему? Кажется, что-то связано с признаками этих собственных векторов ... Или я неправильно понял процедуру?



Мне неоднократно говорили, что знак не имеет значения в СВД ... вот так
провалстатик

@ Amoeba Спасибо за разъяснение этого. Я сосредоточился на английском вопросе, а не на коде. Failedstatistician: посмотрите, что D=diag(c(-1,1,1)*sqrt(eigen(m%*%t(m))$values))делает и имейте в виду, что квадратный корень (как и любой нормализованный собственный вектор) определяется только с точностью до знака. Для получения более подробной информации, измените mна m <- matrix(-2,1,1)и включите ,1,1)в конце каждого из вызовов diag. Это пример который создает ту же проблему - но он настолько прост, что природа проблемы станет совершенно очевидной. 1×1
whuber

1
Понял. Спасибо! Есть ли у вас общее правило определения вектора c (-1, 1, 1)? Или как признаки двух разложения должны быть связаны?
провалстатик

1
Обратите внимание, что трюк @ whuber с c(-1,1,1)работает, но Dопределенный таким образом не дает вам единичные значения. Все значения в единственном числе должны быть положительными по определению. Вопрос о том, как связать признаки Uи Vхорош, а у меня нет ответа. Почему бы вам просто не сделать SVD? :-)
амеба

Ответы:


13

Анализ проблемы

СВД матрицы никогда не бывает уникальным. Пусть матрица имеет размерыn × k, и пусть его SVD будетAn×k

A=UDV

для матрицы U с ортонормированными столбцами, диагональной p × p- матрицы D с неотрицательными элементами и k × p- матрицы V с ортонормированными столбцами.n×pUp×pDk×pV

Теперь произвольно выбираем любую диагональную матрицу S, имеющую ± 1 s на диагонали, так что S 2 = I является тождеством p × p I p . затемp×pS±1S2=Ip×pIp

A=UDV=UIDIV=U(S2)D(S2)V=(US)(SDS)(VS)

Также СВД из А , потому что ( U S ) ' ( U S ) = S ' U ' U S = S ' Я р S = S ' S = S 2 = я р демонстрирует U S имеет ортонормированные столбцы и аналогичный расчет показывает V S имеет ортонормированные столбцы. Более того, поскольку S и D диагональны, они коммутируют, откудаA

(US)'(US)знак равноS'U'USзнак равноS'япSзнак равноS'Sзнак равноS2знак равнояп
USВSSD показывает, что D все еще имеет неотрицательные записи.
SDSзнак равноDS2знак равноD
D

Метод, реализованный в коде для поиска SVD, находит который диагонализирует A A = ( U D V ) ( U D V ) = U D V V D U = U D 2 U и, аналогично, A V, который диагонализирует A ' A = V D 2 V ' . Он продолжает вычислять DU

AA'знак равно(UDВ')(UDВ')'знак равноUDВ'ВD'U'знак равноUD2U'
В
A'Aзнак равноВD2В',
Dв терминах собственных значений, найденных в . Проблема заключается в следующем не гарантирует последовательное согласование столбцов U со столбцами V .D2UВ

Решение

Вместо этого, после нахождения такого и такого V , используйте их для вычисленияUВ

U'AВзнак равноU'(UDВ')Взнак равно(U'U)D(В'В)знак равноD

DA'AAA'SDSDUS

Aзнак равноUDВ'знак равно(US)(SD)В',

Это СВД.

пример

Nзнак равнопзнак равноКзнак равно1Aзнак равно(-2)

(-2)знак равно(1)(2)(-1)

Uзнак равно(1)Dзнак равно(2)Взнак равно(-1)

A'Aзнак равно(4)Uзнак равно(1)Dзнак равно(4)знак равно(2)AA'знак равно(4)Взнак равно(1)

UDВ'знак равно(1)(2)(1)знак равно(2)A,
Dзнак равноU'AВзнак равно(1)'(-2)(1)знак равно(-2),
Sзнак равно(-1)UUSзнак равно(1)(-1)знак равно(-1)DSDзнак равно(-1)(-2)знак равно(2)
Aзнак равно(-1)(2)(1),

Код

Вот модифицированный код. Его вывод подтверждает

  1. Метод воссоздает mправильно.
  2. UВ
  3. Но результат не тот же SVD, возвращенный svd. (Оба одинаково действительны.)
m <- matrix(c(1,0,1,2,1,1,1,0,0),byrow=TRUE,nrow=3)

U <- eigen(tcrossprod(m))$vector
V <- eigen(crossprod(m))$vector
D <- diag(zapsmall(diag(t(U) %*% m %*% V)))
s <- diag(sign(diag(D)))  # Find the signs of the eigenvalues
U <- U %*% s              # Adjust the columns of U
D <- s %*% D              # Fix up D.  (D <- abs(D) would be more efficient.)

U1=svd(m)$u
V1=svd(m)$v
D1=diag(svd(m)$d,n,n)

zapsmall(U1 %*% D1 %*% t(V1)) # SVD
zapsmall(U %*% D %*% t(V))    # Hand-rolled SVD
zapsmall(crossprod(U))        # Check that U is orthonormal
zapsmall(tcrossprod(V))       # Check that V' is orthonormal

1
+1. Это очень ясно. Я бы только добавил, что на практике достаточно вычислить либо, Uлибо Vзатем получить другую матрицу путем умножения на A. Таким образом, каждый выполняет только одно (вместо двух) собственных разложений, и знаки получатся правильными.
амеба

2
@Amoeba Это верно: в духе ручного вычисления SVD, которое, очевидно, является образовательным упражнением, здесь не уделяется внимания эффективности.
whuber

2
Спасибо за вашу помощь! Я думаю, что я понимаю эту проблему (наконец).
провалстатик

3
@Federico Спасибо за это напоминание. Вы совершенно правы - я неявно предположил, что все собственные значения различны, поскольку в статистических приложениях это почти наверняка будет иметь место, и у вас появляется привычка рассматривать неоднозначности с "вырожденными" собственными пространствами.
whuber

3
UВ

5

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

A'AAA'UВAзнак равно[3/54/5-4/53/5]AA'знак равноA'Aзнак равнояяeigenUзнак равноВзнак равнояU'AВзнак равноA

UВ

AA'AAA'| |A| |2UU2×10-1610-8

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


1
Этот комментарий - хороший совет. Обратите внимание, однако, что этот поток не заботится о правильном способе вычисления SVD (и я полагаю, что никто не станет спорить с вашей рекомендацией). ОП неявно принимает, что svdработает. Действительно, они используют его в качестве стандарта для сравнения ручного расчета, целью которого является проверка понимания, а не замена svdв любом случае.
whuber

@whuber Правильное наблюдение; Я перефразировал последний абзац.
Федерико Полони,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.