J'ai 65 échantillons de données en 21 dimensions (collées ici ) et j'en construis la matrice de covariance. Lorsque calculé en C ++, je récupère la matrice de covariance collée ici . Et lorsque calculé dans matlab à partir des données (comme indiqué ci-dessous), je reçois la matrice de covariance collée ici
Code Matlab pour calculer la cov à partir des données:
data = csvread('path/to/data');
matlab_cov = cov(data);
Comme vous pouvez le voir, la différence dans les matrices de covariance est minuscule (~ e-07), ce qui est probablement dû à des problèmes numériques dans le compilateur utilisant l'arithmétique à virgule flottante.
Cependant, lorsque je calcule la matrice de covariance pseudo-inverse à partir de la matrice de covariance produite par matlab et celle produite par mon code C ++, j'obtiens des résultats très différents. Je les calcule de la même manière c'est à dire:
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 différence est si énorme que lorsque je calcule la distance mahalanobis d'un échantillon (collé ici ) à la distribution des 65 échantillons par:
en utilisant les différentes matrices de covariance inverse ( ) j'obtiens des résultats très différents c'est-à-dire:
(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
Est-il normal que les petites différences (e-7) de matrice de covariance aient un tel effet sur le calcul de la matrice pseudo-inverse? Et si oui, que puis-je faire pour atténuer cet effet?
À défaut, y a-t-il d'autres mesures de distance que je peux utiliser qui n'impliquent pas la covariance inverse? J'utilise la distance de Mahalanobis comme nous le savons pour n échantillons, elle suit une distribution bêta, que j'utilise pour les tests d'hypothèse
Merci d'avance
EDIT: Ajout de code C ++ pour calculer la matrice de covariance ci-dessous:
Le vector<vector<double> >
représente la collection de lignes du fichier collé.
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;
}
}