SVM多分类

SVM实现多分类的方案

SVM本身是一个二值分类器

  SVM算法最初是为二值分类问题设计的,当处理多类问题时,就需要构造合适的多类分类器。

  目前,构造SVM多类分类器的方法主要有两类

  (1)直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;

  (2)间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有one-against-one和one-against-all两种。

一对多法(one-versus-rest,简称OVR SVMs)

  训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。

  假如我有四类要划分(也就是4个Label),他们是A、B、C、D。

  于是我在抽取训练集的时候,分别抽取

  (1)A所对应的向量作为正集,B,C,D所对应的向量作为负集;

  (2)B所对应的向量作为正集,A,C,D所对应的向量作为负集;

  (3)C所对应的向量作为正集,A,B,D所对应的向量作为负集;

  (4)D所对应的向量作为正集,A,B,C所对应的向量作为负集;

  使用这四个训练集分别进行训练,然后的得到四个训练结果文件。

  在测试的时候,把对应的测试向量分别利用这四个训练结果文件进行测试。

  最后每个测试都有一个结果f1(x),f2(x),f3(x),f4(x)。

  于是最终的结果便是这四个值中最大的一个作为分类结果。

评价:

  这种方法有种缺陷,因为训练集是1:M,这种情况下存在biased.因而不是很实用。可以在抽取数据集的时候,从完整的负集中再抽取三分之一作为训练负集。

一对一法(one-versus-one,简称OVO SVMs或者pairwise)

  其做法是在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM。

  当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别。

  Libsvm中的多类分类就是根据这个方法实现的。

  假设有四类A,B,C,D四类。在训练的时候我选择A,B; A,C; A,D; B,C; B,D;C,D所对应的向量作为训练集,然后得到六个训练结果,在测试的时候,把对应的向量分别对六个结果进行测试,然后采取投票形式,最后得到一组结果。

  投票是这样的:
  A=B=C=D=0;
  (A,B)-classifier 如果是A win,则A=A+1;otherwise,B=B+1;
  (A,C)-classifier 如果是A win,则A=A+1;otherwise, C=C+1;
  ...
  (C,D)-classifier 如果是A win,则C=C+1;otherwise,D=D+1;
  The decision is the Max(A,B,C,D)

评价:这种方法虽然好,但是当类别很多的时候,model的个数是n*(n-1)/2,代价还是相当大的。

用libsvm在matlab中实现多分类(训练函数svmtrain+预测函数svmpredict) 
对于libsvm中训练模型的函数svmtrain来说,model = svmtrain(训练数据类别, 训练数据, ‘一系列参数’);其中参数的形式如‘-c 2 -g 0.02’在这当中,参数主要包括以下几个方面:
(1) -s —— 其表示SVM的类型,包括上面提到的(默认值为0): 
0 —— C-SVC 
1—— v-SVC 
2 —— 一类SVM 
3 —— e -SVR 
4 —— v-SVR 
(2)-t—— 其表示核函数类型(默认值为2) 
0 – 线性:u’v 
1 – 多项式:(r*u’v + coef0)^degree 
2 – RBF函数:exp(-gamma|u-v|^2) 
3 –sigmoid:tanh(r*u’v + coef0) 
(3)核函数参数设置 
-d ——核函数中的degree设置(针对多项式核函数)(默认3) 
-g ——核函数中的gamma函数设置(针对多项式/rbf/sigmoid 核函数)(默认1/ k,k为特征值个数) 
-r ——核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0) 
-c ——设置C-SVC,e -SVR和v-SVR的参数(损失函数)(默认1) 
-n——设置nu-SVC,一类SVM和nu- SVR的参数(默认0.5) 
-p ——设置e -SVR 中损失函数p的值(默认0.1) 
-m ——设置cache内存大小,以MB为单位(默认40) 
-e ——设置允许的终止判据(默认0.001) 
-h ——是否使用启发式,0或1(默认1) 
-b ——是否训练一个SVC或者SVR模型,0或1(默认0) 
-wi ——设置第i类的参数C为weight*C(C-SVC中的C)(默认1) 
-v——n-fold交互检验模式,n为fold的个数,必须大于等于2(训练中使用了-v参数进行交叉验证时,返回的不是一个模型,而是交叉验证的分类的正确率或者回归的均方根误差)

使用函数svmtrain训练分类模型后,会返回一个结构体,其中包括数据: 
(1) parameters(一个5*1的数组) 
第一个元素:-s,SVM的类型(int默认为0) 
第二个元素:-t,核函数类型(默认为2) 
第三个元素:-d,核函数中的degree设置(针对多项式核函数)(默认3); 
     第四个元素:-g,核函数中的r(gamma)函数设置(针对多项式/rbf/sigmoid核函数) (默认为类别数目的倒数); 
第五个元素:-r 核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0) 
(2)-nr_class: 表示数据集中有多少个类(int) 
(3)-totalSV: 表示支持向量的总数。(int) 
(4)-rho: 决策函数wx+b中的常数偏置的相反数(-b)。 
(5)-Label: 表示数据集中类别的标签 
(6)ProbA: 使用-b参数时用于概率估计的数值,否则为空。 
ProbB: 使用-b参数时用于概率估计的数值,否则为空。 
(7)-nSV: 表示每类样本的支持向量的数目,和Label的类别标签对应。 
(8)-sv_coef: 表示每个支持向量在决策函数中的系数。 
(9)-SVs: 表示所有的支持向量,如果特征是n维的,支持向量一共有m个,则为m x n的稀疏矩阵。 
(10)nu: -n参数的显示 
(11)iter: 迭代次数 
(12)obj: 表示SVM文件转换的二次规划求解的最小值

svmpredict函数根据测试数据类属性,测试数据,以及通过svmtrain函数获得的模型来进行分类预测并计算分类精度,[predict_label, accuracy, dec_values]=svmpredict(测试数据类属性,测试数据,分类模型),返回值介绍如下:
(1)predicted_label:存储着分类后样本所对应的类属性。 
(2)accuracy:一个3 * 1的数组,依次为:分类的正确率、回归的均方根误差、回归的平方相关系数。 
(3)decision_values/prob_estimates:是一个表示概率的数组,对于一个m个数据,n个类的情况,如果指定“-b 1”参数(使用,则n x k的矩阵,每一行表示这个样本分别属于每一个类别的概率;如果没有指定“-b 1”参数,则为n * n×(n-1)/2的矩阵,每一行表示n(n-1)/2个二分类SVM的预测结果。

使用libsvm进行分类的步骤 

(1) 对数据做归一化(simple scaling) 
对数据进行简单的缩放处理(scaling),缩放的最主要优点是能够避免大数值区间的属性过分支配了小数值区间的属性。另一个优点能避免计算过程中数值复杂度。(在试验中发现,归一化过程,分别对训练数据和测试数据进行归一化处理,比对训练数据和测试数据整体进行归一化处理获得的分类精度要高)
(2) 应用 RBF kernel 
(3) 选择得到最优的c和g 
c是惩罚因子,是一个在训练模型前需要自己设置的一个数值,它表示我们对类中的离群数据的重视程度,c的数值越大,表明我们越重视,越不想丢掉这些离群的数据;g是核函数中的gamma函数设置(针对多项式/rbf/sigmoid 核函数)(默认1/ k,k为特征值个数) 。c和g的选择对分类精度影响很大,在本文的试验中,用函数SVMcgForClass选择完成c和g的选择。
(4) 用得到的最优c和g训练分类模型 
使用libsvm中的svmtrain函数来训练多分类模型 
(5)测试 
使用libsvm中的svmpredict函数来测试分类精度


猜你喜欢

转载自blog.csdn.net/u013185349/article/details/81015956