EDA365电子论坛网

标题: SVM matlab 代码详解说明 [打印本页]

作者: baqiao    时间: 2020-4-30 10:48
标题: SVM matlab 代码详解说明
本帖最后由 baqiao 于 2020-4-30 13:18 编辑
0 b+ h. z$ \- a: R* g( s* G" K3 j6 s/ N& `: Y3 S
x=[0 1 0 1 2 -1];y=[0 0 1 1 2 -1];z=[-1 1 1 -1 1 1];1 K! p8 A6 [& j( R6 Q( X# B
%其中,(x,y)代表二维的数据点,z 表示相应点的类型属性。
- s( u/ @) q0 l, K* _+ T( Z, s, ]
3 ]& ?/ I; }5 Y- T9 L6 wdata=[1,0;0,1;2,2;-1,-1;0,0;1,1];% (x,y)构成的数据点
4 r4 H( Q) M  L  P8 M8 E: @groups=[1;1;1;1;-1;-1];%各个数据点的标签: u4 s/ v) Z2 K1 l% q, u) r
figure;* l7 r( u( ~  K6 D
subplot(2,2,1);
. a+ H1 |  y- ?: C3 O0 a9 J5 ^Struct1 = svmtrain(data,groups,'Kernel_Function','quadratic', 'showplot',true);%data数据,标签,核函数,训练$ C- e# p& |: l* T, r
classes1=svmclassify(Struct1,data,'showplot',true);%data数据分类,并显示图形" w! V- }) F& S; R; g+ y# o
title('二次核函数');" K. V/ F8 {6 e& z) [* t
CorrectRate1=sum(groups==classes1)/6  ( V. `  s3 d; U2 F3 n
subplot(2,2,2);" A# f) ~; ]+ Z
Struct2 = svmtrain(data,groups,'Kernel_Function','rbf', 'RBF_Sigma',0.41,'showplot',true);( }' ]0 m5 [$ D! ^2 J  K
classes2=svmclassify(Struct2,data,'showplot',true);) I- V/ ^# \9 O$ U- G) f8 [# V
title('高斯径向基核函数(核宽0.41)');: R3 H. x# }# k* K7 _. k' B" Y8 F
CorrectRate2=sum(groups==classes2)/6
& T5 x# P0 r& g# t/ S* wsubplot(2,2,3);3 I5 s# {5 R7 B. f% r5 a3 [
Struct3 = svmtrain(data,groups,'Kernel_Function','polynomial', 'showplot',true);; ?) U4 W4 ^# A# k
classes3=svmclassify(Struct3,data,'showplot',true);
3 z8 ^/ R, O/ x: O: L3 @  _4 G7 atitle('多项式核函数');
) G9 g5 j4 K% H& @; TCorrectRate3=sum(groups==classes3)/6
. u+ G* V" B( Fsubplot(2,2,4);9 \7 B  @8 s5 a" Z
Struct4 = svmtrain(data,groups,'Kernel_Function','mlp', 'showplot',true);
+ u6 Z8 I  C9 f2 Iclasses4=svmclassify(Struct4,data,'showplot',true);( `0 q5 d; Q, |5 o/ L
title('多层感知机核函数');7 |) Q7 C8 ^1 E* e/ [9 Y' K& @# o* n
CorrectRate4=sum(groups==classes4)/6" j+ h: h5 u  N9 X
* c8 l+ z, H3 _# f. }0 \; J4 S

( i7 A  d6 u& ]svmtrain代码分析:
2 }+ ~& d, i7 e( Lif plotflag   %画出训练数据的点
+ }* q3 W6 N" ^6 ~8 M[hAxis,hLines] = svmplotdata(training,groupIndex);) j, ?( A. f0 W9 f# t, l* i8 O
legend(hLines,cellstr(groupString));
, J0 W3 \# y& T8 M* U5 t1 d/ G0 iend
( Q, }' s# t% K$ b
6 G; M" L+ a% Q% t0 H& z6 K! zscaleData = [];
3 b, R* m& q. n' fif autoScale   %训练数据标准化
$ J# r8 F  |5 @# G0 m; Q( T2 {scaleData.shift = - mean(training);' X' p- H& s. l1 c4 m8 D
stdVals = std(training);
- J* a* c- f0 G' y7 SscaleData.scaleFactor = 1./stdVals;& `, N0 ?3 g5 U5 y
% leave zero-variance data unscaled:- T% h- |6 e1 P& L$ R, u1 I
scaleData.scaleFactor(~isfinite(scaleData.scaleFactor)) = 1;
6 Q( [: |) c0 w, o( x" K
" H6 d1 h' E/ q. @7 _% shift and scale columns of data matrix:( H3 ^: j5 b" Q
for c = 1:size(training, 2)- P' V( j: ?# o) N5 ^' P6 b
training(:,c) = scaleData.scaleFactor(c) * ...
) w; J2 E8 b; T* [( t  {(training(:,c) + scaleData.shift(c));
$ J' B* A9 J! @. @1 v( |' H) e; u2 rend
1 \9 X( J* y+ {( |# kend
$ W% o1 b0 l  n: |1 r4 ^+ H% o/ g( k& a) K( b" N% b

: I" v. y) z. Kif strcmpi(optimMethod, 'SMO')%选择最优化算法
) S$ q+ J: z1 N  \6 `else % QP and LS both need the kernel matrix:
7 |4 t7 }+ f( b- O# ?%求解出超平面的参数 (w,b):     wX+b
1 J+ F8 X4 e. ?& V6 Z8 r( `  t: x8 a$ V* `. f
3 Z8 `* I4 v1 R7 ], j7 {- a6 `
if plotflag  %画出超平面在二维空间中的投影0 y3 T4 _- G* r9 @0 D% u( z
    hSV = svmplotsvs(hAxis,hLines,groupString,svm_struct);) b: \- q8 e% J* p1 U2 A5 d
    svm_struct.FigureHandles = {hAxis,hLines,hSV};- y/ V; F  h1 ~: M5 E. c& C
end
8 h. z. U. k. p" P2 m
% O6 V2 S) `% ~1 P: b# H4 J1 S: w
% k# E6 u% W/ {* Qsvmplotsvs.m文件
) w/ ?. u: |/ M0 q# o: U
0 ]8 G8 U( M/ o1 GhSV = plot(sv(:,1),sv(:,2),'ko');%从训练数据中选出支持向量,加上圈标记出来
% n% ^& q4 U1 l3 U! P0 J2 ~) _2 Q) [" M# j
lims = axis(hAxis);%获取子图的坐标空间0 r2 w9 }* ?. n& t' m2 K6 l
[X,Y] = meshgrid(linspace(lims(1),lims(2)),linspace(lims(3),lims(4)));%根据x和y的范围,切分成网格,默认100份
- f3 C$ t5 t7 i0 `) z2 c3 e' @Xorig = X; Yorig = Y;! i% X6 U. @" q! D, S8 V

1 \2 h; X. d! N& Q9 s% A% need to scale the mesh    将这些隔点标准化
" g4 o( h$ u7 b2 A/ L6 y/ w9 kif ~isempty(scaleData)3 O0 P0 O  Q, \9 Y$ j: X
    X = scaleData.scaleFactor(1) * (X + scaleData.shift(1));! q) F& A& P0 U. x
    Y = scaleData.scaleFactor(2) * (Y + scaleData.shift(2));
( g7 h. v" j5 cend
- g. B1 f. x( h9 A
$ v9 G! \9 K) \" |# I/ @, h7 m[dummy, Z] = svmdecision([X(: ),Y(: )],svm_struct); %计算这些隔点[标签,离超平面的距离]
/ H  j/ |& O" |0 Q/ @) h- t/ e# icontour(Xorig,Yorig,reshape(Z,size(X)),[0 0],'k');%画出等高线图,这个距离投影到二维空间的等高线: |4 F- p. u% F) o, R: I
2 W* u1 w' [, L7 a* q+ n& g

5 g+ K7 }* r; Q; D) v! ?* O2 xsvmdecision.m文件
  ^# M* F: Z7 ~) t) [9 B' Pfunction [out,f] = svmdecision(Xnew,svm_struct)
0 F3 F; m. H- ?0 o' v%SVMDECISION evaluates the SVM decision function
! s1 @8 \8 u8 i; ?5 }  u0 n4 E. j9 m# z( M2 K3 l# R" ?
%   Copyright 2004-2006 The MathWorks, Inc." W8 K, I# y4 I0 \7 W* {
%   $Revision: 1.1.12.4 $  $Date: 2006/06/16 20:07:18 $- U2 A5 {, Q) C( o
6 ]% ?4 b* w' w- Z* j! Z
sv = svm_struct.SupportVectors;
" b! J% h( k, Y4 ValphaHat = svm_struct.Alpha;
1 D- R0 e- i( J$ J- P8 A7 cbias = svm_struct.Bias;
$ w/ C  U: M; H: y9 @. R- Gkfun = svm_struct.KernelFunction;' E# p2 N$ ^" ^! a
kfunargs = svm_struct.KernelFunctionArgs;
* p2 m' R# u6 K) x
7 o" M; ]4 U! E* ff = (feval(kfun,sv,Xnew,kfunargs{:})'*alphaHat(: )) + bias;%计算出距离8 A( e% K7 `( ?) j, v4 \& i
out = sign(f);%距离转化成标签
) F& r; q0 d: k8 \( W2 M4 ?3 Z% points on the boundary are assigned to class 1
# i9 W2 T' `! y5 I4 u; J/ }out(out==0) = 1;
" V# N. b  _- @- @4 b. M  F" C. s9 t& a" {6 u1 S/ V* c8 @

. B* T9 _$ F; vfunction K = quadratic_kernel(u,v,varargin)%核函数计算
6 t/ @* E! S/ V' {( D( d%QUADRATIC_KERNEL quadratic kernel for SVM functions
4 `. g; q* E+ G. N( v1 c& p7 |9 `1 _4 G' J4 U) T% e( N9 H
% Copyright 2004-2008 The MathWorks, Inc.2 F! D7 Q* K/ S, L; d
9 v2 t0 O/ d' f  R0 A  z% D
dotproduct = (u*v');% {! z. I* C$ D! C! V5 I$ `- M
K = dotproduct.*(1 + dotproduct);$ ?4 a) M) L! q* V6 ^% z

$ l3 h9 E5 u7 i+ R; |7 H5 }; b: [" I7 a. ~# L) ]7 R
维度分析:假设输入的训练数据为m个,维度为d,记作X(m,d);显然w为w(m,1);    wT*x+b
: {7 I2 t7 q$ r3 _: P" A! U  n( q1 v% Z
3 z) u) `1 P; [: v核函数计算:k(x,y)->上公式改写成  wT*@(x)+b
* L: s7 |1 H- z7 K5 g2 r
, {5 e' t( t' g: C( Q. @假设支持的向量跟训练数据保持一致,没有筛选掉一个,则支撑的数据就是归一化后的X,记作:Xst;
3 l& a/ ?2 R5 z7 d: [9 D- W" m
# w3 Y5 P4 k# D" S测试数据为T(n,d);
! d- X1 K1 [  h: Z, S& \* m$ s* \  l1 H: ~; W4 G, ^/ U; b
则核函数计算后为:(m,d)*(n,d)'=m*n;与权重和偏移中以后为: (1,m)*(m*n)=1*n;如果是训练数据作核函数处理,则m*d变成为m*m. Y0 Y1 x6 k' A2 E9 P8 Q4 d/ Z
, n# t  `! }7 r1 l( t% g5 z  m
这n个测试点的距离。
# O- b0 T' X& i! z$ {# j7 ?- h, z
将这些隔点和其对应的超平面距离,画成等高线,得到现有图形。" O6 {& F" @: G& U, h6 ?4 s( A
5 Y" r9 L( f& u) w  t6 |& W) t) N
* S6 n! {. K( I  x
第二批测试数据:) U4 r: S+ Z7 P* \

7 k+ u: l" H- S' @* s: oclc;
) N$ j0 m$ h9 [. d  w5 L; k( s+ iclear;, {6 v4 G9 x+ @3 F! d! a: A- y% Q
close all;0 f8 x5 ?) p# l% ?
%rng(1); % For reproducibility' f8 a! X3 H' ^6 X, M. R5 [
r = sqrt(rand(100,1)); % Radius 0~1
. L6 g0 `2 \. h, V1 R1 A2 Tt = 2*pi*rand(100,1); % Angle 0~2pi: b7 n# u  T3 r- s( ?3 Y- U' W6 e
data1 = [r.*cos(t), r.*sin(t)]; % Points
% d3 B4 s% x& k  S$ k  l2 W5 L" `6 v2 `: D
r2 = sqrt(3*rand(100,1)+1); % Radius 1~4
7 P$ F# G& n7 W) ^. h: _# |t2 = 2*pi*rand(100,1); % Angle 0~2pi
8 y3 W4 Z$ A% y& `  P4 odata2 = [r2.*cos(t2), r2.*sin(t2)]; % points  G4 ^$ n/ z1 N( s) x

- @% A5 f7 i8 v% W$ E9 Efigure;, G2 {; l2 g1 h7 A0 |
plot(data1(:,1),data1(:,2),'r.','MarkerSize',15)
6 L* L; L& `6 H$ n* o; Y/ l, vhold on
8 l6 j# L& Z- r) c0 H2 ^. xplot(data2(:,1),data2(:,2),'b.','MarkerSize',15)
+ e+ j  e! q) q/ A4 [, U' k  Sezpolar(@(x)1);ezpolar(@(x)2);* E/ n) W6 P' Z& b( a+ r2 s" {
axis equal. }1 i6 h5 C! w; S9 C" l$ }
hold off
" b; s5 @' g3 n. u) v# Z0 o; t: a
' ]& ^( F- x  l: V) ]* v, n%Put the data in one matrix, and make a vector of classifications.
3 a. V* Z" ~1 F+ O, wdata3 = [data1;data2];%标签 +1 -1/ J$ D4 i) x2 A& a
theclass = ones(200,1);
: Y$ T& l  s2 @; Jtheclass(1:100) = -1;# N* i# A( U7 p

( w) i9 f) Y! L7 h; B# i/ g  N6 M- ?# j; Q! j, C
% r^2(r的平方) KMatrix = exp(-gamma*r2);
. i# T5 C& P! y. {, qfunction KMatrix = getKRBF(X, Y, gamma)%rbf核函数
9 ]' ^: a4 E  Lr2 =  repmat( sum(X.^2,2), 1, size(Y,1) ) ...
6 b+ t' w' Y# S    + repmat( sum(Y.^2,2), 1, size(X,1) )'- 2*X*Y'
6 P4 K# k3 ^. G& C%K(x,y)     m*n
2 k' }1 f" e, @6 O) s%sum(X.^2,2)   m*d  ->   m*1  ->   repmat ->  m*n8 g: d. U7 k5 ?( s7 P
%              n*d  ->   n*1  ->   n*m    ->  m*n  z+ I2 b! a2 R) ~3 r# `0 `
%m*n
; j# Q) j0 _' k/ D& N0 {7 p6 g; D- C, i* P+ @, }' m
% XVec表示X向量。||XVec||表示向量长度。 r表示两点距离。r^2表示r的平方。 ) F: m! g- _3 {' Z
% k(XVec,YVec) = exp(-1/(2*sigma^2)*(r^2)) = exp(-gamma*r^2)        * d: A: ]$ o+ b) W
% 公式-1 这里, gamma=1/(2*sigma^2)是参数, r=||XVec-YVec|| 实际上,可看作是计算2个点X与Y的相似性。: p) v2 E. ^6 j3 [, a( |. {
7 g8 o! G( e" B1 B, ^/ a

( e) p5 Y# g" _' |) `由之前对核函数的定义(见统计学习方法定义7.6): 4 B4 N2 m( S) ]
设χ是输入空间(欧氏空间或离散集合),Η为特征空间(希尔伯特空间),如果存在一个从χ到Η的映射
$ [/ [& r' t6 L2 N: a. Y" S* @
* \4 Y" l% L0 w" v1 t. }( kφ(x): χ→Η; r6 A* ]8 q$ |7 X: U
使得对所有的x,z∈χ,函数Κ(x,z)=φ(x)∙φ(z), 1 R! e5 C6 [. b% \" d: q6 {% M
则称Κ(x,z)为核函数,φ(x)为映射函数,φ(x)∙φ(z)为x,z映射到特征空间上的内积。
+ @0 B6 h+ M  {5 S! ~由于映射函数十分复杂难以计算,在实际中,通常都是使用核函数来求解内积,计算复杂度并没有增加,映射函数仅仅作为一种逻辑映射,表征着输入空间到特征空间的映射关系。例如:
- Q9 v6 P4 J9 b  w* H1 H/ e设输入空间χ: ,
$ d+ i$ {% Q8 [, N4 L; K0 b1 V$ s/ F4 w( C
0 G2 D, T0 z' `0 l0 `7 w
映射函数φ(x)= < X,X > = 0 \$ `6 X( e1 t2 q, V$ ]
核函数Κ(x,z)= + d) t& k! V" X* \, r/ R3 w/ q
那么,取两个样例x=(1,2,3),z=(4,5,6)分别通过映射函数和核函数计算内积过程如下: 0 E# X3 w6 d( Q, g+ r5 ^
φ(x)=(1,2,3,2,4,6,3,6,9)
$ M0 x; R: x9 t* f1 o7 S0 Y% f! iφ(z)=(16,20,24,20,25,30,24,30,36)
6 j9 R& N; A  ~3 z" {7 lφ(x)∙φ(z)=16+40+72+40+100+180+72+180+324=1024
" E/ e0 n: q9 i7 L% i9 f2 _( ~而直接通过Κ(x,z)计算得[(4+10+18)]^2=1024
9 K1 D$ I# Z, ^+ O- x6 I: }  i$ h两者相比,核函数的计算量显然要比映射函数小太多了。
, T6 Y7 V& N; D# t0 [1 T+ F
2 J- E6 V6 @" ]) Y, B7 w4 x/ p# w
3 [! u! j, R2 {/ C& i. A6 a8 i! d- o0 j' c

作者: NNNei256    时间: 2020-4-30 13:59
SVM matlab 代码详解说明




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2