how to predict second class which is more close to test data

后端 未结 1 1994
余生分开走
余生分开走 2021-01-21 16:42

I am using opencv-2.4 (CvSVM) for classification. For each test data it is predicting one class as predicted output. But I need to find the next class which is more

相关标签:
1条回答
  • 2021-01-21 17:36

    Unfortunately, you can not do it directly with the current interface. One solution would be to use the library libsvm instead.

    You may do it in opencv, but it will require a little bit of work.

    First, you must know that OpenCV uses a "1-against-1" strategy for multi-class classification. For a N-class problem, it will train N*(N-1)/2 binary classifier (one for each couple of classes), and then uses a majority vote to choose the most probable class.

    You will have to apply each classifier, and do the majority yourself to get what you want.

    The code below show you how to do that with OpenCV 3 (warning: it is untested, probably contains errors, but it gives you a good starting point).

    Ptr<SVM> svm;
    int N;            //number of classes
    Mat data;         //input data to classify
    
    Mat sv=svm->getSupportVectors();
    Ptr<Kernel> kernel=svm->getKernel();
    Mat buffer(1,sv.rows,CV_32F);
    kernel->calc(sv.rows, sv.cols , sv.ptr<float>(), data.ptr<float>(), buffer.ptr<float>());  // apply kernel on data (CV_32F vector) and support vectors
    
    Mat alpha, svidx;
    vector<int> votes(N, 0);  // results of majority vote will be stored here
    
    int i, j, dfi;
    for( i = dfi = 0; i < N; i++ ) 
    {
        for( j = i+1; j < N; j++, dfi++ )
        {
            // compute score for each binary svm
            double rho=svm->getDecisionFunction(dfi, alpha, svidx);
            double sum = -rho;
            for( k = 0; k < sv.rows; k++ )
                sum += alpha.at<float>(k)*buffer.at<float>(svidx.at<int>(k));
            // majority vote
            votes[sum > 0 ? i : j]++;
        }
    }
    

    Edit: This code is adapted from the internal code of Opencv here. It is incorrect, as pointed out by David Doria in the comments, since there is no getKernel function defined in the SVM class. I still leave it here, since it should'nt be too difficult to modify the internal OpenCV code to add it, and there is apparently no other way to do it.

    0 讨论(0)
提交回复
热议问题