增加了 预抽取预支持向量 的算法 效果如图 其中 * 为抽取的可能的支持向量
线性
非线性
function result=CalcValueBySVM(svm, x)
result=svm.b;
n=size(svm.y);
for j=1:n
if svm.a(j)~=0
result=result+ svm.a(j)*svm.y(j)*CalcKernel(svm.ker, x, svm.x(j,:));
end
end
Code
function SVM_Test
clear all
% ------------------------------------------------------------%
% 构造两类训练数据集 以 y=ax^2+ b*x+c 为分界线 shift
% if a==0 then it is a line
a=0;
b=3;
c=0.5;
shift=0.5;
b1=0.5;
xx=-1:0.1:1;
n = length(xx);
x1=zeros(n,2);
x2=zeros(n,2);
x1(:,1) = xx';
x2(:,1)=xx';
x1(:,2)=a*x1(:,1).*x1(:,1)+b*x1(:,1)+c + shift+ abs(randn(n,1)) ;
x2(:,2)=a*x2(:,1).*x2(:,1)+b*x2(:,1)+c - shift- abs(randn(n,1)) ;
y1 = ones(n,1);
y2 = -ones(n,1);
figure;
plot(x1(:,1),x1(:,2),'bx',x2(:,1),x2(:,2),'k.');
hold on;
X = [x1;x2]; % 训练样本
Y = [y1;y2]; % 训练目标,n×1的矩阵,n为样本个数,值为+1或-1
% ------------------------------------------------------------%
ker=struct('type','linear');
%ker=struct('type','Radial basis kernel','value',1);
% -------------FFMVM 预抽取预支持向量 ------------------------%
XX=X;
YY=Y;
[X,Y]=SVM_FFMVM(ker, XX, YY);
fprintf('原输入向量规模 \n')
sizeX=size(XX)
fprintf('抽取预支持向量规模 \n')
sizeX=size(X)
plot(X(:,1),X(:,2),'*');
% ------------------------------------------------------------%
svm=SVM_DivideTwoClass(ker,X,Y)
%plot the decision function curve
for i=1:n
tx1=x1(i,1);
tx2=a*tx1*tx1+b*tx1+c;
min=1000;
for step=-shift:0.01:shift
tx=[tx1,tx2+step];
f=CalcValueBySVM(svm,tx);
if(abs(f)<min)
min=abs(f);
decisionCurve(i,:)=tx;
end
end
end
plot(decisionCurve(:,1),decisionCurve(:,2));
for i=1:2*n
f=CalcValueBySVM(svm,XX(i,:));
YYY(i)=sign(f);
end
YYY=YYY'
Code
% 参考 安金龙 的 支持向量机若干问题的研究 FFMVM 预抽取预支持向量
function [support_vector_X,support_vector_Y]=SVM_FFMVM(kernel, X, Y)
dimensionX=size(X);
n=dimensionX(1);
possibleVectors=zeros(n,1);
for i=1:n
x=X(i,:);
y=Y(i);
minDistance=100000;
minX=1;
for j=1:n
if y~=Y(j)
distance=CalcDistanceByKernel(kernel,x,X(j,:));
if distance<minDistance
minDistance=distance;
minX=j;
end
end
end
possibleVectors(i)=minX; % the least distance from X(i,:)
fprintf('the least distance %d %d \n',i, minX)
end
count=1;
for i=1:n
k=possibleVectors(i);
exist=0;
for j=1:i-1
if k==possibleVectors(j)
exist=1;
break;
end
end
if exist==0
support_vector_X(count,:)=X(k,:);
support_vector_Y(count)=Y(k);
count=count+1;
end
end
support_vector_Y=support_vector_Y';
function result=CalcDistanceByKernel(kernel, x,y)
result=CalcKernel(kernel,x,x) + CalcKernel(kernel,y,y)-2*CalcKernel(kernel,x,y);