zoukankan      html  css  js  c++  java
  • 支持向量机(SVM)算法的matlab的实现

    支持向量机(SVM)的matlab的实现

    支持向量机是一种分类算法之中的一个,matlab中也有对应的函数来对其进行求解;以下贴一个小例子。这个例子来源于我们实际的项目。

    clc;
    clear;
    N=10;
    %以下的数据是我们实际项目中的训练例子(例子中有8个属性)
    correctData=[0,0.2,0.8,0,0,0,2,2];
    errorData_ReversePharse=[1,0.8,0.2,1,0,0,2,2];
    errorData_CountLoss=[0.2,0.4,0.6,0.2,0,0,1,1];
    errorData_X=[0.5,0.5,0.5,1,1,0,0,0];
    errorData_Lower=[0.2,0,1,0.2,0,0,0,0];
    errorData_Local_X=[0.2,0.2,0.8,0.4,0.4,0,0,0];
    errorData_Z=[0.53,0.55,0.45,1,0,1,0,0];
    errorData_High=[0.8,1,0,0.8,0,0,0,0];
    errorData_CountBefore=[0.4,0.2,0.8,0.4,0,0,2,2];
    errorData_Local_X1=[0.3,0.3,0.7,0.4,0.2,0,1,0];
     sampleData=[correctData;errorData_ReversePharse;errorData_CountLoss;errorData_X;errorData_Lower;errorData_Local_X;errorData_Z;errorData_High;errorData_CountBefore;errorData_Local_X1];%训练例子
    
    type1=1;%正确的波形的类别,即我们的第一组波形是正确的波形,类别号用 1 表示
    type2=-ones(1,N-2);%不对的波形的类别,即第2~10组波形都是有故障的波形。类别号用-1表示
    groups=[type1 ,type2]';%训练所需的类别号
    j=1;
    %由于没有測试数据,因此我将错误的波形数据轮流从训练例子中取出作为測试例子
    for i=2:10
       tempData=sampleData;
       tempData(i,:)=[];
        svmStruct = svmtrain(tempData,groups);
        species(j) = svmclassify(svmStruct,sampleData(i,:));
        j=j+1;
    end
    species
    

    输出结果例如以下:

     -1    -1    -1    -1    -1    -1    -1     1    -1

    从结果能够看出:仅仅有第九个被误判。其他的都是正确的。

    上面仅仅是用于说明matlab中支持向量机中函数的使用方法,由于在训练集中我仅仅用了一个正确的波形和九组有故障的波形作为训练集,因此这样的超平面的选取可能不好。可是,在我们的实际的项目中,我们是用到了很多的训练集的。

    上面是调用matlab中的函数实现多维属性中的支持向量机对其进行分类。

    以下是自己实现此功能,不调用matlab中的支持向量机的函数。代码例如以下:

    %主函数
    clear all;
    clc;
    C = 10;
    kertype = 'linear';
    %训练样本
    n = 50;
    randn('state',6);%能够保证每次每次产生的随机数一样
    x1 = randn(2,n);    %2行N列矩阵
    y1 = ones(1,n);       %1*N个1
    x2 = 5+randn(2,n);   %2*N矩阵
    y2 = -ones(1,n);      %1*N个-1
    
    figure;
    plot(x1(1,:),x1(2,:),'bx',x2(1,:),x2(2,:),'k.'); 
    axis([-3 8 -3 8]);
    xlabel('x轴');
    ylabel('y轴');
    hold on;
    
    X = [x1,x2];        %训练样本d*n矩阵。n为样本个数,d为特征向量个数。在这里。X为一个2*100的数组
    Y = [y1,y2];        %训练目标1*n矩阵,n为样本个数,值为+1或-1。在这里,Y为一个1*100的数组
    svm = svmTrain(X,Y,kertype,C);
    plot(svm.Xsv(1,:),svm.Xsv(2,:),'ro');
    
    %測试
    [x1,x2] = meshgrid(-2:0.05:7,-2:0.05:7);  %x1和x2都是181*181的矩阵
    [rows,cols] = size(x1);  
    nt = rows*cols;                  
    Xt = [reshape(x1,1,nt);reshape(x2,1,nt)];
    Yt = ones(1,nt);
    result = svmTest(svm, Xt, Yt, kertype);
    
    Yd = reshape(result.Y,rows,cols);
    contour(x1,x2,Yd,'m');
    
    
    
    

    训练集函数例如以下:

    function svm = svmTrain(X,Y,kertype,C)
    options = optimset;    % Options是用来控制算法的选项參数的向量
    options.LargeScale = 'off';%LargeScale指大规模搜索。off表示在规模搜索模式关闭
    options.Display = 'off';%这样设置意味着没有输出
    
    n = length(Y);%数组Y的长度
    H = (Y'*Y).*kernel(X,X,kertype);%调用kernel函数。
    
    f = -ones(n,1); %f为1*n个-1,f相当于Quadprog函数中的c
    A = [];
    b = [];
    Aeq = Y; %相当于Quadprog函数中的A1,b1
    beq = 0;
    lb = zeros(n,1); %相当于Quadprog函数中的LB,UB
    ub = C*ones(n,1);
    a0 = zeros(n,1);  % a0是解的初始近似值
    [a,fval,eXitflag,output,lambda]  = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
    
    epsilon = 1e-8;                     
    sv_label = find(abs(a)>epsilon);  %0<a<a(max)则觉得x为支持向量     
    svm.a = a(sv_label);
    svm.Xsv = X(:,sv_label);
    svm.Ysv = Y(sv_label);
    svm.svnum = length(sv_label);
    %svm.label = sv_label;

    核函数例如以下:

    function K = kernel(X,Y,type)
    %X 维数*个数
    switch type
    case 'linear'
        K = X'*Y;
    case 'rbf'
        delta = 5;
        delta = delta*delta;
        XX = sum(X'.*X',2);%sum(a,2)代码中參数2的意思是将a矩阵a中的按“行”为单位进行求和
        YY = sum(Y'.*Y',2);
        XY = X'*Y;
        K = abs(repmat(XX,[1 size(YY,1)]) + repmat(YY',[size(XX,1) 1]) - 2*XY);
        K = exp(-K./delta);
    end

    測试函数例如以下

    function result = svmTest(svm, Xt, Yt, kertype)
    temp = (svm.a'.*svm.Ysv)*kernel(svm.Xsv,svm.Xsv,kertype);
    total_b = svm.Ysv-temp;
    b = mean(total_b);
    w = (svm.a'.*svm.Ysv)*kernel(svm.Xsv,Xt,kertype);
    result.score = w + b;
    Y = sign(w+b);
    result.Y = Y;
    result.accuracy = size(find(Y==Yt))/size(Yt);
    
    

    要说明的是。上面的代码是实现的关于我们样本仅仅有2个属性的情况。当我们的样本用多个属性时,我们须要改动部分代码就可以。

    參考资料:http://blog.sina.com.cn/s/blog_631a4cc40101df0f.html

  • 相关阅读:
    使用helm管理复杂kubernetes应用
    helm repository 相关
    PSQLException: An I/O error occurred while sending to the backend.
    使用helm进行kubernetes包管理
    Slave作为其它Slave的Master时使用
    ext3是对ext2文件系统的一个扩展高性能日志文件系统
    ready是先执行的,load后执行,DOM文档的加载步骤
    jQuery上定义插件并重设插件构造函数
    在PHP与HTML混合输入的页面或者模板中就需要对PHP代码进行闭合
    decode 函数将字符串从某种编码转为 unicode 字符
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5340608.html
Copyright © 2011-2022 走看看