Existe alguma biblioteca / caixa de ferramentas que tenha implementação de SVD incremental no MATLAB. Eu implementei este documento , é rápido, mas não funciona bem. Eu tentei isso, mas neste erro também se propaga rapidamente (dentro de atualização de 5 a 10 pontos, o erro é alto).
Sim. Christopher Baker implementou seu método incremental de SVD em um pacote MATLAB chamado IncPACK ( arquivado no GitHub, dentro do projeto imtsl ). Implementa métodos descritos na tese de mestrado . Uma breve discussão sobre por que o algoritmo de Brand tende a acumular erros pode ser encontrada em um artigo de 2012 de Baker et al . Um método relacionado de Chahlaoui et al. Discute limites de erro no subespaço singular esquerdo e os valores singulares.
Eu já mencionei esses pontos nos comentários sobre a resposta de Stephen, mas vale a pena repetir que os métodos por tanto Baker e por escala Chahlaoui como para um truncada rank SVD de um por matriz . Para aproximações de baixa classificação, o termo domina e, dependendo da variante do algoritmo, possui uma constante líder que geralmente está entre 8 e 12.k m n m n kO ( m n k + n k3)kmnm n k
Como a resposta de Stephen, o algoritmo de Chahlaoui começa com uma fatoração QR. A resposta de Stephen irá funcionar para calcular os vectores singulares esquerda, mas uma densa SVD do matriz teria complexidade superlinear em e antes da truncagem (que seria ), o que provavelmente iria reduzir a eficiência, mas seja mais preciso.m n O ( m n 2 )RmnO ( m n2)
Pelo que vale a pena, eu mesmo implementei o algoritmo de Brand e é um pouco sensível à tolerância interna do produto usada para o truncamento de classificação. Eu não usei o pacote de Baker, mas acredito que seria melhor, porque existem estimativas de erro para o algoritmo de Baker (ou um relacionado a ele) e não para o algoritmo de Brand, e porque a tolerância de truncamento de classificação para o algoritmo de Baker está em valores singulares, não internos produtos.
Eu verifiquei o pacote IncPACK, embora tenha a função seqkl_update, não parece aceitar nenhum parâmetro para novas linhas e colunas. Também do resumo do artigo (pode não estar correto, eu preciso ler tudo), parece que é uma abordagem de várias etapas que eles chamam de incremental.
pj
Baker discute as abordagens de passagem única e de passagem múltipla. A seqklfunção parece ser a principal e possui opções para passes únicos e múltiplos. Uma única passagem é fornecida por seqkl_stdpass, que chama seqkl_update, então você provavelmente desejaria usar seqklpara uma fatoração inicial, seguida por chamadas seqkl_updatepara atualizações de coluna.
Geoff Oxberry
Sim, até agora o que eu descobri é que ele tem apenas atualização de coluna, novos dados Ai são armazenados em U (1: m, o: op) que é um comentário do arquivo seqkl_update. Mas e a atualização de linha?
pj
@pj Pelo que li, a maior parte da literatura foca em atualizações de colunas. Se possível, você poderia calcular o SVD da transposição de sua matriz; no entanto, reconheço que ter de transpor seus dados pode não ser uma opção. Presumo que o algoritmo possa ser reexpresso em termos de atualizações de linha, mas isso pode exigir um pouco de trabalho.
precisa
Os dois primeiros links estão mortos.
Joel Sjögren
4
Um método para calcular o svd de uma matriz Xé o primeiro fator X=QRusando a decomposição QR (para estabilidade, use pivotamento, portanto, isso está [Q,R,E] = qr(X,0)no Matlab) e depois calcule o svd de R. Se a matriz for muito retangular em qualquer um deles, o cálculo mais caro é a fatoração QR.
Portanto, se você incrementar sua matriz Xcom outra linha ou coluna (é isso que você quis dizer, certo?), Basta atualizar a fatoração QR com a qrinsertfunção Matlab e refazer o cálculo SVD de R.
Se você tiver uma matriz quadrada grande, esse método não seria tão útil, pois refazer o SVD de Rconsumirá muito tempo.
Isso é rápido apenas para um svd de baixo nível, certo?
dranxo
@ Stephen Sim, é isso que eu quero, adicione uma coluna e uma linha (que está adicionando um ponto de dados para mim). Eu acho que os métodos que eu tentei também fazem o QR inicialmente e depois atualizam. Minha maior preocupação é o erro. O que eu notei é que o svd para pontos antigos que não deve mudar muito, após 5-6 atualizações incrementais é corrompido com um erro enorme, o mesmo acontece com novos pontos.
pj
RXk do SVD truncado desejado.
precisa
@ GeoffOxberry, foi o que eu disse: se você tem uma matriz quadrada, isso não é eficiente. I mencionar isso, porque muitas vezes você tem uma matriz magra / gordura, e este algoritmo pode ser implementado trivialmente usando funções existentes em Matlab
Stephen
@dranxo, bem, se você é muito retangular, é relativamente rápido. Não é tão rápido como um verdadeiro SVD incremental, mas se você é muito retangular, o custo da SVD interior é trivial, e você pode equilibrar isso com a facilidade de implementação
Stephen
4
Aqui está um método que pode lidar com adições de coluna: http://pcc.byu.edu/resources.html . Eu atualizei para lidar com adições de linha:
Uma alternativa ao SVD Incremental é o HAPOD de Decomposição Ortogonal Aproximada Aproximada Hierárquica , cuja implementação pode ser encontrada no github: http://git.io/hapod . O HAPOD possui limites de erro rigorosos e um caso especial é uma variante incremental.
seqkl
função parece ser a principal e possui opções para passes únicos e múltiplos. Uma única passagem é fornecida porseqkl_stdpass
, que chamaseqkl_update
, então você provavelmente desejaria usarseqkl
para uma fatoração inicial, seguida por chamadasseqkl_update
para atualizações de coluna.Um método para calcular o svd de uma matriz
X
é o primeiro fatorX=QR
usando a decomposição QR (para estabilidade, use pivotamento, portanto, isso está[Q,R,E] = qr(X,0)
no Matlab) e depois calcule o svd deR
. Se a matriz for muito retangular em qualquer um deles, o cálculo mais caro é a fatoração QR.Portanto, se você incrementar sua matriz
X
com outra linha ou coluna (é isso que você quis dizer, certo?), Basta atualizar a fatoração QR com aqrinsert
função Matlab e refazer o cálculo SVD deR
.Se você tiver uma matriz quadrada grande, esse método não seria tão útil, pois refazer o SVD de
R
consumirá muito tempo.fonte
X
Aqui está um método que pode lidar com adições de coluna: http://pcc.byu.edu/resources.html . Eu atualizei para lidar com adições de linha:
Teste com
Você verá os resultados U, S, V de ambos os lados.
Também a versão Python,
fonte
Uma alternativa ao SVD Incremental é o HAPOD de Decomposição Ortogonal Aproximada Aproximada Hierárquica , cuja implementação pode ser encontrada no github: http://git.io/hapod . O HAPOD possui limites de erro rigorosos e um caso especial é uma variante incremental.
fonte