如何预测更接近测试数据的第二类

时间:2015-01-09 17:26:02

标签: opencv svm

我使用opencv-2.4(CvSVM)进行分类。对于每个测试数据,它预测一个类作为预测输出。但是我需要找到更接近测试数据的下一个类。 有没有办法在opencv SVM分类器中找到它?

1 个答案:

答案 0 :(得分:0)

不幸的是,你无法直接使用当前界面。 一种解决方案是使用库libsvm代替。

您可以在opencv中执行此操作,但这需要一些工作。

首先,您必须知道OpenCV使用"1-against-1"策略进行多类分类。 对于N级问题,它将训练N *(N-1)/ 2二元分类器(每两个类一个),然后使用多数投票来选择最可能的类。

你必须应用每个分类器,并自己做多数来获得你想要的东西。

下面的代码向您展示了如何使用OpenCV 3(警告:它未经测试,可能包含错误,但它为您提供了一个很好的起点)。

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]++;
    }
}

编辑:此代码改编自Opencv here的内部代码。 正如David Doria在评论中指出的那样,这是不正确的,因为SVM类中没有定义getKernel函数。我仍然把它留在这里,因为修改内部OpenCV代码来添加它应该太难了,而且显然没有别的方法可以做到。