PCA(principal component analysis,主成分分析),我想是大家用的最多的降维手段,对于PCA的理解,我想大神们都各有各的绝招,可以应用的场合也非常多。下面就介绍一下OpenCV中PCA这个类,因为常用,所以这个类相对OpenCV而言显得比较独立,放在了core这部分中。
PCA类的成员函数包括构造函数、运算符重载()、project、backProject这几个函数,还包括成员变量eigenvectors、eigenvalues、mean。使用也很方便。比如我要计算一组向量的PCA,我们只需要定义个PCA实例,获得主成分,调用project测试新样本,也可以再调用backProject重建原始向量,是project的一个逆运算。
在实际使用我我发现了一个bug,构造函数和运算符重载()函数的第三个参数只能使用0或者1(分别对应CV_PCA_DATA_AS_ROW和CV_PCA_DATA_AS_COL),但调用对应的宏却编译无法通过,不知道大家是否也是一样的情况
下面结合一个实例分析:
2001年全国各地区消费情况指数
北京 101.5 100.4 97.0 98.7 100.8 114.2 104.2
天津 100.8 93.5 95.9 100.7 106.7 104.3 106.4
河北 100.8 97.4 98.2 98.2 99.5 103.6 102.4
山西 99.4 96.0 98.2 97.8 99.1 98.3 104.3
内蒙古 101.8 97.7 99.0 98.1 98.4 102.0 103.7
辽宁 101.8 96.8 96.4 92.7 99.6 101.3 103.4
吉林 101.3 98.2 99.4 103.7 98.7 101.4 105.3
黑龙江 101.9 100.0 98.4 96.9 102.7 100.3 102.3
上海 100.3 98.9 97.2 97.4 98.1 102.1 102.3
江苏 99.3 97.7 97.6 101.1 96.8 110.1 100.4
浙江 98.7 98.4 97.0 99.6 95.6 107.2 99.8
安徽 99.7 97.7 98.0 99.3 97.3 104.1 102.7
福建 97.6 96.5 97.6 102.5 97.2 100.6 99.9
江西 98.0 98.4 97.1 100.5 101.4 103.0 99.9
山东 101.1 98.6 98.7 102.4 96.9 108.2 101.7
河南 100.4 98.6 98.0 100.7 99.4 102.4 103.3
湖北 99.3 96.9 94.0 98.1 99.7 109.7 99.2
湖南 98.6 97.4 96.4 99.8 97.4 102.1 100.0
广东 98.2 98.2 99.4 99.3 99.7 101.5 99.9
广西 98.5 96.3 97.0 97.7 98.7 112.6 100.4
海南 98.4 99.2 98.1 100.2 98.0 98.2 97.8
重庆 99.2 97.4 95.7 98.9 102.4 114.8 102.6
四川 101.3 97.9 99.2 98.8 105.4 111.9 99.9
贵州 98.5 97.8 94.6 102.4 107.0 115.0 99.5
云南 98.3 96.3 98.5 106.2 92.5 98.6 101.6
西藏 99.3 101.1 99.4 100.1 103.6 98.7 101.3
陕西 99.2 97.3 96.2 99.7 98.2 112.6 100.5
甘肃 100.0 99.9 98.2 98.3 103.6 123.2 102.8
青海 102.2 99.4 96.2 98.6 102.4 115.3 101.2
宁夏 100.1 98.7 97.4 99.8 100.6 112.4 102.5
新疆 104.3 98.7 100.2 116.1 105.2 101.6 102.6
我们用PCA来分析这些向量的对消费水平的贡献,代码实现如下:
#include <opencv2/core/core.hpp> #include <iostream> #include <fstream> using namespace cv; using namespace std; void main(int argc, char** argv) { const int SAMPLE_NUM = 31; const int VECTOR_NUM = 7; fstream fp; string temp; char* filename = argv[1]; Mat pcaSet(SAMPLE_NUM, VECTOR_NUM, CV_32F); // 读取数据,生成pcaSet fp.open(filename, ios::in); for (int i=0; i<SAMPLE_NUM; i++) { getline(fp, temp, ' '); for (int j=0; j<VECTOR_NUM; j++) { fp >> pcaSet.at<float>(i, j); } } fp.close(); // cout << pcaSet << endl; PCA pca(pcaSet, Mat(), 0/*CV_PCA_DATA_AS_ROW*/); cout << pca.eigenvalues << endl; cout << endl; cout << pca.eigenvectors << endl; }
eigenvalues:[43.18,14.60,9.21]、
eigenvectors:[0.013,0.034,-.0.100, -0.130, 0.207,0.963,-0.020;
0.157,0.038,0.121,0.893,0.395,0.046,0.060;
0.214,0.018,-0.001,-0.404,0.813,-0.228,0.277]