Разложение по сингулярным значениям (SVD) с R
SVD хорошо работает с R:
A = matrix(1:12,3,4)
A
u = svd(A)$u
v = svd(A)$v
sigma = diag(svd(A)$d)
u %*% sigma %*% t(v) # = A as desired
Но в отличие от обычной формулировки теоремы СВД, v
это не матрица 4х4 (так и должно быть!):
dim(v) # (4,3)
Почему это так?
Согласно теореме
v
должен иметь формат (4,4),sigma
должен иметь формат (3,4).
Кстати, что было бы кратчайшим способом создатьdiag(svd(A)$d)
дополнен нулями, чтобы иметь формат (3,4)?
3 ответа
Решение
Чтобы получить полные матрицы U и V, используйте nu=
а также nv=
аргументы svd()
, Чтобы заполнить диагональную матрицу нулями, используйте nrow=
а также ncol=
аргументы diag()
:
A <- matrix(1:12,3,4)
D <- svd(A, nu=nrow(A), nv=ncol(A))
u <- D$u
v <- D$v
sigma <- diag(D$d, nrow=nrow(A), ncol=ncol(A))
## Check that that worked:
dim(u)
# [1] 3 3
dim(v)
# [1] 4 4
dim(sigma)
# [1] 3 4
u %*% sigma %*% t(v)
# [,1] [,2] [,3] [,4]
# [1,] 1 4 7 10
# [2,] 2 5 8 11
# [3,] 3 6 9 12
Это просто другое соглашение, разные системы / учебники будут определять SVD так или иначе. Важная вещь - унитарная собственность U*U'=I
, В любом соглашении сингулярные векторы будут минимизировать наименьшие квадраты расстояний в проекции.
Вот развитие теории, которая имеет соглашения об измерениях так же, как в LINPACK и R: https://www.cs.princeton.edu/courses/archive/spring12/cos598C/svdchapter.pdf