Estou tentando fazer SVD manualmente:
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)
Mas a última linha não retorna m
. Por quê? Parece ter algo a ver com os sinais desses autovetores ... Ou entendi mal o procedimento?
r
svd
eigenvalues
failstatistician
fonte
fonte
D=diag(c(-1,1,1)*sqrt(eigen(m%*%t(m))$values))
faz e lembre-se de que a raiz quadrada (assim como qualquer vetor próprio normalizado) é definida apenas para assinar. Para obter mais informações, alterem
param <- matrix(-2,1,1)
e inclua,1,1)
no final de cada uma das chamadas paradiag
. Este é um exemplo que cria o mesmo problema - mas é tão simples que a natureza do problema se tornará completamente óbvia.c(-1,1,1)
funciona, masD
definido assim não está fornecendo valores singulares. Todos os valores singulares devem ser positivos por definição. A questão de como vincular os sinais deU
eV
é boa, e eu não tenho uma resposta. Por que você simplesmente não faz um SVD? :-)Respostas:
Análise do Problema
O SVD de uma matriz nunca é único. Deixe a matriz ter dimensões deixe que seu SVD sejan × kA n×k
para um matriz com colunas ortonormais, uma diagonal matriz com entradas não-negativos, e uma matriz com colunas ortonormais.U p × p D k × p Vn×p U p×p D k×p V
Agora escolha, arbitrariamente , qualquer diagonal matriz tendo s na diagonal, para que é a identidade . Entãop×p ± 1 S 2 = I p × p I pS ±1 S2=I p×p Ip
também é um SVD de porque demonstra que tem colunas ortonormais e um cálculo semelhante demonstra que o tem colunas ortonormais. Além disso, como e são diagonais, eles comutam, de onde mostra que ainda possui entradas não negativas.( U S ) ' ( U S ) = S ' L ' L S = S ' I P S = S ' S = S 2 = I P L S V S S D S D S = D S 2 = D DA
O método implementado no código para encontrar um SVD encontra um que diagonaliza e, da mesma forma, um que diagonaliza Ele procede ao cálculo de em termos dos valores próprios encontrados em . O problema é que isto não assegurar uma correspondência consistente das colunas de com as colunas de .A A ′ = ( U D V ′ ) ( U D V ′ ) ′ = U D V ′ V D ′ U ′ = U D 2 U ′ V A ' A = V D 2 V ′ . D D 2 U VU
Uma solução
Em vez disso, depois de encontrar um e um , use-os para calcularVU V
direta e eficientemente. Os valores diagonais deste não são necessariamente positivos.D (Isso ocorre porque não há nada sobre o processo de diagonalizar ou que garantirá que, uma vez que esses dois processos foram realizados separadamente.) Torne-os positivos escolhendo as entradas ao longo da diagonal de igualar os sinais das entradas de , para que tenha todos os valores positivos. Para compensar isso, multiplique por :A′A AA′ S D SD U S
Isso é um SVD.
Exemplo
Seja com . Um SVD én=p=k=1 A=(−2)
com , e .U=(1) D=(2) V=(−1)
Se você diagonalizar , naturalmente escolheria e . Da mesma forma, se você diagonalizar , escolheria . Infelizmente, Em vez disso, calcule Como isso é negativo, defina . Isso ajusta para e para . Você obteve que é um dos dois SVDs possíveis (mas não o mesmo que o original!).A′A=(4) U=(1) D=(4–√)=(2) AA′=(4) V=(1)
Código
Aqui está o código modificado. Sua saída confirma
m
corretamente.svd
. (Ambos são igualmente válidos.)fonte
U
ou outroV
e então obter outra matriz através da multiplicaçãoA
. Dessa maneira, é possível executar apenas uma (em vez de duas) composições automáticas, e os sinais sairão corretos.Como descrevi em um comentário à resposta do @ whuber, esse método para calcular o SVD não funciona para todas as matrizes . A questão não se limita a sinais.
O problema é que pode haver autovalores repetidos e, neste caso, a composição automática de e não é única e nem todas as opções de e podem ser usadas para recuperar o fator diagonal do SVD. Por exemplo, se você usar qualquer matriz ortogonal não diagonal (digamos, ), então . Entre todas as opções possíveis para a matriz de vetor próprio de , retornará , portanto, neste caso, não é diagonal.Um Um ' L V A = [ 3 / 5 4 / 5 - 4 / 5 3 / 5 ] Uma Um ' = A ' A = I I U = V = I L ' A V = AA′A AA′ U V A=[3/5−4/54/53/5] AA′=A′A=I I U=V=I U′AV=A
eigen
Intuitivamente, essa é outra manifestação do mesmo problema que o @whuber descreve, que deve haver uma "correspondência" entre as colunas de e , e calcular duas composições independentes separadamente não garante isso.VU V
Se todos os valores singulares de forem distintos, a composição automática é única (até escala / sinais) e o método funciona. Observação: ainda não é uma boa idéia usá-lo no código de produção em um computador com aritmética de ponto flutuante, porque quando você forma os produtos e o resultado calculado pode ser perturbado por uma quantidade da ordem de , onde é a precisão da máquina. Se as magnitudes dos valores singulares diferem bastante (mais de , aproximadamente), isso é prejudicial à precisão numérica dos menores.A A′A AA′ u ≈ 2 × 10 - 16 10 - 8∥A∥2u u≈2×10−16 10−8
A computação do SVD a partir das duas composições independentes é um ótimo exemplo de aprendizado, mas nas aplicações da vida real sempre use a
svd
função de R para calcular a decomposição de valor singular.fonte
svd
funciona. De fato, eles o usam como um padrão contra o qual comparar um cálculo manual, cujo objetivo é verificar o entendimento, e não substituir desvd
forma alguma.