当前位置:   article > 正文

机器学习算法PCA降维之c++实现(不调用外源库)_pca c++

pca c++

 目前玩机器学习的小伙伴,上来就是使用现有的sklearn机器学习包,写两行代码,调调参数就能跑起来,看似方便,实则有时不利于个人能力发展,要知道现在公司需要的算法工程师,不仅仅只是会调参(这种工作,入门几个月的人就可以干了),而是要深入底层,能优化代码,能自己搭。

本文章适合以下几类人:

1)初学者,了解机器学习的实现过程

2)想提升自己的代码能力

第一步:原理

什么是PCA?

PCA(Principal Component Analysis)是一种常用的数据降维算法,其主要思想是将高维数据映射到低维空间中,同时尽可能地保留原始数据的信息。PCA算法的具体实现步骤如下:

1. 对原始数据进行中心化处理,即将每个特征的均值都减去该特征的平均值,使得数据的均值为0。

2. 计算协方差矩阵,即将中心化后的数据进行矩阵乘法,得到一个n×n的协方差矩阵C。

3. 对协方差矩阵进行特征值分解,得到特征值和特征向量。

4. 将特征值按照从大到小的顺序排序,选择前k个特征值对应的特征向量作为新的基向量。

5. 将原始数据投影到新的基向量上,得到降维后的数据。

PCA算法的优点是可以减少数据的冗余信息,提高计算效率和降低存储空间。但是也存在一些缺点,例如对于非线性数据降维效果不佳等。

PCA的推导,百度一下很多,这里就做一下搬运工了,可参考:【机器学习】降维——PCA(非常详细) - 知乎

第二步:代码实现

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include "matrix.h"
  4. #include <map>
  5. using namespace std;
  6. /**
  7. * @brief 求实对称矩阵的特征值及特征向量的雅克比法
  8. * 利用雅格比(Jacobi)方法求实对称矩阵的全部特征值及特征向量
  9. * @param pMatrix 长度为n*n的数组,存放实对称矩阵
  10. * @param nDim 矩阵的阶数
  11. * @param pdblVects 长度为n*n的数组,返回特征向量(按列存储)
  12. * @param dbEps 精度要求
  13. * @param nJt 整型变量,控制最大迭代次数
  14. * @param pdbEigenValues 特征值数组
  15. * @return
  16. */
  17. bool JacbiCor(double * pMatrix,int nDim, double *pdblVects, double *pdbEigenValues, double dbEps,int nJt)
  18. {
  19. }
  20. //mean 均值 pdblVects特征向量 pdbEigenValues特征值 k为取前k个
  21. void pca(Matrix mean,Matrix pdblVects, int k, vector<double>&meanVal)
  22. {
  23. if (k > mean.row || k < 0)
  24. {
  25. cout<<"error"<<endl;
  26. exit(0);;
  27. }
  28. Matrix pcaVects;
  29. pcaVects.initMatrix(&pcaVects,mean.row,k);
  30. for (int i = 0; i < k; i++)
  31. {
  32. pcaVects = pcaVects.getOneRow(pdblVects,i);
  33. }
  34. pcaVects.print(pcaVects);
  35. Matrix lowData;
  36. //cout<<endl;
  37. lowData.initMatrix(&lowData,mean.col,pcaVects.row);
  38. //mean.print(mean);
  39. //cout<<endl;
  40. //转换成低维数据
  41. lowData.multsmatrix(&lowData,mean,pcaVects);
  42. lowData.print(lowData);
  43. //需要转换到相同的坐标里面
  44. Matrix reconMat;
  45. reconMat.initMatrix(&reconMat, mean.col,mean.row);
  46. Matrix pcaVectsT;
  47. pcaVectsT.initMatrix(&pcaVectsT,k,mean.row);
  48. pcaVectsT.transposematrix(pcaVects,&pcaVectsT);//转置
  49. reconMat.multsmatrix(&reconMat,lowData,pcaVectsT);
  50. //cout<<endl;
  51. //reconMat.print(reconMat);
  52. //加上平均值
  53. for (int i = 0; i < reconMat.col; i++)
  54. {
  55. for (int j = 0; j < reconMat.row; j++)
  56. {
  57. reconMat.mat[i][j] += meanVal[j];
  58. }
  59. }
  60. //cout<<endl;
  61. reconMat.print(reconMat);
  62. }
  63. int main()
  64. {
  65. dataToMatrix dtm;
  66. char file[30]="G:/data/pca.txt";
  67. dtm.loadData(&dtm,file);
  68. Matrix x;
  69. x.loadMatrix(&x,dtm);
  70. Matrix result;
  71. vector<double>meanVal;//存放均值,在降维数据之后,映射到原坐标有用到
  72. result = result.covMatrix(x,meanVal);
  73. // cout<<endl;
  74. // result.print(result);
  75. // cout<<endl;
  76. double *pMatrix = new double[result.row * result.row];
  77. for (int i = 0; i < result.row; i++)
  78. {
  79. for (int j = 0; j < result.row; j++)
  80. {
  81. pMatrix[i * result.row + j] = result.mat[i][j];
  82. }
  83. }
  84. double *pdblVects = new double[result.row * result.row];
  85. double *pdbEigenValues = new double[result.row];
  86. bool a = JacbiCor(pMatrix,2, pdblVects, pdbEigenValues, 0.0001,10000);
  87. //将数组转换到矩阵里面
  88. Matrix vectsMatrix;
  89. vectsMatrix.initMatrix(&vectsMatrix,result.row,result.row);
  90. for (int i = 0; i < result.row; i++)
  91. {
  92. for (int j = 0; j < result.row; j++)
  93. {
  94. vectsMatrix.mat[i][j] = pdblVects[i * result.row + j];
  95. }
  96. }
  97. vectsMatrix.print(vectsMatrix);
  98. pca(x,vectsMatrix, 1, meanVal);
  99. return 0;
  100. }

第三步:运行过程

运行结果

​用到的软件是vs2010以上的版本都可以,不用额外配置什么,没调包,会用这个软件进行c++开发,就会使用这个软件

此程序由于不调用任何外源库,所以读者可以看清楚每一个算法的原理,要想学好机器学习算法,必须打好基础,不要好高骛远,另外,程序都是有备注,应该很好理解的,实在不懂,可以来问店主

代码的下载路径(新窗口打开链接)机器学习算法PCA降维之c++实现(不调用外源库)

有问题可以私信或者留言,有问必答

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号