Tengo 65 muestras de datos de 21 dimensiones (pegados aquí ) y estoy construyendo la matriz de covarianza a partir de ellos. Cuando se calcula en C ++, obtengo la matriz de covarianza pegada aquí . Y cuando se calcula en matlab a partir de los datos (como se muestra a continuación) obtengo la matriz de covarianza pegada aquí
Código de Matlab para calcular cov a partir de datos:
data = csvread('path/to/data');
matlab_cov = cov(data);
Como puede ver, la diferencia en las matrices de covarianza es minuto (~ e-07), lo que probablemente se deba a problemas numéricos en el compilador que usa aritmética de coma flotante.
Sin embargo, cuando calculo la matriz de covarianza pseudo-inversa de la matriz de covarianza producida por matlab y la producida por mi código C ++, obtengo resultados muy diferentes. Los estoy computando de la misma manera, es decir:
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);
La diferencia es tan grande que cuando calculo la distancia mahalanobis de una muestra (pegada aquí ) a la distribución de las 65 muestras por:
usando las diferentes matrices de covarianza inversa ( ) obtengo resultados muy diferentes, es decir:
(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
¿Es normal que las pequeñas diferencias (e-7) en la matriz de covarianza tengan tal efecto en el cálculo de la matriz pseudo-inversa? Y si es así, ¿qué puedo hacer para mitigar este efecto?
De lo contrario, ¿hay alguna otra métrica de distancia que pueda usar que no implique la covarianza inversa? Utilizo la distancia de Mahalanobis como sabemos para n muestras, sigue una distribución beta, que utilizo para la prueba de hipótesis
Muchas gracias de antemano
EDIT: Adición de código C ++ para el cálculo de matriz de covarianza a continuación:
El vector<vector<double> >
representa la colección de filas desde el archivo de pegado.
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;
}
}