天天看點

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

1.軟體版本

MATLAB2013b

2.本算法理論知識

聚類:

首先計算整個資料集合的平均值點,作為第一個初始聚類中心C1;然後分别計算所有對象到C1的歐式距離d,并且計算每個對象在半徑R的範圍内包含的對象個數W。此時計算P=u*d+(1-u)*W,所得到的最大的P值所對應的的對象作為第二個初始聚類中心C2。同樣的方法,分别計算所有對象到C2的歐式距離d,并且計算每個對象在半徑R的範圍内包含的對象個數W,所得到的最大的P值所對應的的對象作為第二個初始聚類中心C3。

從這三個初始聚類中心開始聚類劃分。對于一個待分類的對象,計算它到現有聚類中心的距離,若(這個距離)<(現有各個聚類中心距離的最小值),則将這個待分類對象分到與它相距最近的那一類;如果(這個距離)>(現有各個聚類中心距離的最小值),則這個待分類對象就自成一類,成為一個新的聚類中心,然後對所有對象重新歸類。

如果找到新的聚類中心,在重新計算聚類的中心後。對目前形成的K+1 個聚類計算 DBInew 的值,和未重新配置設定對象到這 k+1 個類之前計算的 DBIold進行比較,如果 DBInew <DBIold,則這個新找到的聚類中心可以作為新的聚類中心,否則将終止本次查找 k 的工作,并恢複到 DBIold 的狀态。當所有這樣符合新類産生條件的資料對象的 DBI 值都大于 DBIold 時,則确定再沒有新的類産生,則确定了最終聚類個數為 k,可以進行最終的配置設定對象工作。

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真
【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

SVM

特征提取:提取對檢測最有用、最利于檢測出攻擊的那些參數。所用到的特征提取方案是利用“資訊增益”,選出各特征參數中資訊增益(Information Gain)最大的那些特征在檢測時使用,這個做之前應該需要對資料先标準化和歸一化一下。具體操作:

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

究竟選多少個特征可以讓檢測的精度最高呢?我論文裡是先将各個特征的資訊增益從高到低排序,然後依次往下取K個,用K-means算法對節點進行分類達到檢測的作用,計算當檢測率最高的時候所對應 K值,即意為選多少個特征。

經過特征提取後,之後所說的樣本,他們的屬性都隻由特征提取後的那些特征來代表了。

SVM訓練樣本篩選:假定有正常和攻擊兩類樣本,将兩類樣本分别用K-means聚類,将這些聚類中心點作為新的樣本點。然後在正常類中,計算每個新樣本點在異常類中距離自己最近的M(假定M=3)個樣本點,進而在異常類中假設找到P個樣本點。異常類中的這P個樣本點找到在正常類中距離自己最近的M個樣本點,假定找到了Q個樣本點。此時,這P+Q個樣本點就是新選出的SVM訓練樣本。

3.部分源碼

clc;
clear;
close all;
warning off;
pack;
addpath 'jl\'
addpath 'svm\'

RandStream.setDefaultStream(RandStream('mt19937ar','seed',1));

%步驟1:調用資料
%步驟1:調用資料
load ..\Step1_Net_Attack\mesh_attack.mat
%選擇資料
Attack_Dat = attack(:,1:end-1)/max(max(attack));
T          = attack(:,end);

%步驟2:聚類
%步驟2:聚類
%C1;
alpha = 1;
u     = 0.5;
%首先計算整個資料集合的平均值點,作為第一個初始聚類中心C1
[r,c] = size(Attack_Dat);
for j = 1:c
    C1(1,j) = mean(Attack_Dat(:,j));     
end

%C2
d1 = func_dis(Attack_Dat,C1);
R1 = alpha*mean(d1);
W1 = 0;
for i = 1:length(d1)
    if d1(i) <= R1
       W1 = W1 + 1;
    end
end
u1= u;
P1= u1*d1 + (1-u1)*W1;
[V1,I1] = max(P1);
C2 = Attack_Dat(I1,:); 

%C3
d2 = func_dis(Attack_Dat,C2);
R2 = alpha*mean(d2);
W2 = 0;
for i = 1:length(d2)
    if d2(i) <= R2
       W2 = W2 + 1;
    end
end
u2= u;
P2= u2*d2 + (1-u2)*W2;
[V2,I2] = max(P2);
C3 = Attack_Dat(I2,:); 
d3 = func_dis(Attack_Dat,C3);
R3 = alpha*mean(d3);

is_continue = 1;
C           = [C1;C2;C3];
R           = [R1;R2;R3];
Leg         = ones(length(Attack_Dat),1);
K           = 3;
CNT         = 0;
while(is_continue == 1)
    CNT = 0;
    for i = 1:length(Attack_Dat)
        for j = 1:size(C,1)
            d(i,j) = func_dis(Attack_Dat(i,:),C(j,:));
        end
        [VV,II] = min(d(i,:));
        if VV <= min(R)
            Leg(i) = II;
            CNT = CNT + 1;
        else
            K = K + 1;
            Leg(i) = K;
            C = [C;Attack_Dat(i,:)];
            R = [R;alpha*mean(func_dis(Attack_Dat,Attack_Dat(i,:)))];
        end
    end 
    
    if CNT == length(Attack_Dat)
       is_continue = 0;
    else
       is_continue = 1; 
    end
end

Tmps = unique(Leg);
if min(Tmps) > 1
   Leg = Leg - (min(Tmps)-1);
end
Leg = sort(Leg);
Leg = Leg-1;
%檢測率
Right1 = 100*(length(find(Leg == T))/length(Attack_Dat))
%誤判率
Error1 = 100*(1-length(find(Leg == T))/length(Attack_Dat))

%對比算法K-means  
%對比算法K-means    
KK         = length(unique(Leg));
opts       = statset('Display','final');
X          = Attack_Dat;
[idx,ctrs] = kmeans(X,KK,'Distance','city','Replicates',10,'Options',opts);
idx        = sort(idx);
%檢測率
Right2 = 100*(length(find(idx == T))/length(X))
%誤判率
Error2 = 100*(1-length(find(idx == T))/length(X))


attack1 = [Attack_Dat(:,:),Leg];

%步驟3:SVM
%步驟3:SVM
%特征選取時,選取的特征數量所對應的的檢測率的仿真圖
POS = attack1(1:length(Attack_Dat)/2,:);
NEG = attack1(length(Attack_Dat)/2+1:end,:);
%将資料随機産生訓練集合和測試集合
INDD= (1:length(POS));


Attack_Dat_train = [POS(INDD(1:round(2/3*length(POS))),1:end-1);NEG(INDD(1:round(2/3*length(POS))),1:end-1)];
T_train          = [POS(INDD(1:round(2/3*length(POS))),end)    ;NEG(INDD(1:round(2/3*length(POS))),end)];

Attack_Dat_test = [POS(INDD(round(2/3*length(POS)))+1:end,1:end-1);NEG(INDD(round(2/3*length(POS)))+1:end,1:end-1)];
T_test          = [POS(INDD(round(2/3*length(POS)))+1:end,end)    ;NEG(INDD(round(2/3*length(POS)))+1:end,end)];


%訓練集合
POS_train = Attack_Dat_train(find(T_train==1),:);
NEG_train = Attack_Dat_train(find(T_train==2),:);
%測試集合
POS_test = Attack_Dat_test(find(T_test==1),:);
NEG_test = Attack_Dat_test(find(T_test==2),:);


%随機選擇K個樣本進行分類,并計算對應的檢測率
K     = 60;
KK    = 2;
Alpha = 0.7;
Indes = 0;

Index = 0;
Indes = Indes + 1;

tic
Index = Index + 1;

IND        = randperm(length(POS_train));
POS_train2 = POS_train(IND(1:K),:);
NEG_train2 = NEG_train(IND(1:K),:);
%Kmeans
opts       = statset('Display','final');
X          = [POS_train2;NEG_train2];
[idx,ctrs] = kmeans(X,KK,'Distance','city','Replicates',10,'Options',opts);
%準備SVM訓練分類——SVM訓練樣本的選擇
Q          = round(Alpha*size(POS_train2,1));
if Q == 0
   Q = 1;
end
P          = round(Alpha*size(NEG_train2,1));
if P == 0
   P = 1;
end    

%正樣本
d_pos      = func_dis2(POS_train2,ctrs(1,:));
%選擇距離最近的M個
[Vpos,Ipos]= sort(d_pos);
POS_train_final = POS_train2(Ipos(1:Q),:);
%負樣本
d_neg      = func_dis2(NEG_train2,ctrs(2,:));
%選擇距離最近的N個
[Vneg,Ineg]= sort(d_neg);
NEG_train_final = NEG_train2(Ipos(1:P),:);

%SVM訓練
options = optimset('maxiter',10000);
Ps      = [POS_train_final;NEG_train_final];
Ts      = [ones(size(POS_train_final),1);2*ones(size(NEG_train_final),1)];
SvmNet  = svmtrain(Ps,Ts,'Kernel_Function','linear','Polyorder',2,'quadprog_opts',options);  

%SVM測試
Test_Dat = [POS_test;NEG_test];
Classify = svmclassify(SvmNet,Test_Dat);

%計算檢測率
times(Index) = toc;
Right(Index) = length(find(Classify==T_test))/length(T_test);
clc;

timess(:,Indes) = times;
Rights(:,Indes) = Right;


disp('仿真時間:')
timess
disp('檢測率:')
100*Rights

      

4.仿真分析

1.特征選取時,選取的特征數量所對應的的檢測率的仿真圖

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

 從上面的仿真圖可知,當選擇的樣本數量越多的時候,檢測率精度越高。

在選擇樣本個數大于50的時候,檢測率趨于穩定。

2.樣本篩選前後,數量多少的對比圖

這裡,我們對比篩選不同格式下,檢測的對比效果。

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

 3.經過樣本篩選和特征選取後SVM的檢測準确度和不經過上述操作的SVM的檢測準确度的對比仿真圖

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

 4.經過樣本篩選和特征選取後SVM的誤判率和不經過上述操作的SVM的誤判率的對比仿真圖

【SVM分類】基于kmeans聚類+SVM的資料分類MATLAB仿真

5.參考文獻

繼續閱讀