用c++实现pca算法
时间: 2023-08-04 07:34:22 浏览: 102
PCA(Principal Component Analysis)是一种经典的线性降维算法,可以用来降低数据的维度,从而更好地进行数据分析和可视化。下面是用C++实现PCA算法的示例代码:
```
#include <iostream>
#include <vector>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
// 计算均值向量
VectorXd mean(vector<VectorXd>& data) {
VectorXd meanVec(data[0].size());
meanVec.setZero();
for (int i = 0; i < data.size(); i++) {
meanVec += data[i];
}
meanVec /= data.size();
return meanVec;
}
// 计算协方差矩阵
MatrixXd covariance(vector<VectorXd>& data, VectorXd& meanVec) {
MatrixXd covMat(data[0].size(), data[0].size());
covMat.setZero();
for (int i = 0; i < data.size(); i++) {
VectorXd diff = data[i] - meanVec;
covMat += diff * diff.transpose();
}
covMat /= data.size();
return covMat;
}
// 计算特征值和特征向量
void eig(MatrixXd& mat, VectorXd& eigVals, MatrixXd& eigVecs) {
EigenSolver<MatrixXd> solver(mat);
eigVals = solver.eigenvalues().real();
eigVecs = solver.eigenvectors().real();
}
// 选择前k个主成分,并返回新的数据矩阵
MatrixXd pca(vector<VectorXd>& data, int k) {
VectorXd meanVec = mean(data);
MatrixXd covMat = covariance(data, meanVec);
VectorXd eigVals;
MatrixXd eigVecs;
eig(covMat, eigVals, eigVecs);
// 按特征值大小排序
vector<pair<double, VectorXd>> eigPairs;
for (int i = 0; i < eigVals.size(); i++) {
eigPairs.push_back(make_pair(eigVals[i], eigVecs.col(i)));
}
sort(eigPairs.begin(), eigPairs.end(), [](const pair<double, VectorXd>& x, const pair<double, VectorXd>& y) {return x.first > y.first;});
// 选择前k个主成分
MatrixXd newMat(data.size(), k);
for (int i = 0; i < k; i++) {
newMat.col(i) = eigPairs[i].second;
}
// 将数据投影到新的空间中
MatrixXd newData = (data[0] - meanVec).transpose() * newMat;
for (int i = 1; i < data.size(); i++) {
newData.conservativeResize(newData.rows(), newData.cols() + 1);
newData.rightCols<1>() = (data[i] - meanVec).transpose() * newMat;
}
return newData;
}
int main() {
vector<VectorXd> data;
data.push_back(VectorXd(3));
data[0] << 1, 2, 3;
data.push_back(VectorXd(3));
data[1] << 4, 5, 6;
data.push_back(VectorXd(3));
data[2] << 7, 8, 9;
MatrixXd newData = pca(data, 2);
cout << newData << endl;
return 0;
}
```
这段代码实现了一个简单的PCA算法,可以将一个三维数据集降至二维,并输出降维后的数据。具体实现步骤为:
1. 计算均值向量
2. 计算协方差矩阵
3. 计算特征值和特征向量
4. 选择前k个主成分,并返回新的数据矩阵
5. 将数据投影到新的空间中
需要注意的是,在实现中使用了Eigen库来进行矩阵计算,需要提前安装Eigen库。
阅读全文