我想从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