支持向量機(SVM)算法的matlab的實現

支持向量機(SVM)的matlab的實現

支持向量機是一種分類算法之中的一個,matlab中也有對應的函數來對其進行求解;如下貼一個小例子。這個例子來源於咱們實際的項目。html

clc;
clear;
N=10;
%如下的數據是咱們實際項目中的訓練例子(例子中有8個屬性)
correctData=[0,0.2,0.8,0,0,0,2,2];
errorData_ReversePharse=[1,0.8,0.2,1,0,0,2,2];
errorData_CountLoss=[0.2,0.4,0.6,0.2,0,0,1,1];
errorData_X=[0.5,0.5,0.5,1,1,0,0,0];
errorData_Lower=[0.2,0,1,0.2,0,0,0,0];
errorData_Local_X=[0.2,0.2,0.8,0.4,0.4,0,0,0];
errorData_Z=[0.53,0.55,0.45,1,0,1,0,0];
errorData_High=[0.8,1,0,0.8,0,0,0,0];
errorData_CountBefore=[0.4,0.2,0.8,0.4,0,0,2,2];
errorData_Local_X1=[0.3,0.3,0.7,0.4,0.2,0,1,0];
 sampleData=[correctData;errorData_ReversePharse;errorData_CountLoss;errorData_X;errorData_Lower;errorData_Local_X;errorData_Z;errorData_High;errorData_CountBefore;errorData_Local_X1];%訓練例子

type1=1;%正確的波形的類別,即咱們的第一組波形是正確的波形,類別號用 1 表示
type2=-ones(1,N-2);%不對的波形的類別,即第2~10組波形都是有故障的波形。類別號用-1表示
groups=[type1 ,type2]';%訓練所需的類別號
j=1;
%因爲沒有測試數據,所以我將錯誤的波形數據輪流從訓練例子中取出做爲測試例子
for i=2:10
   tempData=sampleData;
   tempData(i,:)=[];
    svmStruct = svmtrain(tempData,groups);
    species(j) = svmclassify(svmStruct,sampleData(i,:));
    j=j+1;
end
species

輸出結果例如如下:算法

-1 -1 -1 -1 -1 -1 -1 1 -1

從結果可以看出:僅僅有第九個被誤判。其餘的都是正確的。數組

上面僅僅是用於說明matlab中支持向量機中函數的使用方法,因爲在訓練集中我僅僅用了一個正確的波形和九組有故障的波形做爲訓練集,所以這樣的超平面的選取可能很差。但是,在咱們的實際的項目中,咱們是用到了不少的訓練集的。ruby

上面是調用matlab中的函數實現多維屬性中的支持向量機對其進行分類。markdown

如下是本身實現此功能,不調用matlab中的支持向量機的函數。代碼例如如下:svn

%主函數
clear all;
clc;
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]);
xlabel('x軸');
ylabel('y軸');
hold on;

X = [x1,x2];        %訓練樣本d*n矩陣。n爲樣本個數,d爲特徵向量個數。在這裏。X爲一個2*100的數組
Y = [y1,y2];        %訓練目標1*n矩陣,n爲樣本個數,值爲+1或-1。在這裏,Y爲一個1*100的數組
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';%LargeScale指大規模搜索。off表示在規模搜索模式關閉
options.Display = 'off';%這樣設置意味着沒有輸出

n = length(Y);%數組Y的長度
H = (Y'*Y).*kernel(X,X,kertype);%調用kernel函數。

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;                     
sv_label = find(abs(a)>epsilon);  %0<a<a(max)則以爲x爲支持向量 
svm.a = a(sv_label);
svm.Xsv = X(:,sv_label);
svm.Ysv = Y(sv_label);
svm.svnum = length(sv_label);
%svm.label = sv_label;

核函數例如如下:ui

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);%sum(a,2)代碼中參數2的意思是將a矩陣a中的按「行」爲單位進行求和
    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

測試函數例如如下spa

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);

要說明的是。上面的代碼是實現的關於咱們樣本僅僅有2個屬性的狀況。當咱們的樣本用多個屬性時,咱們需要改動部分代碼就能夠。code

參考資料:http://blog.sina.com.cn/s/blog_631a4cc40101df0f.html

相關文章
相關標籤/搜索