Ask Your Question

PCA+SVM Explanation

asked 2014-04-29 08:46:23 -0500

UncleSam gravatar image

I'm trying to apply a SVM classifier to a PCA projected matrix, but I've some doubt on how to perform it. After training a PCA obj, I've applied a back-projection. Then I've trained my SVM obj with this back-projection and the labels matrix.

But when I need to predict a new image, should I recreate a PCA obj, train it with the image only and back-project it? or should I apply the previous PCA obj?

Here's my piece of code

Mat values = asRowMatrix(labels, CV_32FC1);

Mat desc_mat = asRowMatrix(images_cropped, CV_32FC1);

Mat average = Mat();
PCA pca(desc_mat, average, CV_PCA_DATA_AS_ROW);

Mat mean = pca.mean.clone();
Mat eigenvalues = pca.eigenvalues.clone();
Mat eigenvectors = pca.eigenvectors.clone();

CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

Mat data(desc_mat.rows, images_cropped.size(), CV_32FC1); //This Mat will contain all the Eigenfaces that will be used later with SVM for detection

for (int i = 0; i<images_cropped.size(); i++) {
    Mat projectedMat(1, images_cropped.size(), CV_32FC1);
    pca.project(desc_mat.row(i), projectedMat);

CvSVM svm;
svm.train(data, values, Mat(), Mat(), params);

vector<Mat> images_cropped_t;
vector<int> labels_t;
//vectors with images and labels

int accuracy = 0;
Mat m_img = asRowMatrix(images_croppedt, CV_32FC1);
for (int i = 0; i < images_croppedt.size(); i++)
    Mat face = m_img.row(i);
    Mat projectedMat(1, images_croppedt.size(), CV_32FC1);
    pca.project(face, projectedMat);

    int predict = svm.predict(projectedMat);

    accuracy = ((predict < 51) && (labelst[i] == 0)) ? ++accuracy : (((predict > 51) && (labelst[i] == 1)) ? ++accuracy : accuracy);

cout << endl;
cout << "ACCURACY: " << accuracy << "/" << images_croppedt.size() << " : - " << accuracy * 100 / images_croppedt.size() << "%" << endl;
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2014-04-29 09:18:38 -0500

Hansg91 gravatar image

Your PCA object basically creates a new coordinate system for your data, such that the first principal component captures the 'most interesting data', the second principal component the second most, etc. With most interesting data I mean that the data in this direction has the highest variation.

If you have projected your samples for your SVM classifier using some PCA projection, you need to do that exact same projection if you want to classify a new image. Otherwise you'd be comparing different coordinate systems with eachother, like comparing meters with yards, celsius with fahrenheit, apples with pears.

edit flag offensive delete link more


So what I'm doing with my code is right I suppose! (or I am comparing apples with celsius?)

UncleSam gravatar imageUncleSam ( 2014-04-29 09:22:40 -0500 )edit

I didn't check your code before, but it seems like you use PCA/SVM fine there. That is of course no guarantee that it'll work ;) good luck!

Hansg91 gravatar imageHansg91 ( 2014-04-30 02:42:48 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2014-04-29 08:46:23 -0500

Seen: 2,187 times

Last updated: Apr 29 '14