Antecedentes e problema
Estou usando Processos Gaussianos (GP) para regressão e subsequente otimização bayesiana (BO). Para regressão, uso o pacote gpml do MATLAB com várias modificações personalizadas, mas o problema é geral.
É um fato bem conhecido que, quando duas entradas de treinamento estão muito próximas no espaço de entrada, a matriz de covariância pode se tornar definitiva não positiva (há várias perguntas sobre isso neste site). Como resultado, a decomposição de Cholesky da matriz de covariância, necessária para vários cálculos de GP, pode falhar devido a erro numérico. Isso aconteceu comigo em vários casos ao executar o BO com as funções objetivas que estou usando e gostaria de corrigi-lo.
Soluções propostas
AFAIK, a solução padrão para aliviar o mau condicionamento é adicionar uma crista ou pepita à diagonal da matriz de covariância. Para a regressão GP, isso equivale a adicionar (ou aumentar, se já estiver presente) ruído de observação.
Por enquanto, tudo bem. Modifiquei o código para inferência exata de gpml, para que, sempre que a decomposição de Cholesky falhe, tento fixar a matriz de covariância na matriz simétrica positiva definida (SPD) mais próxima na norma Frobenius, inspirada neste código MATLAB de John d'Errico. A lógica é minimizar a intervenção na matriz original.
Essa solução alternativa faz o trabalho, mas notei que o desempenho do BO reduziu substancialmente para algumas funções - possivelmente sempre que o algoritmo precisasse aumentar o zoom em alguma área (por exemplo, porque ele está se aproximando do mínimo ou porque o comprimento é menor) do problema se tornar não uniformemente pequeno). Esse comportamento faz sentido, pois estou aumentando efetivamente o ruído sempre que dois pontos de entrada se aproximam demais, mas é claro que não é o ideal. Como alternativa, eu poderia remover pontos problemáticos, mas, novamente, às vezes preciso que os pontos de entrada estejam próximos.
Questão
Não acho que problemas numéricos com a fatoração de Cholesky das matrizes de covariância de GP sejam um problema novo, mas para minha surpresa não consegui encontrar muitas soluções até agora, além de aumentar o ruído ou remover pontos muito próximos um do outro. Por outro lado, é verdade que algumas das minhas funções são muito mal comportadas, então talvez minha situação não seja tão típica.
Alguma sugestão / referência que possa ser útil aqui?