我想從C++的數據集中計算2個主要成分與特徵。用特徵庫進行主成分分析
我現在這樣做的方法是對[0, 1]
之間的數據進行規範化處理,然後將中間值居中。之後,我計算協方差矩陣並對其進行特徵值分解。我知道SVD速度更快,但我對計算組件感到困惑。
這裏是我是如何做到這一點(其中traindata
是我的M×N的大小的輸入矩陣)的主要代碼:
Eigen::VectorXf normalize(Eigen::VectorXf vec) {
for (int i = 0; i < vec.size(); i++) { // normalize each feature.
vec[i] = (vec[i] - minCoeffs[i])/scalingFactors[i];
}
return vec;
}
// Calculate normalization coefficients (globals of type Eigen::VectorXf).
maxCoeffs = traindata.colwise().maxCoeff();
minCoeffs = traindata.colwise().minCoeff();
scalingFactors = maxCoeffs - minCoeffs;
// For each datapoint.
for (int i = 0; i < traindata.rows(); i++) { // Normalize each datapoint.
traindata.row(i) = normalize(traindata.row(i));
}
// Mean centering data.
Eigen::VectorXf featureMeans = traindata.colwise().mean();
Eigen::MatrixXf centered = traindata.rowwise() - featureMeans;
// Compute the covariance matrix.
Eigen::MatrixXf cov = centered.adjoint() * centered;
cov = cov/(traindata.rows() - 1);
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eig(cov);
// Normalize eigenvalues to make them represent percentages.
Eigen::VectorXf normalizedEigenValues = eig.eigenvalues()/eig.eigenvalues().sum();
// Get the two major eigenvectors and omit the others.
Eigen::MatrixXf evecs = eig.eigenvectors();
Eigen::MatrixXf pcaTransform = evecs.rightCols(2);
// Map the dataset in the new two dimensional space.
traindata = traindata * pcaTransform;
這段代碼的結果是這樣的:
爲了確認我的結果,我嘗試了WEKA。所以我所做的就是按照這個順序使用標準化和中心過濾器。然後主要組件過濾並保存並繪製輸出。結果是這樣的:
技術上我應該做的是相同的,但結果是如此不同。任何人都可以看到我是否犯了一個錯誤?
有一點需要補充:我很確定WEKA正在使用SVD。但是這不應該解釋結果的差異還是? – Chris