如何预测第二个 class 更接近测试数据
how to predict second class which is more close to test data
我正在使用 opencv-2.4 (CvSVM
) 进行 class化。对于每个测试数据,它预测一个 class 作为预测输出。但是我需要找到下一个更接近测试数据的class。
有什么办法可以在 opencv SVM classifier ??
中找到它
很遗憾,您不能直接使用当前界面进行操作。
一种解决方案是改用库 libsvm。
您可以在 opencv 中完成,但这需要一些工作。
首先,您必须知道OpenCV使用"1-against-1"策略进行多class class化。
对于 N-class 问题,它将训练 N*(N-1)/2 个二进制 classifier(每对 classes 一个),然后使用多数表决选择最有可能的 class.
您将必须应用每个 classifier,并自己完成大部分以获得您想要的。
下面的代码向您展示了如何使用 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 class 中没有定义 getKernel 函数。我还是把它留在这里,因为修改内部 OpenCV 代码来添加它应该不会太难,而且显然没有其他方法可以做到。
我正在使用 opencv-2.4 (CvSVM
) 进行 class化。对于每个测试数据,它预测一个 class 作为预测输出。但是我需要找到下一个更接近测试数据的class。
有什么办法可以在 opencv SVM classifier ??
很遗憾,您不能直接使用当前界面进行操作。 一种解决方案是改用库 libsvm。
您可以在 opencv 中完成,但这需要一些工作。
首先,您必须知道OpenCV使用"1-against-1"策略进行多class class化。 对于 N-class 问题,它将训练 N*(N-1)/2 个二进制 classifier(每对 classes 一个),然后使用多数表决选择最有可能的 class.
您将必须应用每个 classifier,并自己完成大部分以获得您想要的。
下面的代码向您展示了如何使用 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 class 中没有定义 getKernel 函数。我还是把它留在这里,因为修改内部 OpenCV 代码来添加它应该不会太难,而且显然没有其他方法可以做到。