美文网首页
svm原理之svm由来与功用|另附SVM实践实例

svm原理之svm由来与功用|另附SVM实践实例

作者: 何大仁_71c1 | 来源:发表于2019-07-27 19:11 被阅读0次

    /part 1_理论/

    Xnip2019-07-27_15-59-32.jpg

    SVM(SUPPORT VECTOR MACHINE)于1964年被提出,20世纪九十年代得到改进扩展,后被广泛应用于:人脸识别(face recognition)、文本分类(text categorization)等模式识别(pattern recognition)问题当中。

    支持向量机方法是建立在统计学理论的VC维理论和结构风险理论最小原理基础上的,根据现有的样本信息在模型的复杂性(对特定训练样本的学习精度:accuracy)和学习能力(无错误识别任何样本的能力)之间寻求最佳折中,以期待得到最好的推广能力,或称为泛化能力。

    所谓VC维理论是指对函数的一种度量,可以简单的理解为问题的复杂度,VC维越高,问题越复杂。由于SVM关注的是VC维,因此SVM在解决问题时,和样本的维数是无关的。(样本维数甚至可以是万维以上,正因为有这样的能力,因此才会有核函数的产生)

    机器学习的本质是对问题真实模型的逼近,真实模型是我们所不知道的,因此我们选择假设,而假设与问题真实解之间的误差便叫做风险(更为严格的说叫做累积误差风险),当我们选择一个假设之后,或者说找到一个分类器之后,真实值是无法得知的,但是可以通过已经掌握的量来去逼近它。最为直观的便是使用分类器在样本数据上的分类结果与真实结果之间的差值来表示,这个差值就叫做经验风险。

    先前的机器学习都把经验风险最小化作为努力的目标,但是后来发现很多分类函数能在样本集上轻易达到100%的正确率,但是在真实分类时一塌糊涂,也就是推广能力差(泛化能力差)。这时的情况便是选择了一个复杂的分类函数(VC维高),能够精确的记住每一个样本,但对样本之外的数据无能为力。由此可见,经验风险最小化原则适用的大前提是经验风险要确实能够逼近真实风险才对,但实际上不可以做到。因为样本,毕竟是少数量。

    统计学习因此引入泛化误差界概念,真实风险应该由两部分组成,一是经验风险,代表分类器在给定样本上的误差;二是置信风险,代表在多大程度上可以信任分类器在未知问题上的分类结果。置信误差是没有办法精确得到的,只能给出一个估计的区间,使得整个误差只能计算上界,无法得到准确的值。

    置信风险只与两个量有关,一是样本数量,样本数量越大,学习结果越有可能正确;二是分类函数的VC维,VC维越大,推广能力越差,置信风险也就越大。

    泛化误差界的公式:
    R(W)≤ Remp(w)+Q(n/h)
    式中:R(W)指真实风险,Remp(w)指经验风险,Q(n/h)指置信风险,统计学习的目标从经验风险最小化变成了寻求经验风险与置信风险和最小化,也即结构化风险最小。

    SVM正是一种努力最小化结构风险的算法。

    因此SVM的一些特点也就可以理解了:

    • 小样本——并非样本绝对的少,而是讲与问题的复杂度相比较而言,SVM算法要求的样本数量较少,对于任何算法而言,样本越多,总是能带来较好的结果。

    • 非线性——SVM较为擅长样本数据线性不可分的情况,主要是通过松弛变量(又称惩罚因子)和核技术来实现的。

    • 高斯模式识别——指样本维数很高,SVM应对高维数数据仍然游刃有余。

    /part_2实践/

    简单例子(参数分类):SVM分类只需要属性矩阵和标签,然后建立分类模型,利用此分类模型进行分类预测。

    //假设//一个班级里面有两个男生(男生1、男生2),两个女生(女生1、女生2),其中:

    • 男生1 身高: 176cm 体重:70kg;

    • 男生2 身高: 180cm 体重:80kg;

    • 女生1 身高: 161cm 体重:45kg;

    • 女生2 身高: 163cm 体重:47kg;

    接下来将男生定义为1,女生定义为-1,并将上述数据存入矩阵date当中,即:

    date = [176,70;180,80;161,45;163,47];
    

    在label中存入男生和女生的类别标签:

    label = [1;1;-1;-1];
    

    上述date矩阵便是一个属性矩阵,行数4代表4个样本,列数2代表属性有两个,lable表示标签。

    下面便可以用libsvm建立分类模型了:

    model = svmtrain(label,date);
    

    //假如//现在有一个新来的学生:

    性别未知,身高190cm,体重85Kg;

    现在想通过上面两个属性信息来判别他/她是男是女。

    可令(由于标签未知,这里可假定其标签为-1):

    test_date = [190,85];
    test_date_label = -1;
    

    最后利用libsvm来预测这个学生是男是女:

    [predict_label,auccracy,decision_values] = svmpredict(test_date_label,test_date,model);
    

    运行得到:predict_label=1,accuracy = 0%(0/1)classification.

    可见新来的同学是男生,由于我们之前的假设标签是-1,假设错误,所以分类准确率是0.

    /part_3实践/

    测试libsvm自带的heart_scale.mat数据,此数据是一个270*13 的一个属性矩阵,共有270个样本数据,每个样本有13个属性。

    代码:

     %程序:
     tic;    %开始计时
     close all;
    clear;
     clc;
     format compact; %压缩空格
     %载入数据
     [heart_scale_label,heart_scale_inst] = libsvmread('heart_scale');
     data = heart_scale_inst;
    label = heart_scale_label;
    % 选取前200个数据作为训练集合,后70个数据作为测试集合
    ind = 200;
    traindata = data(1:ind,:);      %取1到200行全部元素
    trainlabel = label(1:ind,:);
    testdata = data(ind+1:end,:);   %取200到270行全部元素
    testlabel = label(ind+1:end,:);
    % 利用训练集合建立分类模型
    model = svmtrain(trainlabel,traindata,'-s 0 -t 2 -c 1.2 -g 2.8');
    % 分类模型model解密
    model
    Parameters = model.Parameters
    Label = model.Label
    nr_class = model.nr_class
    totalSV = model.totalSV
    nSV = model.nSV 
    % 利用建立的模型看其在训练集合上的分类效果
    [ptrain,acctrain,decision_values] = svmpredict(trainlabel,traindata,model);
    % 预测测试集合标签
    [ptest,acctest,decision_values] = svmpredict(testlabel,testdata,model);
    toc;%结束计时
    

    代码部分解释:

     %model= svmtrain(train_label, train_matrix, ['libsvm_options']);
     %train_label表示训练集的标签。
     %train_matrix表示训练集的属性矩阵。
     %libsvm_options是需要设置的一系列参数。
     %model:是训练得到的模型,是一个结构体(如果参数中用到-v,得到的就不是结构体,对于分类问题,得到的是交叉检验下的平均分类准确率;对于回归问题,得到的是均方误差)。
     
     %[predicted_label, accuracy/mse, decision_values]=svmpredict(test_label, test_matrix, model, ['libsvm_options']);
     %其中:
     %test _label表示测试集的标签(这个值可以不知道,因为作预测的时候,本来就是想知道这个值的,这个时候,随便制定一个值就可以了,只是这个时候得到的mse就没有意义了)。
    %test _matrix表示测试集的属性矩阵。
    %model是上面训练得到的模型。
    %libsvm_options是需要设置的一系列参数。
    %predicted_label表示预测得到的标签。
    %accuracy/mse是一个3*1的列向量,其中第1个数字用于分类问题,表示分类准确率;后两个数字用于回归问题,第2个数字表示mse;第三个数字表示平方相关系数(也就是说,如果分类的话,看第一个数字就可以了;回归的话,看后两个数字)。
    %decision_values表示决策值。
    

    输出结果:

     .*
     optimization finished, #iter = 350
     nu = 0.719833
     obj = -88.802168, rho = 0.058346
     nSV = 197, nBSV = 13
     Total nSV = 197
     model = 
       包含以下字段的 struct:
     
        Parameters: [5×1 double]
          nr_class: 2
           totalSV: 197
               rho: 0.0583
             Label: [2×1 double]
        sv_indices: [197×1 double]
             ProbA: []
             ProbB: []
               nSV: [2×1 double]
           sv_coef: [197×1 double]
               SVs: [197×13 double]
    Parameters =
             0
        2.0000
        3.0000
        2.8000
             0
    Label =
         1
        -1
    nr_class =
         2
    totalSV =
       197
    nSV =
        89
       108
    Accuracy = 99.5% (199/200) (classification)
    Accuracy = 68.5714% (48/70) (classification)
    时间已过 0.043275 秒。
    

    关于model结构体里面的参数:

     %关于model结构体里面的参数;
     >>model.Parameters =
             0  %-s svm类型:SVM设置类型(默认0)
         2.0000  %-t 核函数类型:核函数设置类型(默认2)
         3.0000  %-d degree:核函数中的degree设置(针对多项式核函数)(默认3)
         2.8000  %-g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数) (默认类别数目的倒数)
              0  %-r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
     >>model.label  
         ans=
            1   
           -1  %model.Label表示数据集中类别的标签都有什么,这里是 1,-1;
    >>model.nr_class
    ans=
            2   %model.nr_class表示数据集中有多少类别,这里是二分类。
    >> model.totalSV
        ans =
            197 %代表总共的支持向量的数目,这里共有197个支持向量
    >> model.nSV
        ans =
            89  %model.nSV表示每类样本的支持向量的数目,这里表示标签为1的样本的支持向量有89个
            108 %标签为-1的样本的支持向量为108  
    sv_coef: [197x1 double]  %model.sv_coef是一个197*1的矩阵,承装的是197个支持向量在决策函数中的系数;
    SVs:     [197x13 double] %一个197*13的稀疏矩阵,承装的是259个支持向量      
    

    <center>以上内容学习、改进自www.matlabsky.com,仅为分享学习

    相关文章

      网友评论

          本文标题:svm原理之svm由来与功用|另附SVM实践实例

          本文链接:https://www.haomeiwen.com/subject/sloerctx.html