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


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存在误分、拒分现象提出的 。
这里仅仅是对几种多分类方法的简要说明,如果直接调用的方法,并不需要关心多分类算法的具体实现,来看看下面的例子:
中SVM多类分类问题编程实例:
#
#
#
#
#
usingstd;
int main()
// step 1:
//训练数据的分类标记,即4类
【四学习Opencv2.4.9---SVM支持向量机】float [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};
CvMat= cvMat(16, 1, , );
//训练数据矩阵
float [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} };
CvMat= cvMat(16, 2, , );
// step 2:
//训练参数设定
;
. = CvSVM::C_SVC;//SVM类型
. = CvSVM::;//核函数的类型
//SVM训练过程的终止条件, :最大迭代次数 :结果的精确性
. = (, 100,);
// step 3:
//启动训练过程
CvSVM SVM;
SVM.train( &, &, NULL,NULL, );
// step 4:
//使用训练所得模型对新样本进行分类测试
for (int i=-5; i {
for (int j=-5; j{
float a[] = {i,j};
CvMat ;
(&,1,2,,a);
(&,0,0,i);// Set M(i,j)
(&,0,1,j);// Set M(i,j)
float= SVM.(&);
cout