当前位置:   article > 正文

PCA算法的原理以及c++实现_c++协方差矩阵求特征向量

c++协方差矩阵求特征向量

PCA主成分分析,是模式识别中常见的特征降维的算法,其大体步骤可以分为以下几个部分:

(1)原始特征矩阵归一化处理(假设M和样本,每个样本n个特征,则对M*N的X数据,进行零均值化,即减去这一列的均值)

(2)求取归一化处理后特征矩阵的协方差矩阵

(3)计算协方差矩阵的特征值及其对应的特征向量

(4)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P;

(5)Y=PX即为降维到k维后的数据;

数据类型:(保存到文本里面即可读取)

  1. 10 2
  2. 2.5 2.4
  3. 0.5 0.7
  4. 2.2 2.9
  5. 1.9 2.2
  6. 3.1 3.0
  7. 2.3 2.7
  8. 2.0 1.6
  9. 1.0 1.1
  10. 1.5 1.6
  11. 1.1 0.9

这里先贴出完整代码,后续有时间,会具体整理一下算法流程:

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdlib>
  4. #include<fstream>
  5. #include "Eigen/Dense"
  6. using namespace std;
  7. using namespace Eigen;
  8. void featurenormalize(MatrixXd &X)
  9. {
  10. //计算每一维度均值
  11. MatrixXd meanval = X.colwise().mean();
  12. RowVectorXd meanvecRow = meanval;
  13. //样本均值化为0
  14. X.rowwise() -= meanvecRow;
  15. }
  16. void computeCov(MatrixXd &X, MatrixXd &C)
  17. {
  18. //计算协方差矩阵C = XTX / n-1;
  19. C = X.adjoint() * X;
  20. C = C.array() / (X.rows() - 1);
  21. }
  22. void computeEig(MatrixXd &C, MatrixXd &vec, MatrixXd &val)
  23. {
  24. //计算特征值和特征向量,使用selfadjont按照对阵矩阵的算法去计算,可以让产生的vec和val按照有序排列
  25. SelfAdjointEigenSolver<MatrixXd> eig(C);
  26. vec = eig.eigenvectors();
  27. val = eig.eigenvalues();
  28. }
  29. int computeDim(MatrixXd &val)
  30. {
  31. int dim;
  32. double sum = 0;
  33. for (int i = val.rows() - 1; i >= 0; --i)
  34. {
  35. sum += val(i, 0);
  36. dim = i;
  37. if (sum / val.sum() >= 0.95)
  38. break;
  39. }
  40. return val.rows() - dim;
  41. }
  42. int main()
  43. {
  44. ifstream fin("test_data");
  45. ofstream fout("output.txt");
  46. //读取数据
  47. double a, b; fin >> a; fin >> b;
  48. std::cout << "pass " << a << " " << b << std::endl;
  49. const int m = a, n = b;
  50. MatrixXd X(m, n), C(n, n);
  51. MatrixXd vec, val;
  52. double in[200];
  53. for (int i = 0; i < m; ++i)
  54. {
  55. for (int j = 0; j < n; ++j)
  56. fin >> in[j];
  57. for (int j = 1; j <= n; ++j)
  58. X(i, j - 1) = in[j-1];
  59. }
  60. //pca
  61. //零均值化
  62. featurenormalize(X);
  63. //计算协方差
  64. computeCov(X, C);
  65. std::cout << "cov: \n" << C << std::endl;
  66. //计算特征值和特征向量
  67. computeEig(C, vec, val);
  68. //计算损失率,确定降低维数
  69. int dim = computeDim(val);
  70. std::cout << val << std::endl;
  71. std::cout << vec << std::endl;
  72. //计算结果
  73. MatrixXd res = X * vec.rightCols(n);
  74. //输出结果
  75. fout << "the result is " << res.rows() << "x" << res.cols() << " after pca algorithm." << endl;
  76. fout << res;
  77. fout.close();
  78. system("pause");
  79. return 0;
  80. }

 

参考:

https://blog.csdn.net/HLBoy_happy/article/details/77146012 

https://blog.csdn.net/Qer_computerscience/article/details/71246634?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/qq_36812406/article/details/80600068?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/watkinsong/article/details/38536463

https://blog.csdn.net/panhao762/article/details/55273789 

https://blog.csdn.net/zmdsjtu/article/details/77932176

https://blog.csdn.net/u010442908/article/details/81182405?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/222085
推荐阅读
相关标签
  

闽ICP备14008679号