% 支持向量机SVM分类算法
clear all
% ------------------------------------------------------------%
% 构造两类训练数据集 x2=aa*x1+bb+(-)b1
aa=3;
bb=6;
b1=0.2;
x1(:,1) = -1:0.1:1;
n = length(x1(:,1));
x1(:,2) = aa.*x1(:,1) + bb + b1 + abs(randn(n,1));
y1 = ones(n,1);
x2(:,1) = -1:0.1:1;
x2(:,2) = aa.*x2(:,1) + bb - b1 - abs(randn(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
% ------------------------------------------------------------%
tic
% 解二次优化方城
n = length(Y);
H = (Y*Y').*(X*X'); % liner kernel
f = -ones(n,1);
A = [];
b = [];
Aeq = Y';
beq = 0;
lb = zeros(n,1);
ub = 100*ones(n,1);
a0 = zeros(n,1);
options = optimset;
options.LargeScale = 'off';
options.Display = 'off';
[a,fval,eXitflag,output,lambda] = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
eXitflag
time=toc
%先复制上面的代码 运行后 再复制下面的代码 运行 呵呵 (对Matlab不熟,不知道为什么一次执行和分开执行看到的结果不同)
% 以下是分类平面:
Y2=a.*Y;
W(1)=sum(Y2.*(X(:,1)));
W(2)=sum(Y2.*(X(:,2)));
aLarge=find(a>0.1);
j=aLarge(1);
S(:,1)=Y.*a.*X(:,1);
S(:,2)=Y.*a.*X(:,2);
S2=S*(X(j,:)');
b=Y(j)-sum(S2);
xx1=x1(:,1);
xx2=-(W(1)*xx1+b)/W(2);
plot(xx1,xx2);
线性核 分界线
径向基核 分界线 可以看出非线性核可以拟合非线性曲线(对应 核空间中的线性曲线)
代码如下 还有部分小bug 例如有时候随机生成的数据 对应奇异矩阵 解二次规划 解不出来 此时可以重新运行
代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

1
function result=CalcValueBySVM(svm, x)
2
3
4
result=svm.b;
5
6
n=size(svm.y);
7
8
for j=1:n
9
result=result+ svm.a(j)*svm.y(j)*CalcKernel(svm.ker, x, svm.x(j,:));
10
end
11
12
13

2

3

4

5

6

7

8

9

10

11

12

13


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

补充以前漏的,呵呵,刚刚调试出来的

%---------------- author: feathersky----------------
function svm=SVM_DivideTwoClass(ker, X,Y)
% 解二次优化方城
n = length(Y);
%H = (Y*Y').*(X*X'); % liner kernel
H = (Y*Y').*CalcKernel(ker,X,X); % kernel
f = -ones(n,1);
A = [];
b = [];
Aeq = Y';
beq = 0;
lb = zeros(n,1);
ub = 1000*ones(n,1);
a0 = zeros(n,1);
options = optimset;
options.LargeScale = 'off';
options.Display = 'off';
[a,fval,eXitflag,output,lambda] = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
eXitflag
svm.ker=ker;
svm.x=X;
svm.y=Y;
svm.a=a;
% aLarge=find(a>0.01); %找到第一个不等于0的a ,
% j=aLarge(1);
% svm.b=Y(j)-CalcKernel(ker,X(j,:),w);
% ------------------------------------------------------------%%
% 求 b
epsilon = 1e-8; % 如果小于此值则认为是0
i_sv = find(a>epsilon); % 支持向量下标
tmp = (Y.*a)'*CalcKernel(ker,X,X(i_sv,:)); % 行向量
b = 1./Y(i_sv)-tmp';
b = mean(b);
svm.b=b
fprintf('Construct function Y = sign(tmp+b):')
% ------------------------------------------------------------%
function svm=SVM_DivideTwoClass(ker, X,Y)
% 解二次优化方城
n = length(Y);
%H = (Y*Y').*(X*X'); % liner kernel
H = (Y*Y').*CalcKernel(ker,X,X); % kernel
f = -ones(n,1);
A = [];
b = [];
Aeq = Y';
beq = 0;
lb = zeros(n,1);
ub = 1000*ones(n,1);
a0 = zeros(n,1);
options = optimset;
options.LargeScale = 'off';
options.Display = 'off';
[a,fval,eXitflag,output,lambda] = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
eXitflag
svm.ker=ker;
svm.x=X;
svm.y=Y;
svm.a=a;
% aLarge=find(a>0.01); %找到第一个不等于0的a ,
% j=aLarge(1);
% svm.b=Y(j)-CalcKernel(ker,X(j,:),w);
% ------------------------------------------------------------%%
% 求 b
epsilon = 1e-8; % 如果小于此值则认为是0
i_sv = find(a>epsilon); % 支持向量下标
tmp = (Y.*a)'*CalcKernel(ker,X,X(i_sv,:)); % 行向量
b = 1./Y(i_sv)-tmp';
b = mean(b);
svm.b=b
fprintf('Construct function Y = sign(tmp+b):')
% ------------------------------------------------------------%