matlab實現SVM演算法進行分類
阿新 • • 發佈:2018-12-11
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%
圖片資料分類結果圖