点击上方蓝字关注“公众号”
![ffa72d4b7ebd4cd2280d7adab9bf519e.gif](https://i-blog.csdnimg.cn/blog_migrate/bd75dbbb8306bb3737fb89f0bc6623f7.gif)
基于matlab的支持向量机分类、回归问题
Part.1
支持向量机(support vector machines)是一种二分类模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。
![f2ec11123e759b7a7b6e3b989ced8a08.gif](https://i-blog.csdnimg.cn/blog_migrate/2bda1c1a11777dfd742543a9648eb434.gif)
对于线性可分来说程序一大筐,今天我们主要来讲非线性问题。主要有二分类、一分类和回归问题的处理。
![d0e26d265b1c598b4bec8b627f0cbaf0.gif](https://i-blog.csdnimg.cn/blog_migrate/b28cd64a31416374f9553257d8dbac1d.gif)
对于这样的问题,可以将训练样本从原始空间映射到一个更高维的空间,使得样本在这个空间中线性可分,如果原始空间维数是有限的,即属性是有限的,那么一定存在一个高维特征空间使样本可分。
![91fd736734bb3083e235a6f5d76c3946.png](https://i-blog.csdnimg.cn/blog_migrate/b1bddac3c323015289cf8b134d69fa3f.png)
令ϕ(x)表示将 x 映射后的特征向量,于是在特征空间中,划分超平面所对应的的模型可表示为:
f(x)=wTϕ(x)+b
于是有最小化函数:
在实际应用中,通常人们会从一些常用的核函数里选择(根据样本数据的不同,选择不同的参数,实际上就得到了不同的核函数)。
![1c6b6ff772d9e868f3333fe96f0805e0.png](https://i-blog.csdnimg.cn/blog_migrate/5bce20e531ccab5c42cd824c0697a652.png)
Part.2
下面介绍每一个程序的思想。
核函数
首先是编写核函数:
function [K] = kernel(ker,x,y)
% x: 输入样本,d×n1的矩阵,n1为样本个数,d为样本维数
% y: 输入样本,d×n2的矩阵,n2为样本个数,d为样本维数
% ker 核参数(结构体变量)
% K: 输出核参数,n1×n2的矩阵
switch ker.type
case 'linear'
K = x'*y;
case 'ploy'
d = ker.degree;
c = ker.offset;
K = (x'*y+c).^d;
case 'gauss'
s = ker.width;
rows = size(x,2);
cols = size(y,2);
tmp = zeros(rows,cols);
for i = 1:rows
for j = 1:cols
tmp(i,j) = norm(x(:,i)-y(:,j));
end
end
K = exp(-0.5*(tmp/s).^2);
case 'tanh'
g = ker.gamma;
c = ker.offset;
K = tanh(g*x'*y+c);
otherwise
K = 0;
end
决策函数
function Yd = svmSim(svm,Xt)
cathe = 10e+6; % kernel输出的元素个数的上限
nx = size(svm.x,2); % 训练样本数
nt = size(Xt,2); % 测试样本数
block = ceil(nx*nt/cathe); % 分块处理
num = ceil(nt/block); % 每块测试样本数
for i = 1:block
if (i==block)
index = [(i-1)*num+1:nt];
else
index = (i-1)*num+[1:num];
end
Yd(index) = svmSim_block(svm,Xt(:,index));
% 测试输出
end
function Yd = svmSim_block(svm,Xt);
% x - 训练样本
% y - 训练目标;
% a - 拉格朗日乘子
% Xt 测试样本,d×n的矩阵,n为样本个数,d为样本维数
% 输出参数:
% Yd 测试输出,1×n的矩阵,n为样本个数,值为+1或-1
type = svm.type;
ker = svm.ker;
X = svm.x;
Y = svm.y;
a = svm.a;
% 测试输出
epsilon = 1e-8;