Saya memiliki 65 sampel data 21 dimensi (disisipkan di sini ) dan saya membuat matriks kovarians. Ketika dihitung dalam C ++ saya mendapatkan matriks kovarians disisipkan di sini . Dan ketika dihitung dalam matlab dari data (seperti yang ditunjukkan di bawah ini) saya mendapatkan matriks kovarians yang disisipkan di sini
Kode Matlab untuk menghitung cov dari data:
data = csvread('path/to/data');
matlab_cov = cov(data);
Seperti yang Anda lihat perbedaan dalam matriks kovarian adalah menit (~ e-07), yang mungkin disebabkan oleh masalah numerik dalam kompiler menggunakan aritmatika floating point.
Namun, ketika saya menghitung matriks kovarians semu-terbalik dari matriks kovarians yang diproduksi oleh matlab dan yang dihasilkan oleh kode C ++ saya, saya mendapatkan hasil yang sangat berbeda. Saya menghitungnya dengan cara yang sama yaitu:
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);
Perbedaannya sangat besar sehingga ketika saya menghitung jarak mahalanobis dari sampel (disisipkan di sini ) ke distribusi 65 sampel dengan:
menggunakan matriks kovarians terbalik yang berbeda ( ) Saya mendapatkan hasil yang sangat berbeda yaitu:
(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
Apakah normal jika perbedaan kecil (e-7) dalam matriks kovarians memiliki efek pada perhitungan matriks pseudo-invers? Dan jika demikian, apa yang bisa saya lakukan untuk mengurangi efek ini?
Gagal ini, apakah ada metrik jarak lain yang dapat saya gunakan yang tidak melibatkan kovarians terbalik? Saya menggunakan jarak Mahalanobis seperti yang kita tahu untuk n sampel itu mengikuti distribusi beta, yang saya gunakan untuk pengujian hipotesis
Banyak terima kasih sebelumnya
EDIT: Menambahkan C ++ kode untuk menghitung kovarians matriks di bawah ini:
The vector<vector<double> >
mewakili koleksi baris dari file disisipkan.
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;
}
}