3.1 原始數據分析
1)測試數據為:wine data set,儲存在chapter_WineClass.mat。classnumer = 3;wine,記錄了178個樣本的13個屬性;wine_labels.178×1,記錄了178個樣本的各自類別標簽。
2)數據的可視化:13個指標的屬性值即數據的箱式圖;數據的分維可視化圖。
% 畫出測試數據的分維可視化圖
figure
subplot(3,5,1);
hold on
for run = 1:178
plot(run,wine_labels(run),'*');
end
xlabel('樣本','FontSize',10);
ylabel('類別標簽','FontSize',10);
title('class','FontSize',10);
for run = 2:14
subplot(3,5,run);
hold on;
str = ['attrib ',num2str(run-1)];
for i = 1:178
plot(i,wine(i,run-1),'*');
end
xlabel('樣本','FontSize',10);
ylabel('屬性值','FontSize',10);
title(str,'FontSize',10);
end


3.2 模型建立及其實現
3.2.1 模型建立
首先從原始數據中把訓練集和測試集提取出來,然后進行預處理,之后用訓練集對SVM進行訓練,最后用得到的模型來預測測試集的分類標簽,算法流程如圖:
選定訓練集和測試集 → 數據預處理 → 訓練SVM → 分類准確率 → 預測(測試集)
3.2.2 MATLAB 實現
1) 選定測試集和訓練集
該數據一共有三類,現將每個類別分為兩組,重新組合數據,一部分為訓練集(train_wine),一部分為測試集(test_wine)。
% 選定訓練集和測試集 % 將第一類的1-30,第二類的60-95,第三類的131-153做為訓練集 train_wine = [wine(1:30,:);wine(60:95,:);wine(131:153,:)]; % 相應的訓練集的標簽也要分離出來 train_wine_labels = [wine_labels(1:30);wine_labels(60:95);wine_labels(131:153)]; % 將第一類的31-59,第二類的96-130,第三類的154-178做為測試集 test_wine = [wine(31:59,:);wine(96:130,:);wine(154:178,:)]; % 相應的測試集的標簽也要分離出來 test_wine_labels = [wine_labels(31:59);wine_labels(96:130);wine_labels(154:178)];
2) 數據預處理——歸一化
[0,1]區間歸一化:y=(x-xmin)/(xmax-xmin);
[-1,1]區間歸一化:2*(x-xmin)/(xmax-xmin)-1;
mapminmax 函數實現:y=(ymax-ymin)×(x-xmin)/(xmax-xmin)+ymin,其中ymin和ymax是映射范圍參數,可調節,默認值是-1和1。函數接口如下:
[y,ps] = mapminmax(x)
[y,ps] = mapminmax(x,ymin,ymax)
[x,ps] = mapminmax('reverse',y,ps) %反歸一化
新的映射函數對x進行重新歸一化方法:
[y,ps] = mapminmax(x); ps.ymin = 0; ps.ymax = 1; [ynew,ps] = mapminmax(x,ps);
wine 數據的歸一化實現:
%% 數據預處理 % 數據預處理,將訓練集和測試集歸一化到[0,1]區間 [mtrain,ntrain] = size(train_wine); [mtest,ntest] = size(test_wine); dataset = [train_wine;test_wine]; % mapminmax為MATLAB自帶的歸一化函數 [dataset_scale,ps] = mapminmax(dataset',0,1); dataset_scale = dataset_scale'; train_wine = dataset_scale(1:mtrain,:); test_wine = dataset_scale( (mtrain+1):(mtrain+mtest),: );
3) 分類及預測
%% SVM網絡訓練
model = svmtrain(train_wine_labels, train_wine, '-c 2 -g 1');
%% SVM網絡預測
[predict_label, accuracy,dec_values] = svmpredict(test_wine_labels, test_wine, model);
%% 結果分析
% 測試集的實際分類和預測分類圖
% 通過圖可以看出只有一個測試樣本是被錯分的
figure;
hold on;
plot(test_wine_labels,'o');
plot(predict_label,'r*');
xlabel('測試集樣本','FontSize',12);
ylabel('類別標簽','FontSize',12);
legend('實際測試集分類','預測測試集分類');
title('測試集的實際分類和預測分類圖','FontSize',12);
grid on;

3.3 案例擴展——歸一化方式及核函數對准確了的影響
1)采用不同歸一化方式的對比
a.不進行歸一化處理
Accuracy = 39.3258% (35/89) (classification)
b.[-1,1]歸一化
[dataset_scale,ps] = mapminmax(dataset',-1,1); Accuracy = 97.7528% (87/89) (classification)
c.[0,1]歸一化
[dataset_scale,ps] = mapminmax(dataset',0,1); Accuracy = 98.8764% (88/89) (classification)
不同的歸一化對最后的准確率會有一定的影響。並不是任何問題都必須事先把原始數據進行歸一化,要具體問題具體看待,測試表明有時候歸一化后的測試准確率比沒有歸一化的准確率會低很多。
2) 采用不同核函數的對比
a.linear
'-c 2 -g 1 -t 0'
Accuracy = 97.7528% (87/89) (classification)
b.polynomial
'-c 2 -g 1 -t 1'
Accuracy = 98.8764% (88/89) (classification)
c.radial basis function
'-c 2 -g 1 -t 2'
Accuracy = 98.8764% (88/89) (classification)
d.sigmoid
'-c 2 -g 1 -t 3'
Accuracy = 52.809% (47/89) (classification)
如何通過選取 c 和 g 的值提升分類器的性能?下個隨筆將會具體介紹。
