赞
踩
前段时间写了一个HOG+PCA降维,在进行随机森林训练的时候,说得知道降维后信息保留了多少,以及得把降维后所有特征的重要性进行排序,于是删删改改终于解决了!
PCA的简单原理参见另一篇博客
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; }
int main(){
//hog_pca
MatrixXd descriptorValues;
descriptorValues = get_hog_feature();
pca_1(descriptorValues, 324, 38);
return 0;
}
总的来说是很简单的,只要掌握了原理,明白自己每一步要干什么就可以,同时注意合理调用库函数,减少工作量;
优化的两个亮点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。