支持向量机的smo算法(MATLAB code)

建立smo.m

% function [alpha,bias] = smo(X, y, C, tol)

function model = smo(X, y, C, tol)

% SMO: SMO algorithm for SVM
%
%Implementation of the Sequential Minimal Optimization (SMO)
%training algorithm for Vapnik‘s Support Vector Machine (SVM)
%
% This is a modified code from Gavin Cawley‘s MATLAB Support
% Vector Machine Toolbox
% (c) September 2000.
%
% Diego Andres Alvarez.
%
% USAGE: [alpha,bias] = smo(K, y, C, tol)
%
% INPUT:
%
%   K: n x n kernel matrix
%   y: 1 x n vector of labels, -1 or 1
%   C: a regularization parameter such that 0 <= alpha_i <= C/n
%   tol: tolerance for terminating criterion
%
% OUTPUT:
%
%   alpha: 1 x n lagrange multiplier coefficient
%   bias: scalar bias (offset) term

% Input/output arguments modified by JooSeuk Kim and Clayton Scott, 2007

global SMO;

y = y‘;

ntp = size(X,1);
%recompute C
% C = C/ntp;

%initialize
ii0 = find(y == -1);
ii1 = find(y == 1);

i0 = ii0(1);
i1 = ii1(1);

alpha_init = zeros(ntp, 1);
alpha_init(i0) = C;
alpha_init(i1) = C;
bias_init = C*(X(i0,:)*X(i1,:)‘ -X(i0,:)*X(i1,:)‘) + 1;

%Inicializando las variables
SMO.epsilon = 10^(-6); SMO.tolerance = tol;
SMO.y = y‘; SMO.C = C;
SMO.alpha = alpha_init; SMO.bias = bias_init;
SMO.ntp = ntp; %number of training points

%CACHES:
SMO.Kcache = X*X‘; %kernel evaluations
SMO.error = zeros(SMO.ntp,1); %error 

numChanged = 0; examineAll = 1;

%When all data were examined and no changes done the loop reachs its
%end. Otherwise, loops with all data and likely support vector are
%alternated until all support vector be found.
while ((numChanged > 0) || examineAll)
    numChanged = 0;
    if examineAll
        %Loop sobre todos los puntos
        for i = 1:ntp
            numChanged = numChanged + examineExample(i);
        end;
    else
        %Loop sobre KKT points
        for i = 1:ntp
            %Solo los puntos que violan las condiciones KKT
            if (SMO.alpha(i)>SMO.epsilon) && (SMO.alpha(i)<(SMO.C-SMO.epsilon))
                numChanged = numChanged + examineExample(i);
            end;
        end;
    end;

    if (examineAll == 1)
        examineAll = 0;
    elseif (numChanged == 0)
        examineAll = 1;
    end;
end;
alpha = SMO.alpha‘;
alpha(alpha < SMO.epsilon) = 0;
alpha(alpha > C-SMO.epsilon) = C;
bias = -SMO.bias;

model.w = (y.*alpha)* X; %%%%%%%%%%%%%%%%%%%%%%
model.b = bias;

return;

function RESULT = fwd(n)
global SMO;
LN = length(n);
RESULT = -SMO.bias + sum(repmat(SMO.y,1,LN) .* repmat(SMO.alpha,1,LN) .* SMO.Kcache(:,n))‘;
return;

function RESULT = examineExample(i2)
%First heuristic selects i2 and asks to examineExample to find a
%second point (i1) in order to do an optimization step with two
%Lagrange multipliers

global SMO;
alpha2 = SMO.alpha(i2); y2 = SMO.y(i2);

if ((alpha2 > SMO.epsilon) && (alpha2 < (SMO.C-SMO.epsilon)))
    e2 = SMO.error(i2);
else
    e2 = fwd(i2) - y2;
end;

% r2 < 0 if point i2 is placed between margin (-1)-(+1)
% Otherwise r2 is > 0. r2 = f2*y2-1

r2 = e2*y2;
%KKT conditions:
% r2>0 and alpha2==0 (well classified)
% r2==0 and 0% r2<0 and alpha2==C (support vectors between margins)
%
% Test the KKT conditions for the current i2 point.
%
% If a point is well classified its alpha must be 0 or if
% it is out of its margin its alpha must be C. If it is at margin
% its alpha must be between 0%take action only if i2 violates Karush-Kuhn-Tucker conditions
if ((r2 < -SMO.tolerance) && (alpha2 < (SMO.C-SMO.epsilon))) || ...
((r2 > SMO.tolerance) && (alpha2 > SMO.epsilon))
    % If it doens‘t violate KKT conditions then exit, otherwise continue.

    %Try i2 by three ways; if successful, then immediately return 1;
    RESULT = 1;
    % First the routine tries to find an i1 lagrange multiplier that
    % maximizes the measure |E1-E2|. As large this value is as bigger
    % the dual objective function becames.
    % In this first test, only support vectors will be tested.

    POS = find((SMO.alpha > SMO.epsilon) & (SMO.alpha < (SMO.C-SMO.epsilon)));
    [MAX,i1] = max(abs(e2 - SMO.error(POS)));
    if ~isempty(i1)
        if takeStep(i1, i2, e2), return;
        end;
    end;

    %The second heuristic choose any Lagrange Multiplier that is a SV and tries to optimize
    for i1 = randperm(SMO.ntp)
        if (SMO.alpha(i1) > SMO.epsilon) & (SMO.alpha(i1) < (SMO.C-SMO.epsilon))
        %if a good i1 is found, optimise
            if takeStep(i1, i2, e2), return;
            end;
        end
    end

    %if both heuristc above fail, iterate over all data set
    for i1 = randperm(SMO.ntp)
        if ~((SMO.alpha(i1) > SMO.epsilon) & (SMO.alpha(i1) < (SMO.C-SMO.epsilon)))
            if takeStep(i1, i2, e2), return;
            end;
        end
    end;
end; 

%no progress possible
RESULT = 0;
return;

function RESULT = takeStep(i1, i2, e2)
% for a pair of alpha indexes, verify if it is possible to execute
% the optimisation described by Platt.

global SMO;
RESULT = 0;
if (i1 == i2), return;
end;

% compute upper and lower constraints, L and H, on multiplier a2
alpha1 = SMO.alpha(i1); alpha2 = SMO.alpha(i2);
y1 = SMO.y(i1); y2 = SMO.y(i2);
C = SMO.C; K = SMO.Kcache;

s = y1*y2;
if (y1 ~= y2)
    L = max(0, alpha2-alpha1); H = min(C, alpha2-alpha1+C);
else
    L = max(0, alpha1+alpha2-C); H = min(C, alpha1+alpha2);
end;

if (L == H), return;
end;

if (alpha1 > SMO.epsilon) & (alpha1 < (C-SMO.epsilon))
    e1 = SMO.error(i1);
else
    e1 = fwd(i1) - y1;
end;

%if (alpha2 > SMO.epsilon) & (alpha2 < (C-SMO.epsilon))
% e2 = SMO.error(i2);
%else
% e2 = fwd(i2) - y2;
%end;

%compute eta
k11 = K(i1,i1); k12 = K(i1,i2); k22 = K(i2,i2);
eta = 2.0*k12-k11-k22;

%recompute Lagrange multiplier for pattern i2
if (eta < 0.0)
    a2 = alpha2 - y2*(e1 - e2)/eta;

    %constrain a2 to lie between L and H
    if (a2 < L)
        a2 = L;
    elseif (a2 > H)
        a2 = H;
    end;
else
%When eta is not negative, the objective function W should be
%evaluated at each end of the line segment. Only those terms in the
%objective function that depend on alpha2 need be evaluated... 

    ind = find(SMO.alpha>0);

    aa2 = L; aa1 = alpha1 + s*(alpha2-aa2);

    Lobj = aa1 + aa2 + sum((-y1*aa1/2).*SMO.y(ind).*K(ind,i1) + (-y2*aa2/2).*SMO.y(ind).*K(ind,i2));

    aa2 = H; aa1 = alpha1 + s*(alpha2-aa2);
    Hobj = aa1 + aa2 + sum((-y1*aa1/2).*SMO.y(ind).*K(ind,i1) + (-y2*aa2/2).*SMO.y(ind).*K(ind,i2));

    if (Lobj>Hobj+SMO.epsilon)
        a2 = H;
    elseif (Lobj<Hobj-SMO.epsilon)
        a2 = L;
    else
        a2 = alpha2;
    end;
end;

if (abs(a2-alpha2) < SMO.epsilon*(a2+alpha2+SMO.epsilon))
    return;
end;

% recompute Lagrange multiplier for pattern i1
a1 = alpha1 + s*(alpha2-a2);

w1 = y1*(a1 - alpha1); w2 = y2*(a2 - alpha2);

%update threshold to reflect change in Lagrange multipliers
b1 = SMO.bias + e1 + w1*k11 + w2*k12;
bold = SMO.bias;

if (a1>SMO.epsilon) & (a1<(C-SMO.epsilon))
    SMO.bias = b1;
else
    b2 = SMO.bias + e2 + w1*k12 + w2*k22;
    if (a2>SMO.epsilon) & (a2<(C-SMO.epsilon))
        SMO.bias = b2;
    else
        SMO.bias = (b1 + b2)/2;
    end;
end;

% update error cache using new Lagrange multipliers
SMO.error = SMO.error + w1*K(:,i1) + w2*K(:,i2) + bold - SMO.bias;
SMO.error(i1) = 0.0; SMO.error(i2) = 0.0;

% update vector of Lagrange multipliers
SMO.alpha(i1) = a1; SMO.alpha(i2) = a2;

%report progress made
RESULT = 1;
return;

画图文件:start_SMOforSVM.m(点击自动生成二维两类数据,画图,这里只是线性的,非线性的可以对应修改)

clear
X = []; Y=[];
figure;
% Initialize training data to empty; will get points from user
% Obtain points froom the user:
trainPoints=X;
trainLabels=Y;
clf;
axis([-5 5 -5 5]);
if isempty(trainPoints)
	% Define the symbols and colors we‘ll use in the plots later
	symbols = {‘o‘,‘x‘};
	classvals = [-1 1];
	trainLabels=[];
    hold on; % Allow for overwriting existing plots
    xlim([-5 5]); ylim([-5 5]);

    for c = 1:2
        title(sprintf(‘Click to create points from class %d. Press enter when finished.‘, c));
        [x, y] = getpts;

        plot(x,y,symbols{c},‘LineWidth‘, 2, ‘Color‘, ‘black‘);

        % Grow the data and label matrices
        trainPoints = vertcat(trainPoints, [x y]);
        trainLabels = vertcat(trainLabels, repmat(classvals(c), numel(x), 1));
    end

end

% C = 10;tol = 0.001;
% par = SMOforSVM(trainPoints, trainLabels , C, tol );
% p=length(par.b); m=size(trainPoints,2);
%  if m==2
% %     for i=1:p
% %         plot(X(lc(i)-l(i)+1:lc(i),1),X(lc(i)-l(i)+1:lc(i),2),‘bo‘)
% %         hold on
% %     end
%     k = -par.w(1)/par.w(2);
%     b0 = - par.b/par.w(2);
%     bdown=(-par.b-1)/par.w(2);
%     bup=(-par.b+1)/par.w(2);
%     for i=1:p
%         hold on
%         h = refline(k,b0(i));
%         set(h, ‘Color‘, ‘r‘)
%         hdown=refline(k,bdown(i));
%         set(hdown, ‘Color‘, ‘b‘)
%         hup=refline(k,bup(i));
%         set(hup, ‘Color‘, ‘b‘)
%     end
%  end
% xlim([-5 5]); ylim([-5 5]);
%
% pause

C = 10;tol = 0.001;
par = smo(trainPoints, trainLabels, C, tol);
p=length(par.b); m=size(trainPoints,2);
 if m==2
%     for i=1:p
%         plot(X(lc(i)-l(i)+1:lc(i),1),X(lc(i)-l(i)+1:lc(i),2),‘bo‘)
%         hold on
%     end
    k = -par.w(1)/par.w(2);
    b0 = - par.b/par.w(2);
    bdown=(-par.b-1)/par.w(2);
    bup=(-par.b+1)/par.w(2);
    for i=1:p
        hold on
        h = refline(k,b0(i));
        set(h, ‘Color‘, ‘r‘)
        hdown=refline(k,bdown(i));
        set(hdown, ‘Color‘, ‘b‘)
        hup=refline(k,bup(i));
        set(hup, ‘Color‘, ‘b‘)
    end
 end
xlim([-5 5]); ylim([-5 5]);

  

时间: 2024-10-05 06:05:28

支持向量机的smo算法(MATLAB code)的相关文章

smo算法matlab实现

看完CSDN上结构之法,算法之道的支持向量机通俗导论(理解SVM的三层境界) http://blog.csdn.net/v_july_v/article/details/7624837 参考了台湾的林智仁教授写了一个封装SVM算法的libsvm库,下载地址: http://www.csie.ntu.edu.tw/~cjlin/libsvm/,此外下载了一份libsvm的注释文档,下载地址: http://www.pami.sjtu.edu.cn/people/gpliu/document/lib

支持向量机(SVM)(五)-- SMO算法详解

一.我们先回顾下SVM问题. A.线性可分问题 1.SVM基本原理: SVM使用一种非线性映射,把原训练            数据映射到较高的维.在新的维上,搜索最佳分离超平面,两个类的数据总可以被超平面分开. 2.问题的提出: 3.如何选取最优的划分直线f(x)呢? 4.求解:凸二次规划 建立拉格朗日函数: 求偏导数: B.线性不可分问题 1.核函数 如下图:横轴上端点a和b之间红色部分里的所有点定为正类,两边的黑色部分里的点定为负类. 设: g(x)转化为f(y)=<a,y> g(x)=

【机器学习算法-python实现】svm支持向量机(2)—简化版SMO算法

(转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景知识 通过上一节我们通过引入拉格朗日乗子得到支持向量机变形公式.详细变法可以参考这位大神的博客--地址 参照拉格朗日公式F(x1,x2,...λ)=f(x1,x2,...)-λg(x1,x2...).我们把上面的式子变型为: 约束条件就变成了: 下面就根据最小优化算法SMO(Sequential Minimal Optimization).找出距离分隔面最近的点,也就是支持向量集.如下图的蓝色点所示.

[笔记]关于支持向量机(SVM)中 SMO算法的学习(一)理论总结

1. 前言 最近又重新复习了一遍支持向量机(SVM).其实个人感觉SVM整体可以分成三个部分: 1. SVM理论本身:包括最大间隔超平面(Maximum Margin Classifier),拉格朗日对偶(Lagrange Duality),支持向量(Support Vector),核函数(Kernel)的引入,松弛变量的软间隔优化(Outliers),最小序列优化(Sequential Minimal Optimization)等. 2. 核方法(Kernel):其实核方法的发展是可以独立于S

支持向量机原理(四)SMO算法原理

支持向量机原理(一) 线性支持向量机 支持向量机原理(二) 线性支持向量机的软间隔最大化模型 支持向量机原理(三)线性不可分支持向量机与核函数 支持向量机原理(四)SMO算法原理 支持向量机原理(五)线性支持回归(待填坑) 在SVM的前三篇里,我们优化的目标函数最终都是一个关于\alpha向量的函数.而怎么极小化这个函数,求出对应的\alpha向量,进而求出分离超平面我们没有讲.本篇就对优化这个关于\alpha向量的函数的SMO算法做一个总结. 1. 回顾SVM优化目标函数 我们首先回顾下我们的

理解支持向量机(三)SMO算法

在支持向量机模型的求解中,我们用到了SMO算法来求解向量α. 那么什么是SMO算法?在讲SMO算法之前.我们须要先了解下面坐标上升法. 1.坐标上升法 如果有优化问题: W是α向量的函数.利用坐标上升法(当然,求目标函数的最小时即为坐标下降法)求解问题最优的步骤例如以下: 算法的思想为:每次仅仅考虑一个变量进行优化,将其它变量固定.这时整个函数能够看作仅仅关于该变量的函数,能够对其直接求导计算. 然后继续求其它分变量的值,整个内循环下来就得到了α的一组值,若该组值满足条件.即为我们求的值,否则继

【转载】支持向量机(五)SMO算法

支持向量机(五)SMO算法 11 SMO优化算法(Sequential minimal optimization) SMO算法由Microsoft Research的John C. Platt在1998年提出,并成为最快的二次规划优化算法,特别针对线性SVM和数据稀疏时性能更优.关于SMO最好的资料就是他本人写的<Sequential Minimal Optimization A Fast Algorithm for Training Support Vector Machines>了. 我拜

SVM之SMO算法(转)

支持向量机(Support Vector Machine)-----SVM之SMO算法(转) 此文转自两篇博文 有修改 序列最小优化算法(英语:Sequential minimal optimization, SMO)是一种用于解决支持向量机训练过程中所产生优化问题的算法.SMO由微软研究院的约翰·普莱特(John Platt)发明于1998年,目前被广泛使用于SVM的训练过程中,并在通行的SVM库libsvm中得到实现. 1998年,SMO算法发表在SVM研究领域内引起了轰动,因为先前可用的S

SMO算法总结

1.概述 SMO(Sequentil Minimal Optimization)算法在支持向量机中用来求解对偶问题,即 min 12∑Ni=1∑Nj=1αiαjyiyjK(xi,xj)?∑Ni=1αi s.t.∑αiyi=0 0?αiyi?C 在这个问题中,变量是拉格朗日乘子α,一个αi对应一个样本点(xi,yi),变量总数等于样本数量N. SMO算法是一个启发式的算法,它的基本思路是:如果所有变量的解都满足KKT条件,即: ?????????????????αi≥0yif(xi)?1+ξ≥0α