学习Opencv2.4.9---SVM支持向量机1( 三 )


在分类题目中,这个函数返回类别编号;在回归题目中,返回函数值 。
输入的样本必须与传给的练习样本同样大小 。
若是练习中应用了参数,必然记住在函数中应用跟练习特点一致的特点 。
(1)获得练习样本及制作其类别标签(,)
(2)设置练习参数()
(3)对SVM进行训练(CvSVM::train)
(4)对新的输入样本进行猜测(CvSVM::),并输出结果类型(对应标签)
(5)获取支撑向量(CvSVM::ount,CvSVM:: )
目前,构造SVM多类分类器的方法主要有两类:一类是直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类 。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;另一类是间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有one--one和one--all两种 。
1、一对多法(one--rest,简称) 。训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM 。分类时将未知样本分类为具有最大分类函数值的那类 。
假如我有四类要划分(也就是4个Label),他们是A、B、C、D 。于是我在抽取训练集的时候,分别抽取A所对应的向量作为正集,B,C,D所对应的向量作为负集;B所对应的向量作为正集,A,C,D所对应的向量作为负集;C所对应的向量作为正集,A,B,D所对应的向量作为负集;D所对应的向量作为正集,A,B,C所对应的向量作为负集,这四个训练集分别进行训练,然后的得到四个训练结果文件,在测试的时候,把对应的测试向量分别利用这四个训练结果文件进行测试,最后每个测试都有一个结果f1(x),f2(x),f3(x),f4(x).于是最终的结果便是这四个值中最大的一个 。
PS:这种方法有种缺陷,因为训练集是1:M,这种情况下存在偏差.因而不是很实用.
2、一对一法(one--one,简称或者) 。其做法是在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM 。当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别 。中的多类分类就是根据这个方法实现的 。
还是假设有四类A,B,C,D四类 。在训练的时候我选择A,B;A,C; A,D; B,C;B,D;C,D所对应的向量作为训练集,然后得到六个训练结果,在测试的时候,把对应的向量分别对六个结果进行测试,然后采取投票形式,最后得到一组结果 。
3、层次支持向量机(H-SVMs) 。层次分类法首先将所有类别分成两个子类,再将子类进一步划分成两个次级子类,如此循环,直到得到一个单独的类别为止 。
4、DAG-SVMS是由Platt提出的决策导向的循环图DDAG导出的,是针对“一对一”SVMS存在误分、拒分现象提出的 。
这里仅仅是对几种多分类方法的简要说明,如果直接调用的方法,并不需要关心多分类算法的具体实现,来看看下面的例子:
【学习Opencv2.4.9---SVM支持向量机1】

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. using namespace std;
  7. int main()
  8. {
  9. // step 1:
  10. //训练数据的分类标记,即4类
  11. float labels[16] = {1.0, 1.0,1.0,1.0,2.0,2.0,2.0,2.0,3.0,3.0,3.0,3.0,4.0,4.0,4.0,4.0};
  12. CvMat labelsMat = cvMat(16, 1, CV_32FC1, labels);
  13. //训练数据矩阵
  14. float trainingData[16][2] = { {0, 0}, {4, 1}, {4, 5}, {-1, 6},{3,11},{-2,10},{4,30},{0,25},{10,13},{15,12},{25,40},{11,35},{8,1},{9,6},{15,5},{20,-1} };