Ich habe 65 Stichproben von 21-dimensionalen Daten ( hier eingefügt ) und konstruiere daraus die Kovarianzmatrix. Bei der Berechnung in C ++ wird hier die Kovarianzmatrix eingefügt . Und wenn ich in Matlab aus den Daten berechnet werde (wie unten gezeigt), wird die Kovarianzmatrix hier eingefügt
Matlab-Code zur Berechnung von cov aus Daten:
data = csvread('path/to/data');
matlab_cov = cov(data);
Wie Sie sehen können, sind die Unterschiede in den Kovarianzmatrizen winzig (~ e-07), was wahrscheinlich auf numerische Probleme im Compiler mit Gleitkomma-Arithmetik zurückzuführen ist.
Wenn ich jedoch die pseudo-inverse Kovarianzmatrix aus der von matlab und der von meinem C ++ - Code erzeugten Kovarianzmatrix berechne, erhalte ich sehr unterschiedliche Ergebnisse. Ich berechne sie auf die gleiche Weise, dh:
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);
Der Unterschied ist so groß, dass bei der Berechnung des Mahalanobis-Abstands von einer Probe ( hier eingefügt ) zur Verteilung der 65 Proben durch:
Mit den verschiedenen inversen Kovarianzmatrizen ( ) erhalte ich sehr unterschiedliche Ergebnisse, dh:
(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
Ist es normal, dass die kleinen (e-7) Unterschiede in der Kovarianzmatrix einen solchen Effekt auf die Berechnung der pseudoinversen Matrix haben? Und wenn ja, was kann ich tun, um diesen Effekt abzuschwächen?
Wenn dies nicht gelingt, kann ich andere Entfernungsmetriken verwenden, die nicht die inverse Kovarianz beinhalten? Ich verwende den Mahalanobis-Abstand, da wir wissen, dass er für n Proben einer Beta-Verteilung folgt, die ich für Hypothesentests verwende
Vielen Dank im Voraus
BEARBEITEN: Hinzufügen von C ++ - Code zur Berechnung der Kovarianzmatrix unten:
Die vector<vector<double> >
repräsentiert die Sammlung von Zeilen aus der eingefügten Datei.
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;
}
}