简单粗暴理解支持向量机(SVM)及其MATLAB实例

简单粗暴理解支持向量机(SVM)及其MATLAB实例目录SVM概述SVM的改进:解决回归拟合问题的SVR多分类的SVMQP求解SVM的MATLAB实现:Libsvm【实例】用SVM分类【实例】用SVM回归SVM概述SVM已经是非常流行、大家都有所耳闻的技术了。网络上也有很多相关的博客,讲解得都非常详细。如果你要从零开始推导一个SVM,细致抠它全程的数学原理,我建议可以阅读此篇文章:ZhangHao的《从零构建支…

大家好,又见面了,我是你们的朋友全栈君。

目录

SVM概述

SVM的改进:解决回归拟合问题的SVR

多分类的SVM

QP求解

SVM的MATLAB实现:Libsvm

【实例】用SVM分类

【实例】用SVM回归


SVM概述

SVM已经是非常流行、大家都有所耳闻的技术了。网络上也有很多相关的博客,讲解得都非常详细。如果你要从零开始推导一个SVM,细致抠它全程的数学原理,我建议可以阅读此篇文章:Zhang Hao的《从零构建支持向量机》。因此本文就不做过多的枯燥的数学原理的讲解。

下面我们只针对数学基础不一、偏工程应用的同学,用简单的语言描述来帮助理解SVM。

简单粗暴理解支持向量机(SVM)及其MATLAB实例

传统的SVM做的事情其实就是找到一个超平面,实现二分类,一类+1,一类-1。如上所示。它的目的就是使得两类的间隔最大。黑色的块表示距离分割面最近的样本向量,称为支持向量

如果我们在低维空间里找不到一个线性分类面把样本分开,SVM就为我们提供了一个思路:将数据从低维空间映射到高维空间后,就很可能使得这堆数据线性可分。比如说,我们要在猫科动物这个特征很局限的“低维空间”里去分猫和老虎,是比较困难的,因为他们很多特征比较相近。但是,如果我们有了更多的参考依据,从生物界的视角,即一个“高维空间”再去区分猫和老虎,我们就有了更多的理由来做出科学的辨别。至于如何低维映射到高维,就是一门数学上的学问了。

简单粗暴理解支持向量机(SVM)及其MATLAB实例

数据从输入到输出的过程其实和神经网络非常像:

简单粗暴理解支持向量机(SVM)及其MATLAB实例

K就是核函数,做一个内积的运算。SVM中核函数保证了低维空间里的计算量,输出到高维空间里。

K相当于隐含层的神经元。核函数的输出乘上权重,进入激活函数处。

简单粗暴理解支持向量机(SVM)及其MATLAB实例

SVM的改进:解决回归拟合问题的SVR

  • 为了利用SVM解决回归拟合方面的问题,Vapnik等人在SVM分 类的基础上引入了 不敏感损失函数,从而得到了回归型支持向 量机(Support Vector Machine for Regression,SVR)。

  • SVM应用于回归拟合分析时,其基本思想不再是寻找一个最优 分类面使得两类样本分开,而是寻找一个最优分类面使得所有 训练样本离该最优分类面的误差最小

简单粗暴理解支持向量机(SVM)及其MATLAB实例

多分类的SVM

当我们要分多类,而不是简单的二分类(+1,-1)时,怎么破?

解决思路:把多分类转化为二分类问题。具体来看有两个办法:

1. one-against-all

      Classification of new instances for one-against-all case is done by a winner-takes-all strategy, in which the classifier

with the highest output function assigns the class.

比如有一堆样本,打算分成10类。那么我们先取第1类训练标记为【1】。其他9类都是【-1】。这样经过一次SVM就可以得到第1类。

然后我们对【-1】中的9类继续做上述操作,分出第2类。

再以此类对,逐渐把第3、第4类分出来……直至分完。

2. one-against-one

       For the one-against-one approach, classification is done by a max-wins voting strategy, in which every classifier assigns the instance to one of the two classes, then the vote for the assigned class is increased by one vote, and finally the class with most votes determines the instance classification.

比如,一共有10种类别的一堆数据。那么我们就要训练C{2,5}=10(组合数)个SVM分类器。每个SVM分类器都可以区分出两种类别。我们把数据分别输入到这10个SVM分类器中,根据结果进行投票,依据得票数最多来确定它的类别。

QP求解

大致有下面4种方法:

分块算法(Chunking)

Osuna算法

序列最小优化算法(Sequential Minimal Optimization,SMO)

增量学习算法(IncrementalLearning)

数学原理比较难解释清楚,大家可以看Zhang Hao的那篇文章细究。

SVM的MATLAB实现:Libsvm

工具箱下载:https://github.com/cjlin1/libsvm

首先,要给macOS系统的Matlab,配置好xcode支持的编译器:https://blog.csdn.net/lyxleft/article/details/83756592

在MacOS X系统上,为matlab安装libsvm工具箱:https://www.jianshu.com/p/f45e1828ed85

重要函数:

  • meshgrid 交叉验证用

    • –  Generate X and Y arrays for 3-D plots

    • –  [X,Y] = meshgrid(x,y) –

  • svmtrain

    • –  Train support vector machine classifier

    • –  model = svmtrain(train_label,train_matrix,’libsvm_options’);

    • Options:可用的选项即表示的涵义如下:
        -s svm类型:SVM设置类型(默认0)
          0 — C-SVC
          1 — nu-SVC
          2 — one-class SVM
          3 — epsilon-SVR
          4 — nu-SVR
        -t 核函数类型:核函数设置类型(默认2)
          0 — linear: u’*v 线性
          1 — polynomial: (gamma*u’*v + coef0)^degree   多项式
          2 — radial basis function: exp(-gamma*|u-v|^2) RBF
          3 — sigmoid: tanh(gamma*u’*v + coef0)
          4 — precomputed kernel (kernel values in training_instance_matrix)
        -d degree:核函数中的degree设置(针对多项式核函数)(默认3)
        -g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/ k)
        -r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
        -c cost:设置C-SVC,e -SVR和v-SVR的参数(损失函数)(默认1)  惩罚因子
        -n nu:设置v-SVC,一类SVM和v- SVR的参数(默认0.5)
        -p p:设置e -SVR 中损失函数p的值(默认0.1)
        -m cachesize:设置cache内存大小,以MB为单位(默认40)
        -e eps:设置允许的终止判据(默认0.001)
        -h shrinking:是否使用启发式,0或1(默认1)
        -wi weight:设置第几类的参数C为weight*C(C-SVC中的C)(默认1)
        -v n: n-fold交互检验模式,n为fold的个数,必须大于等于2
        其中-g选项中的k是指输入数据中的属性数。option -v 随机地将数据剖分为n部分并计算交互检验准确度和均方根误差。
         以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。

  • svmpredict

    • –  Predict data using support vector machine

    • –  [predict_label,accuracy] = svmpredict(test_label,test_matrix,model);

下面要用到的数据集在:链接:https://pan.baidu.com/s/1XwhynjKuJOVsa5Nxi9NVaA  密码:d0u7

【实例】用SVM分类

%% I. 清空环境变量
clear all
clc

%% II. 导入数据
load BreastTissue_data.mat

%%
% 1. 随机产生训练集和测试集
n = randperm(size(matrix,1));

%%
% 2. 训练集――80个样本
train_matrix = matrix(n(1:80),:);
train_label = label(n(1:80),:);

%%
% 3. 测试集――26个样本
test_matrix = matrix(n(81:end),:);
test_label = label(n(81:end),:);

%% III. 数据归一化
[Train_matrix,PS] = mapminmax(train_matrix');
Train_matrix = Train_matrix';
Test_matrix = mapminmax('apply',test_matrix',PS);
Test_matrix = Test_matrix';

%% IV. SVM创建/训练(RBF核函数)
%%
% 1. 寻找最佳c/g参数――交叉验证方法
[c,g] = meshgrid(-10:0.2:10,-10:0.2:10);
[m,n] = size(c);
cg = zeros(m,n);
eps = 10^(-4);
v = 5;
bestc = 1;
bestg = 0.1;
bestacc = 0;
for i = 1:m
    for j = 1:n
        cmd = ['-v ',num2str(v),' -t 2',' -c ',num2str(2^c(i,j)),' -g ',num2str(2^g(i,j))];
        cg(i,j) = svmtrain(train_label,Train_matrix,cmd);     
        if cg(i,j) > bestacc
            bestacc = cg(i,j);
            bestc = 2^c(i,j);
            bestg = 2^g(i,j);
        end        
        if abs( cg(i,j)-bestacc )<=eps && bestc > 2^c(i,j) 
            bestacc = cg(i,j);
            bestc = 2^c(i,j);
            bestg = 2^g(i,j);
        end               
    end
end
cmd = [' -t 2',' -c ',num2str(bestc),' -g ',num2str(bestg)];

%%
% 2. 创建/训练SVM模型
model = svmtrain(train_label,Train_matrix,cmd);

%% V. SVM仿真测试
[predict_label_1,accuracy_1] = svmpredict(train_label,Train_matrix,model);
[predict_label_2,accuracy_2] = svmpredict(test_label,Test_matrix,model);
result_1 = [train_label predict_label_1];
result_2 = [test_label predict_label_2];

%% VI. 绘图
figure
plot(1:length(test_label),test_label,'r-*')
hold on
plot(1:length(test_label),predict_label_2,'b:o')
grid on
legend('真实类别','预测类别')
xlabel('测试集样本编号')
ylabel('测试集样本类别')
string = {'测试集SVM预测结果对比(RBF核函数)';
          ['accuracy = ' num2str(accuracy_2(1)) '%']};
title(string)

【实例】用SVM回归

%% I. 清空环境变量
clear all
clc

%% II. 导入数据
load concrete_data.mat

%%
% 1. 随机产生训练集和测试集
n = randperm(size(attributes,2));

%%
% 2. 训练集――80个样本
p_train = attributes(:,n(1:80))';
t_train = strength(:,n(1:80))';

%%
% 3. 测试集――23个样本
p_test = attributes(:,n(81:end))';
t_test = strength(:,n(81:end))';

%% III. 数据归一化
%%
% 1. 训练集
[pn_train,inputps] = mapminmax(p_train');
pn_train = pn_train';
pn_test = mapminmax('apply',p_test',inputps);
pn_test = pn_test';

%%
% 2. 测试集
[tn_train,outputps] = mapminmax(t_train');
tn_train = tn_train';
tn_test = mapminmax('apply',t_test',outputps);
tn_test = tn_test';

%% IV. SVM模型创建/训练
%%
% 1. 寻找最佳c参数/g参数
[c,g] = meshgrid(-10:0.5:10,-10:0.5:10);
[m,n] = size(c);
cg = zeros(m,n);
eps = 10^(-4);
v = 5;
bestc = 0;
bestg = 0;
error = Inf;
for i = 1:m
    for j = 1:n
        cmd = ['-v ',num2str(v),' -t 2',' -c ',num2str(2^c(i,j)),' -g ',num2str(2^g(i,j) ),' -s 3 -p 0.1'];
        cg(i,j) = svmtrain(tn_train,pn_train,cmd);
        if cg(i,j) < error
            error = cg(i,j);
            bestc = 2^c(i,j);
            bestg = 2^g(i,j);
        end
        if abs(cg(i,j) - error) <= eps && bestc > 2^c(i,j)
            error = cg(i,j);
            bestc = 2^c(i,j);
            bestg = 2^g(i,j);
        end
    end
end

%%
% 2. 创建/训练SVM  
cmd = [' -t 2',' -c ',num2str(bestc),' -g ',num2str(bestg),' -s 3 -p 0.01'];
model = svmtrain(tn_train,pn_train,cmd);

%% V. SVM仿真预测
[Predict_1,error_1] = svmpredict(tn_train,pn_train,model);
[Predict_2,error_2] = svmpredict(tn_test,pn_test,model);

%%
% 1. 反归一化
predict_1 = mapminmax('reverse',Predict_1,outputps);
predict_2 = mapminmax('reverse',Predict_2,outputps);

%%
% 2. 结果对比
result_1 = [t_train predict_1];
result_2 = [t_test predict_2];

%% VI. 绘图
figure(1)
plot(1:length(t_train),t_train,'r-*',1:length(t_train),predict_1,'b:o')
grid on
legend('真实值','预测值')
xlabel('样本编号')
ylabel('耐压强度')
string_1 = {'训练集预测结果对比';
           ['mse = ' num2str(error_1(2)) ' R^2 = ' num2str(error_1(3))]};
title(string_1)
figure(2)
plot(1:length(t_test),t_test,'r-*',1:length(t_test),predict_2,'b:o')
grid on
legend('真实值','预测值')
xlabel('样本编号')
ylabel('耐压强度')
string_2 = {'测试集预测结果对比';
           ['mse = ' num2str(error_2(2)) ' R^2 = ' num2str(error_2(3))]};
title(string_2)

%% VII. BP神经网络
%%
% 1. 数据转置
pn_train = pn_train';
tn_train = tn_train';
pn_test = pn_test';
tn_test = tn_test';

%%
% 2. 创建BP神经网络
net = newff(pn_train,tn_train,10);

%%
% 3. 设置训练参数
net.trainParam.epochs = 1000;
net.trainParam.goal = 1e-3;
net.trainParam.show = 10;
net.trainParam.lr = 0.1;

%%
% 4. 训练网络
net = train(net,pn_train,tn_train);

%%
% 5. 仿真测试
tn_sim = sim(net,pn_test);

%%
% 6. 均方误差
E = mse(tn_sim - tn_test);

%%
% 7. 决定系数
N = size(t_test,1);
R2=(N*sum(tn_sim.*tn_test)-sum(tn_sim)*sum(tn_test))^2/((N*sum((tn_sim).^2)-(sum(tn_sim))^2)*(N*sum((tn_test).^2)-(sum(tn_test))^2)); 

%%
% 8. 反归一化
t_sim = mapminmax('reverse',tn_sim,outputps);

%%
% 9. 绘图
figure(3)
plot(1:length(t_test),t_test,'r-*',1:length(t_test),t_sim,'b:o')
grid on
legend('真实值','预测值')
xlabel('样本编号')
ylabel('耐压强度')
string_3 = {'测试集预测结果对比(BP神经网络)';
           ['mse = ' num2str(E) ' R^2 = ' num2str(R2)]};
title(string_3)

更正:

有些同学跑不了我给的程序。引用评论里同学的指导:(最近太忙还没时间细看,先贴在此处给大家参考)

第一个实例:用SVM分类 中,第62 63行代码 [predict_label_1,accuracy_1] = svmpredict(train_label,Train_matrix,model); [predict_label_2,accuracy_2] = svmpredict(test_label,Test_matrix,model); 需要改为: [predict_label_1,accuracy_1,decision_values1] = svmpredict(train_label,Train_matrix,model); [predict_label_2,accuracy_2,decision_values2] = svmpredict(test_label,Test_matrix,model); 第二个实例:用SVM回归 中,第71 72行代码 [Predict_1,error_1] = svmpredict(tn_train,pn_train,model); [Predict_2,error_2] = svmpredict(tn_test,pn_test,model); 需要改为: [Predict_1,error_1,decision_values1] = svmpredict(tn_train,pn_train,model); [Predict_2,error_2,decision_values2] = svmpredict(tn_test,pn_test,model);

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/135024.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • USB协议详解

    USB协议详解本博客整理自网络,仅供学习参考,如有侵权,联系删除。邮箱:rom100@163.com一个transfer(传输)由一个或多个transaction(事务)构成,一个transaction(事务)由一个或多个packet(包)构成,一个packet(包)由一个或多个sync(域)构成。1.传输数据通信USB的数据通讯首先是基于传输(transfer)的,传输的类型有:中断传输、批量传输…

    2022年6月29日
    44
  • python:类基础「建议收藏」

    python:类基础「建议收藏」1、面向对象编程(oop)是一种程序设计思想。oop把对象作为程序的基本单元,一个对象包含数据和操作数据的函数2、在python中,所有数据类型都被视为对象,也可以自定义对象。自定义对象数据类型就是面向对象中类的概念1、类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例2、方法:类中定义的函数3、类变量(属性):类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体(方法)之外。类变量通常不作为实例变量使用,类变量也称作属性4、数

    2022年7月23日
    9
  • java socket通讯乱码问题的解决

    java socket通讯乱码问题的解决使用socket通讯经常会遇到客户端、服务器端字符编码不一致的情况,如果传输的信息包含中文,这时我们可能就需要对传输的信息的按照指定的字符集进行解码或者编码首先我们了解jdkapi中的几个基本的概念String类StringpublicString(byte[] bytes,String charsetName)th

    2022年7月8日
    58
  • pta集合相似度_结构相似度

    pta集合相似度_结构相似度原题链接输入样例:33 99 87 1014 87 101 5 877 99 101 18 5 135 18 9921 21 3输出样例:50.00%33.33%#include<bits/stdc++.h>#define x first#define y second#define send string::nopsusing namespace std;typedef long long ll;const int N = 1e4 + 10;cons

    2022年8月8日
    4
  • 实战:WEB攻击之网页脚本攻击试验

    实战:WEB攻击之网页脚本攻击试验

    2021年8月24日
    55
  • voliate关键字[通俗易懂]

    voliate关键字[通俗易懂]1.voliate简介在上一篇文章中我们深入理解了java关键字synchronized,我们知道在java中还有一大神器就是关键volatile,可以说是和synchronized各领风骚,其中奥妙,我们来共同探讨下.通过上一篇的文章我们了解到synchronized是阻塞同步的,在线程竞争激烈的情况下会升级为重量级锁。而voliate就可以说是java虚拟机提供的最轻量级的同步锁。但它同时…

    2022年4月29日
    82

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号