当前位置:   article > 正文

PCA 降维优化(C++实现)_降维pca c++

降维pca c++

前段时间写了一个HOG+PCA降维,在进行随机森林训练的时候,说得知道降维后信息保留了多少,以及得把降维后所有特征的重要性进行排序,于是删删改改终于解决了!

PCA的简单原理参见另一篇博客

HOG+PCA(C++实现)


代码及解释
Mat pca_1(MatrixXd samFeatureMatrix, int featureNum, int k){
      // samFeatureMatrix 为原始矩阵
     // featureNum 为图像原始特征维度大小
     // k 为可选的降维大小

	 //复制一份原始矩阵,便于后续得到投影矩阵后进行相乘得到最终结果
    MatrixXd X = samFeatureMatrix; 

    // 去均值化
    RowVectorXd meanVecRow = X.colwise().mean();
    X.rowwise() -= meanVecRow;

    // 计算协方差矩阵
    MatrixXd cov = X.transpose()*X / X.rows();

	// 划重点,eigen库中在定义时可以直接调用,达到自动排序的目的,但注意是从小到大排序
    SelfAdjointEigenSolver<MatrixXd> solver(cov); //有序排列
    
    //调用库直接计算特征值和特征向量
    MatrixXd eigenValues = solver.eigenvalues();
    MatrixXd eigenVectors = solver.eigenvectors();
    
	//需要查看的话,直接cout即可
    cout << eigenValues << endl;

    //计算可降维的维度以及保留信息的程度
    // 大致思路是 降维后的特征值平方和 与 原始矩阵的特征值平方和 相除,可以估计出特征损失,也可根据特征向量的差来实现
    int dim;
    double sum = 0;
    // 简单的 for 求和,知道满足条件,输出结果
    for (int i = eigenValues.rows()-1; i >= 0; --i)
    {
        sum += eigenValues(i, 0);
        dim = i;

        if (sum / eigenValues.sum() >= 0.90) //信息保留90
            break;
    }
    int final_dim = eigenValues.rows() - dim;
    
	//实际维度
    cout << "---------------result---------" << endl;
    cout << final_dim << endl; 

	// 最终结果,将原始矩阵与我们的特征向量的最后final_dim列进行相乘,得到最终投影矩阵
    MatrixXd projection = samFeatureMatrix * eigenVectors.rightCols(final_dim);

    // eigen::Matrix -> cv::mat,类型转换
    Mat projectionMat;
    eigen2cv(projection, projectionMat);

    cout << projectionMat.cols << endl << projectionMat.rows << endl;
    cout << projectionMat << endl;
    return projectionMat;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
int main(){
    //hog_pca
    MatrixXd descriptorValues;
    descriptorValues = get_hog_feature();
    pca_1(descriptorValues, 324, 38);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

总结

总的来说是很简单的,只要掌握了原理,明白自己每一步要干什么就可以,同时注意合理调用库函数,减少工作量;
优化的两个亮点:

  1. 实现了特征重要性排序,但注意是从小到大排序,所以在最后选择主要成分的时候需要选择右边的列,而不是左边的列;
  2. 实现了维度的选择和信息保留程度的量化处理,便于后续分析该特征是否可用。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/222006
推荐阅读