1. 程式人生 > >matlab實現SVM演算法進行分類

matlab實現SVM演算法進行分類

1.實驗內容

(1)掌握支援向量機(SVM)的原理,核函式型別選擇以及核引數選擇原則等,並用malab的SVM函式求解各類分類問題例項。

(2)熟悉基於libsvm二分類的一般流程與方法,並對"bedroom,forest"兩組資料進行分類(二分類),最後對試驗分類的準確率進行分析。

2.實驗過程

(1)線性分類

>> sp = [3,7;6,4;4,6;7.5,6.5]

sp =

    3.0000    7.0000
    6.0000    4.0000
    4.0000    6.0000
    7.5000    6.5000

>> nsp = size(sp)

nsp =

     4     2

>> sn = [1,3;5,2;7,3;3,4;6,1]

sn =

     1     3
     5     2
     7     3
     3     4
     6     1

>> nsn = size(sn)

nsn =

     5     2

>> sd = [sp;sn]

sd =

    3.0000    7.0000
    6.0000    4.0000
    4.0000    6.0000
    7.5000    6.5000
    1.0000    3.0000
    5.0000    2.0000
    7.0000    3.0000
    3.0000    4.0000
    6.0000    1.0000

>> lsd = [true true true true false false false false false]

lsd =

  1×9 logical 陣列

   1   1   1   1   0   0   0   0   0

>> Y = nominal(lsd)

Y = 

  1×9 nominal 陣列

     true      true      true      true      false      false      false      false      false 

>> figure(1);
>> subplot(1,2,1)
>> plot(sp(1:nsp,1),sp(1:nsp,2),'m+');
>> hold on
>> plot(sn(1:nsn,1),sn(1:nsn,2),'c*');
>> subplot(1,2,2)
>> svmStruct = svmtrain(sd,Y,'showplot',true);
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
>> 

 線性分類結果:

線性分類結果圖

(2)非線性分類

  >> sp = [3,7;6,6;4,6;5,6.5]

sp =

    3.0000    7.0000
    6.0000    6.0000
    4.0000    6.0000
    5.0000    6.5000

>> nsp = size(sp);
>> sn = [1,2;3,5;7,3;3,4;6,2.7;4,3;2,7];
>> nsn = size(sn)

nsn =

     7     2

>> sd = [sp;sn]

sd =

    3.0000    7.0000
    6.0000    6.0000
    4.0000    6.0000
    5.0000    6.5000
    1.0000    2.0000
    3.0000    5.0000
    7.0000    3.0000
    3.0000    4.0000
    6.0000    2.7000
    4.0000    3.0000
    2.0000    7.0000

>> lsd = [true true true true false false false false false false false]

lsd =

  1×11 logical 陣列

   1   1   1   1   0   0   0   0   0   0   0

>> Y = nominal(lsd)

Y = 

  1×11 nominal 陣列

     true      true      true      true      false      false      false      false      false      false      false 

>> figure(1);
>> subplot(1,2,1)
>> plot(sp(1:nsp,1),sp(1:nsp,2),'m+');
>> hold on
>> plot(sn(1:nsn,1),sn(1:nsn,2),'c*');
>> subplot(1,2,2)
>> svmStruct = svmtrain(sd,Y,'kernel_Function','quadratic','showplot',true);
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
>> %use the trained svm (svmStruct) to classify the data
>> RD = svmclassify(svmStruct,sd,'showplot',true)
警告: svmclassify will be removed in a future release. Use the predict method of an object returned by fitcsvm instead. 
> In svmclassify (line 47) 

RD = 

  11×1 nominal 陣列

     true 
     true 
     true 
     true 
     false 
     false 
     false 
     false 
     false 
     false 
     false 

>> % RD is the classification result vector

非線性分類結果

非線性分類結果圖 

(3)高斯分類

 >> sp = [5,4.5;3,7;6,6;4,6;5,6.5]%positive sample points

sp =

    5.0000    4.5000
    3.0000    7.0000
    6.0000    6.0000
    4.0000    6.0000
    5.0000    6.5000

>> nsp = size(sp);
>> sn = [1,2;3,5;7,3;3,4;6,2.7;4,3;2,7]

sn =

    1.0000    2.0000
    3.0000    5.0000
    7.0000    3.0000
    3.0000    4.0000
    6.0000    2.7000
    4.0000    3.0000
    2.0000    7.0000

>> nsn = size(sn)

nsn =

     7     2

>> sd = [sp,sn]
錯誤使用 horzcat
串聯的矩陣的維度不一致。
 
>> sd = [sp;sn]

sd =

    5.0000    4.5000
    3.0000    7.0000
    6.0000    6.0000
    4.0000    6.0000
    5.0000    6.5000
    1.0000    2.0000
    3.0000    5.0000
    7.0000    3.0000
    3.0000    4.0000
    6.0000    2.7000
    4.0000    3.0000
    2.0000    7.0000

>> lsd = [true true true true true false  false  false  false  false  false  false]

lsd =

  1×12 logical 陣列

   1   1   1   1   1   0   0   0   0   0   0   0

>> Y = nominal(lsd)

Y = 

  1×12 nominal 陣列

     true      true      true      true      true      false      false      false      false      false      false      false 

>> figure(1);
>> subplot(1,2,1)
>> plot(sp(1:nsp,1),sp(1:nsp,2),'m+');
>> hold on
>> plot(sn(1:nsn,1),sn(1:nsn,2),'c*');
>> subplot(1,2,2)
>> svmStruct = svmtrain(sd,Y,'Kernel_Function','rbf','rbf_sigma',0.6,'method','SMO','showplot',true);
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
>> % use the trained svm (svmStruct) to classify the data
>> RD = svmclassify(svmStruct,sd,'showplot',true)
警告: svmclassify will be removed in a future release. Use the predict method
of an object returned by fitcsvm instead. 
> In svmclassify (line 47) 

RD = 

  12×1 nominal 陣列

     true 
     true 
     true 
     true 
     true 
     false 
     false 
     false 
     false 
     false 
     false 
     false 

>> %RD is the classification result vector

高斯分類結果圖

高斯分類結果圖 

(4)對兩組圖片資料進行分類

 >> load('bedroom.mat')
>> load('forest.mat')
>> load('labelset.mat')
>> dataset = [bedroom;MITforest];
>> save dataset.mat dataset
>> %選定訓練集和測試集,將第一類的1-5,第二類的11-15作為訓練集
>> train_set = [dataset(1:5,:);dataset(11:15,:)];
>> %相應的訓練集的標籤也要分離出來
>> train_set_labels = [lableset(1:5);lableset(11:15)];
>> %將第一類的6-10,,第二類的16-20作為測試集
>> test_set = [dataset(6:10,:);dataset(16:20,:)];
>> %相應的測試集的標籤也要分離出來
>> test_set_labels = [lableset(6:10);lableset(16:20)];
>> %資料預處理,將訓練集和測試集歸一化到[0,1]區間
>> [mtrain,ntrain] = size(train_set);
>> [mtest,ntest] = size(test_set);
>> test_dataset = [train_set;test_set];
>> %mapminmax 為matlab自帶的歸一化函式
>> [dataset_scale,ps] = mapminmax (test_dataset,0,1);
>> dataset_scale = dataset_scale;
>> train_set = dataset_scale(1:mtrain,:);
>> test_set = dataset_scale((mtrain+1):(mtrain+mtest),:);
>> %SVM網路訓練
>> model = svmtrain(train_set_labels,train_set,'-s 2-c 1 -g 0.07');
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
錯誤使用 svmtrain (line 236)
Y must be a vector or a character array.
 
>> %svm網路訓練
>> [predict_label] = svmpredict(test_set_labels,test_set,model);
未定義函式或變數 'model'。
 
>> model = svmtrain(train_set_labels,train_set,'-s 2-c 1 -g 0.07');
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
錯誤使用 svmtrain (line 236)
Y must be a vector or a character array.
 
>> model = svmtrain(train_set_labels,train_set,'-s 2 -c 1 -g 0.07');
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
錯誤使用 svmtrain (line 236)
Y must be a vector or a character array.
 
>> [dataset_scale,ps] = mapminmax(test_dataset',0,1);
>> dataset_scale = dataset_scale';
>> train_set = dataset_scale(1:mtrain,:);
>> test_set = dataset_scale((mtrain+1):(mtrain+mtest),:);
>> %svm網路訓練
>> model = svmtrain(train_set_labels,train_set, '-s 2 -c 1 -g 0.07');
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
錯誤使用 svmtrain (line 236)
Y must be a vector or a character array.
 
>> model = fitcsvm(train_set_labels,train_set, '-s 2 -c 1 -g 0.07');
錯誤使用 internal.stats.parseArgs (line 42)
Wrong number of arguments.

出錯 classreg.learning.paramoptim.parseOptimizationArgs (line 5)
[OptimizeHyperparameters,~,~,RemainingArgs] = internal.stats.parseArgs(...

出錯 fitcsvm (line 302)
[IsOptimizing, RemainingArgs] =
classreg.learning.paramoptim.parseOptimizationArgs(varargin);
 
>> model = fitcsvm(train_set_labels,train_set, '-s 2 -c 1 -g 0.07');
錯誤使用 internal.stats.parseArgs (line 42)
Wrong number of arguments.

出錯 classreg.learning.paramoptim.parseOptimizationArgs (line 5)
[OptimizeHyperparameters,~,~,RemainingArgs] = internal.stats.parseArgs(...

出錯 fitcsvm (line 302)
[IsOptimizing, RemainingArgs] =
classreg.learning.paramoptim.parseOptimizationArgs(varargin);
 
>> model = svmtrain(train_set_labels,train_set, '-s 2 -c 1 -g 0.07');
*
optimization finished, #iter = 3
obj = 9.208867, rho = 3.781010
nSV = 6, nBSV = 4
>> [predict_label] = svmpredict(test_set_labels,test_set,model);
Accuracy = 30% (3/10) (classification)
>> %結果
>> figure;
>> hold on;
>> plot(test_set_labels,'o');
>> plot(predict_labels,'r*');
未定義函式或變數 'predict_labels'。
 
是不是想輸入:
>> plot(predict_label,'r*');
>> xlabel('測試集樣本‘,’FontSize‘,12);
 xlabel('測試集樣本‘,’FontSize‘,12);
        ↑
錯誤: 字元向量未正常終止。
 
>> xlabel ('測試集樣本','FontSize',12);
>> ylabel ('類別標籤','FontSize',12);
>> legend('實際測試集分類','預測測試集分類');
>> title('測試集的實際分類和預測分類圖','FontSize',12);
>> grid on;
>> 

**出現問題**
> model = svmtrain(train_set_labels,train_set, '-s 2 -c 1 -g 0.07');
警告: svmtrain will be removed in a future release. Use fitcsvm instead. 
> In svmtrain (line 230) 
錯誤使用 svmtrain (line 236)
Y must be a vector or a character array.

出現問題 > model = svmtrain(train_set_labels,train_set, '-s 2 -c 1 -g 0.07'); 警告: svmtrain will be removed in a future release. Use fitcsvm instead.  > In svmtrain (line 230)  錯誤使用 svmtrain (line 236) Y must be a vector or a character array.

解決辦法 出現這個問題是因為libsvm的路徑不對。解決辦法是,將資料載入到matlab的工作區,然後將檔案路徑指到libsvm的路徑即可。我這裡是C:\Program Files\MATLAB\R2017b\toolbox\libsvm-3.23

分類準確率只有30%

圖片資料分類結果圖

圖片資料分類結果圖