Eu tenho 65 amostras de dados 21-dimensionais (colados aqui ) e estou construindo a matriz de covariância a partir dele. Quando computado em C ++, recebo a matriz de covariância colada aqui . E quando computado no Matlab a partir dos dados (como mostrado abaixo), recebo a matriz de covariância colada aqui
Código Matlab para computação cov a partir de dados:
data = csvread('path/to/data');
matlab_cov = cov(data);
Como você pode ver, as diferenças nas matrizes de covariância são mínimas (~ e-07), o que provavelmente se deve a problemas numéricos no compilador usando aritmética de ponto flutuante.
No entanto, quando computo a matriz de covariância pseudo-inversa da matriz de covariância produzida pelo matlab e a produzida pelo meu código C ++, obtenho resultados amplamente diferentes. Estou computando-os da mesma maneira, ou seja:
data = csvread('path/to/data');
matlab_cov = cov(data);
my_cov = csvread('path/to/cov_file');
matlab_inv = pinv(matlab_cov);
my_inv = pinv(my_cov);
A diferença é tão grande que, quando estou computando a distância dos mahalanobis de uma amostra (colada aqui ) até a distribuição das 65 amostras por:
usando as diferentes matrizes de covariância inversa ( ), obtenho resultados amplamente diferentes, ou seja:
(65/(64^2))*((sample-sample_mean)*my_inv*(sample-sample_mean)')
ans =
1.0167e+05
(65/(64^2))*((sample-sample_mean)*matlab_inv*(sample-sample_mean)')
ans =
109.9612
É normal que as pequenas diferenças (e-7) na matriz de covariância tenham esse efeito no cálculo da matriz pseudo-inversa? E se sim, o que posso fazer para mitigar esse efeito?
Caso contrário, existem outras métricas de distância que eu possa usar que não envolvam a covariância inversa? Eu uso a distância de Mahalanobis como sabemos para n amostras segue uma distribuição beta, que eu uso para testes de hipóteses
Muito obrigado antecipadamente
EDIT: Adicionando código C ++ para calcular a matriz de covariância abaixo:
O vector<vector<double> >
representa a coleção de linhas do arquivo colado.
Mat covariance_matrix = Mat(21, 21, CV_32FC1, cv::Scalar(0));
for(int j = 0; j < 21; j++){
for(int k = 0; k < 21; k++){
for(std::vector<vector<double> >::iterator it = data.begin(); it!= data.end(); it++){
covariance_matrix.at<float>(j,k) += (it->at(j) - mean.at(j)) * (it->at(k) - mean[k]);
}
covariance_matrix.at<float>(j,k) /= 64;
}
}