代码小白在努力学习 2022-11-11 10:45 采纳率: 42.9%
浏览 88

用MATLAB对鸢尾花数据分类

在MATLAB中,应用软间隔SVM算法(非线性)对鸢尾花数据进行分类,并画图

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-11-11 12:04
    关注
    • 看下这篇博客,也许你就懂了,链接:支持向量机实现鸢尾花数据集分类matlab
    • 除此之外, 这篇博客: 支持向量机实现鸢尾花数据集分类matlab中的 代码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • %% 数据预处理和导入
      close;clear;clc
      [train_data,train_label,test_data,test_label,m1,n1,m2,n2] = data_set(0.6,100);
      %% 模型训练
      Kernel = 'linear';% Kernel 核技巧备选:gaussian linear sigmoid mullinear 
      svm = train_svm(train_data',train_label',Kernel,10); % svm = train_svm(X,Y,kertype,C) C为变量上界(惩罚因子) svm为结构体
      %% 模型测试
      result = test_svm(svm,test_data',test_label',Kernel);
      fprintf('训练完成!\n应用模型:SVM 支持向量机\n优化算法:interior-point-convex\n核函数:%s\n测试集识别率为:%f\n',Kernel,result.accuracy);
      %% 作图显示数据以及训练结果;中间为支持向量[三维]
      draw_svm(train_data,train_label,svm,3,Kernel);
      
      function [train_data,train_label,test_data,test_label,m1,n1,m2,n2] = data_set(k,data_num)
      % 功能说明:完成数据的预处理,setosa:1  versicolor:2  virginica:3
      % 调用语法及参数说明:[data_iris,data_label] = data_set();
      % 
      load('data_iris.mat');load('data_label.mat');
      data_label = zeros(data_num,1);
      for i = 1:data_num
          switch species(i)
              case 'setosa'
                  data_label(i) = 1;
              case 'versicolor'
                  data_label(i) = -1;
      %         case 'virginica'
      %             data_label(i) = 3;
          end
      end
      data_iris = iris(1:data_num,:);
      
      % 乱序排列
      randIndex = randperm(data_num);
      data_new=data_iris(randIndex,:);
      label_new=data_label(randIndex,:);
      
      % 分为两组,比例k用于训练,剩余用于测试
      k = k*data_num;
      train_data=data_new(1:k,:);
      train_label=label_new(1:k,:);
      test_data=data_new(k+1:end,:);
      test_label=label_new(k+1:end,:);
      [m1,n1] = size(train_data);
      [m2,n2] = size(test_data);
      end
      
      function draw_svm(train_data,train_label,svm,data_features,Kernel)
      % 功能说明:根据数据特征的维数判断,进而分别绘图
      % 函数语法及参数列表:draw_svm(inputArg1,data_features)
      % input: 
      % train_data: 训练数据集 
      % train_label:训练集数据的类别
      % svm:svm结构体(详见train_svm,help train_svm)
      % data_features特征维数
      
      switch data_features
          case 2
              plot(train_data(train_label==1,1),train_data(train_label==1,2),'ro',train_data(train_label==-1,1),train_data(train_label==-1,2),'go');hold on;
              plot(svm.data(1,:),svm.data(2,:),'mo');hold on;title(['样本分布',Kernel]); % 显示支持向量 'mo'品红色的圈
              [x1,x2] = meshgrid(4:0.01:7,2:0.01:5);
              [rows,cols] = size(x1);  
              nt = rows*cols;                  
              Xt = [reshape(x1,1,nt);reshape(x2,1,nt)];
              Yt = ones(1,nt);
              result = test_svm(svm, Xt, Yt,Kernel);
              Yd = reshape(result.Y,rows,cols);
              contour(x1,x2,Yd,'m');
          otherwise
              plot3(train_data(train_label==1,1),train_data(train_label==1,2),train_data(train_label==1,3),'r.');hold on;
              plot3(train_data(train_label==-1,1),train_data(train_label==-1,2),train_data(train_label==-1,3),'gx');hold on;
              plot3(svm.data(1,:),svm.data(2,:),svm.data(3,:),'mo');hold on;
              
              title(['样本分布',Kernel]);
      end
      end
      
      function K = kernel(X,Y,kerneltype)
      % 功能:支持多种核运算;
      % 语法结构:K = kernel(X,Y,kerneltype),kerneltype选择核技巧
      % 'linear':线性内积
      %           K(v1,v2) = <v1,v2>
      % 'gaussian':高斯核 %
      %           K(v1,v2)=exp(-gama||v1-v2||^2)
      % 'sigmoid':sigmoid核;双曲正切函数
      %           K(v1,v2)=tanh(gama<v1,v2>+c)    
      % 'mullinear':多项式核
      %           K(v1,v2)=<v1,v2>^d;d为多项式的次数
      % 'triangle':三角核
      %           K(v1,v2)=-||v1-v2||^d
      
      % 在svm中运用线性,高斯或者sigmoid效果比较好
      switch kerneltype
          case 'linear' % 线性内积
              K = X'*Y;
          case 'sigmoid'
              belta = 0.01;
              theta = 0.001;
              K = tanh(belta*X*Y+theta);
          case 'gaussian'% k(v1,v2) = exp(-||v1-v2||^2/(2sigma^2))
              delta = 2*1.414;
              delta = delta*delta;
              XX = sum(X'.*X',2);
              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);
          case 'mullinear'
              K = (X'*Y).^2;
      %     case'triangle'
      %         K = -norm(X-Y,1)^2;
              
      end
      end
      
      function result = test_svm(svm, test_data, test_label, kerneltype)
      % 功能说明:
      % 完成测试集的预测以及准确率的输出
      % 语法习惯核参数列表:result = test(svm, test_data, test_label, kerneltype)
      % input:
      % svm: train_svm函数返回的结构体(详见help train_svm)
      % test_data: 测试数据
      % test_label:测试集标签
      % kerneltype:核技巧种类,形式参数,可选:linear gaussian sigmoid mullinear triangle
      % output:
      % result:结构体,属性如下
      % result.Y:测试集中数据的预测类别  result.Y ∈{+1-1}
      % result.accuracy:测试集的准确率
      
      % 教材非线性支持向量机学习算法的策略为选择a的一个正分量0< a <C进行计算
      % 此处选择了对所有满足0< ai <C求得bi,并对b进行取平均运算
      sum_b = svm.label - (svm.a'.* svm.label)*kernel(svm.data,svm.data,kerneltype);
      b = mean(sum_b);
      w = (svm.a'.* svm.label)*kernel(svm.data,test_data,kerneltype);% 统一起见,令 w = sigma(ai*yi*K(x,xi)
      result.Y = sign(w+b);% 加外壳符号函数进行分类
      result.plotx = min(test_data(1,:)):0.001: max(test_data(1,:));
      
      result.accuracy = size(find(result.Y==test_label))/size(test_label);% 预测正确的数据数目/总测试集数目
      end
      
      function svm = train_svm(train_data,train_label,kertype,C)
      % 功能说明:完成SVM训练
      % 语法习惯与参数列表:svm = train_svm(train_data,train_label,kertype,B)
      % input:
      % train_data:训练数据
      % train_label:训练数据的类别
      % kertype:核函数的类别
      % C 惩罚参数
      % B 为变量约束中的上界
      % output:
      % svm:是一个结构体,包含属性如下:
      % svm.a :得到的凸二次规划的解
      % svm.data : 支持向量
      % svm.label :支持向量的类别
      % ------------*************************···········
      % ------------关键函数quadprog的一些说明···········
      % 函数quadprog:用于解二次规划问题
      % 问题描述:
      % min(x): 0.5·x'·H·x + f'·x
      %      
      %           A·x <= b,    
      % s.t.:   Aeq·x  = beq;
      %         lb <=x <= ub;
      % 
      % 全参数语法结构:x = quadprog(H,f,A,b,Aeq,beq,lb,ub,x0,options);
      % 变量说明:
      % H,A,Qeq是矩阵,f,b,beq,lb,ub,x是向量
      % options:选择优化算法并进行设置
      % 优化选项设置,对属性进行设置:
      % 使用 optimoptions 或 optimset 创建选项(属性)% 指定为 optimoptions 的输出或 optimset 等返回的结构体。
      
      % 变量初始化以及超参设置
      n = length(train_label); % 对变量的自由约束,上下界
      H = (train_label'*train_label).*kernel(train_data,train_data,kertype);% H为yi*yj*K(xi,xj)
      f = -ones(n,1); % 保证f为列向量,原式中包含转置操作
      A = [];% 不含不等约束
      b = [];% 不含不等约束
      Aeq = train_label;  % s.t.: aY = 0;
      beq = 0;            % s.t.: aY = 0;
      lb = zeros(n,1);    % 解:a 的范围  
      ub = C*ones(n,1);   % 0 <= a <= C
      a0 = zeros(n,1);    % a0是解的初始近似值
      options = optimset;  % 'interior-point-convex'(默认优化算法)
      options.Display = 'iter-detailed';% 显示优化步骤
      
      % x = quadprog(H,f,A,b,Aeq,beq,lb,ub,x0,options) 使用 options 中指定的优化选项求解上述问题。
      % 使用 optimset 创建 options。如果不提供初始点,设置 x0 = []。
      a = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
      
      % 寻找支持向量;a>e 则认为train_data为支持向量 函数find查找逻辑为真的索引  
      e = 1e-4;      
      
      sv_index = find(abs(a)>e);
      svm.a = a(sv_index);
      svm.data = train_data(:,sv_index);% 作图显示支持向量位置
      svm.label = train_label(sv_index);
      end
      
      
    评论

报告相同问题?

问题事件

  • 创建了问题 11月11日

悬赏问题

  • ¥15 问题遇到的现象和发生背景 360导航页面千次ip是20元,但是我们是刷量的 超过100ip就不算量了,假量超过100就不算了 这是什么逻辑呢 有没有人能懂的 1000元红包感谢费
  • ¥30 计算机硬件实验报告寻代
  • ¥15 51单片机写代码,要求是图片上的要求,请大家积极参与,设计一个时钟,时间从12:00开始计时,液晶屏第一行显示time,第二行显示时间
  • ¥15 用C语言判断命题逻辑关系
  • ¥15 原子操作+O3编译,程序挂住
  • ¥15 使用STM32F103C6微控制器设计两个从0到F计数的一位数计数器(数字),同时,有一个控制按钮,可以选择哪个计数器工作:需要两个七段显示器和一个按钮。
  • ¥15 在yolo1到yolo11网络模型中,具体有哪些模型可以用作图像分类?
  • ¥15 AD9910输出波形向上偏移,波谷不为0V
  • ¥15 淘宝自动下单XPath自动点击插件无法点击特定<span>元素,如何解决?
  • ¥15 曙光1620-g30服务器安装硬盘后 看不到硬盘