转自:http://blog.sina.com.cn/s/blog_631a4cc40101df0f.html
先简要说一下支持向量机(support vector
machine,
SVM)吧。感知机(perceptron)是二分类的线性模型,但是由于不同初值或选取不同的样本顺序,解是不同的,也就是不唯一的。在此基础上svm引入间隔最大化(margin
maximization)不仅是样本更容易分开,而且解是唯一的。之后,为了容忍奇异点(outlier)引入松弛变量(slack
variable)(注:引入松弛变量之后w依然是唯一的,但是b不是唯一的)。但是并不是所有问题都是线性的,所以用kernel
track变成非线性模型。
在求解SVM的时候一般都用其对偶形式,主要有两个优点,其一提供了一种方便的方法去解决约束问题,其二对偶问题中的点积能够很好地处理kernel
function。而这个对偶函数又是一个二次规划问题。所以我们可以说求解SVM的本质就是在再生核希尔伯特空间(RKHS)上的二次优化问题。
如果你想详细了解,我建议看《支持向量机——理论、算法与拓展》邓乃扬 田英杰著。
这篇博文的主要是目的是把svm的matlab代码贴出来,供大家学习,代码有一部分是在网上找的一部分是我写的,解二次规划是用matlab的自带函数。把下面的代码直接复制就可运行,能够提高你对svm的理解。运行以下程序就能得到上面的图。
%主函数
clear all;
close all;
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]);
hold on;
X = [x1,x2];
%训练样本d*n矩阵,n为样本个数,d为特征向量个数
Y = [y1,y2];
%训练目标1*n矩阵,n为样本个数,值为+1或-1
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';
options.Display = 'off';
n = length(Y);
H = (Y'*Y).*kernel(X,X,kertype);
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;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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);
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
阅读(2858) | 评论(0) | 转发(0) |