SVM多分类
SVM實現多分類的方案
SVM本身是一個二值分類器
SVM算法最初是為二值分類問題設計的,當處理多類問題時,就需要構造合適的多類分類器。
目前,構造SVM多類分類器的方法主要有兩類
(1)直接法,直接在目標函數上進行修改,將多個分類面的參數求解合并到一個最優化問題中,通過求解該最優化問題“一次性”實現多類分類。這種方法看似簡單,但其計算復雜度比較高,實現起來比較困難,只適合用于小型問題中;
(2)間接法,主要是通過組合多個二分類器來實現多分類器的構造,常見的方法有one-against-one和one-against-all兩種。
一對多法(one-versus-rest,簡稱OVR SVMs)
訓練時依次把某個類別的樣本歸為一類,其他剩余的樣本歸為另一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類為具有最大分類函數值的那類。
假如我有四類要劃分(也就是4個Label),他們是A、B、C、D。
于是我在抽取訓練集的時候,分別抽取
(1)A所對應的向量作為正集,B,C,D所對應的向量作為負集;
(2)B所對應的向量作為正集,A,C,D所對應的向量作為負集;
(3)C所對應的向量作為正集,A,B,D所對應的向量作為負集;
(4)D所對應的向量作為正集,A,B,C所對應的向量作為負集;
使用這四個訓練集分別進行訓練,然后的得到四個訓練結果文件。
在測試的時候,把對應的測試向量分別利用這四個訓練結果文件進行測試。
最后每個測試都有一個結果f1(x),f2(x),f3(x),f4(x)。
于是最終的結果便是這四個值中最大的一個作為分類結果。
評價:
這種方法有種缺陷,因為訓練集是1:M,這種情況下存在biased.因而不是很實用。可以在抽取數據集的時候,從完整的負集中再抽取三分之一作為訓練負集。
一對一法(one-versus-one,簡稱OVO SVMs或者pairwise)
其做法是在任意兩類樣本之間設計一個SVM,因此k個類別的樣本就需要設計k(k-1)/2個SVM。
當對一個未知樣本進行分類時,最后得票最多的類別即為該未知樣本的類別。
Libsvm中的多類分類就是根據這個方法實現的。
假設有四類A,B,C,D四類。在訓練的時候我選擇A,B; A,C; A,D; B,C; B,D;C,D所對應的向量作為訓練集,然后得到六個訓練結果,在測試的時候,把對應的向量分別對六個結果進行測試,然后采取投票形式,最后得到一組結果。
投票是這樣的:
A=B=C=D=0;
(A,B)-classifier 如果是A win,則A=A+1;otherwise,B=B+1;
(A,C)-classifier 如果是A win,則A=A+1;otherwise, C=C+1;
...
(C,D)-classifier 如果是A win,則C=C+1;otherwise,D=D+1;
The decision is the Max(A,B,C,D)
評價:這種方法雖然好,但是當類別很多的時候,model的個數是n*(n-1)/2,代價還是相當大的。
用libsvm在matlab中實現多分類(訓練函數svmtrain+預測函數svmpredict)?
對于libsvm中訓練模型的函數svmtrain來說,model = svmtrain(訓練數據類別, 訓練數據, ‘一系列參數’);其中參數的形式如‘-c 2 -g 0.02’在這當中,參數主要包括以下幾個方面:
(1) -s —— 其表示SVM的類型,包括上面提到的(默認值為0):?
0 —— C-SVC?
1—— v-SVC?
2 —— 一類SVM?
3 —— e -SVR?
4 —— v-SVR?
(2)-t—— 其表示核函數類型(默認值為2)?
0 – 線性:u’v?
1 – 多項式:(r*u’v + coef0)^degree?
2 – RBF函數:exp(-gamma|u-v|^2)?
3 –sigmoid:tanh(r*u’v + coef0)?
(3)核函數參數設置?
-d ——核函數中的degree設置(針對多項式核函數)(默認3)?
-g ——核函數中的gamma函數設置(針對多項式/rbf/sigmoid 核函數)(默認1/ k,k為特征值個數)?
-r ——核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0)?
-c ——設置C-SVC,e -SVR和v-SVR的參數(損失函數)(默認1)?
-n——設置nu-SVC,一類SVM和nu- SVR的參數(默認0.5)?
-p ——設置e -SVR 中損失函數p的值(默認0.1)?
-m ——設置cache內存大小,以MB為單位(默認40)?
-e ——設置允許的終止判據(默認0.001)?
-h ——是否使用啟發式,0或1(默認1)?
-b ——是否訓練一個SVC或者SVR模型,0或1(默認0)?
-wi ——設置第i類的參數C為weight*C(C-SVC中的C)(默認1)?
-v——n-fold交互檢驗模式,n為fold的個數,必須大于等于2(訓練中使用了-v參數進行交叉驗證時,返回的不是一個模型,而是交叉驗證的分類的正確率或者回歸的均方根誤差)
使用函數svmtrain訓練分類模型后,會返回一個結構體,其中包括數據:?
(1) parameters(一個5*1的數組)?
第一個元素:-s,SVM的類型(int默認為0)?
第二個元素:-t,核函數類型(默認為2)?
第三個元素:-d,核函數中的degree設置(針對多項式核函數)(默認3);?
第四個元素:-g,核函數中的r(gamma)函數設置(針對多項式/rbf/sigmoid核函數) (默認為類別數目的倒數);?
第五個元素:-r 核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0)?
(2)-nr_class: 表示數據集中有多少個類(int)?
(3)-totalSV: 表示支持向量的總數。(int)?
(4)-rho: 決策函數wx+b中的常數偏置的相反數(-b)。?
(5)-Label: 表示數據集中類別的標簽?
(6)ProbA: 使用-b參數時用于概率估計的數值,否則為空。?
ProbB: 使用-b參數時用于概率估計的數值,否則為空。?
(7)-nSV: 表示每類樣本的支持向量的數目,和Label的類別標簽對應。?
(8)-sv_coef: 表示每個支持向量在決策函數中的系數。?
(9)-SVs: 表示所有的支持向量,如果特征是n維的,支持向量一共有m個,則為m x n的稀疏矩陣。?
(10)nu: -n參數的顯示?
(11)iter: 迭代次數?
(12)obj: 表示SVM文件轉換的二次規劃求解的最小值
svmpredict函數根據測試數據類屬性,測試數據,以及通過svmtrain函數獲得的模型來進行分類預測并計算分類精度,[predict_label, accuracy, dec_values]=svmpredict(測試數據類屬性,測試數據,分類模型),返回值介紹如下:
(1)predicted_label:存儲著分類后樣本所對應的類屬性。?
(2)accuracy:一個3 * 1的數組,依次為:分類的正確率、回歸的均方根誤差、回歸的平方相關系數。?
(3)decision_values/prob_estimates:是一個表示概率的數組,對于一個m個數據,n個類的情況,如果指定“-b 1”參數(使用,則n x k的矩陣,每一行表示這個樣本分別屬于每一個類別的概率;如果沒有指定“-b 1”參數,則為n * n×(n-1)/2的矩陣,每一行表示n(n-1)/2個二分類SVM的預測結果。
使用libsvm進行分類的步驟?
(1) 對數據做歸一化(simple scaling)?
對數據進行簡單的縮放處理(scaling),縮放的最主要優點是能夠避免大數值區間的屬性過分支配了小數值區間的屬性。另一個優點能避免計算過程中數值復雜度。(在試驗中發現,歸一化過程,分別對訓練數據和測試數據進行歸一化處理,比對訓練數據和測試數據整體進行歸一化處理獲得的分類精度要高)
(2) 應用 RBF kernel?
(3) 選擇得到最優的c和g?
c是懲罰因子,是一個在訓練模型前需要自己設置的一個數值,它表示我們對類中的離群數據的重視程度,c的數值越大,表明我們越重視,越不想丟掉這些離群的數據;g是核函數中的gamma函數設置(針對多項式/rbf/sigmoid 核函數)(默認1/ k,k為特征值個數) 。c和g的選擇對分類精度影響很大,在本文的試驗中,用函數SVMcgForClass選擇完成c和g的選擇。
(4) 用得到的最優c和g訓練分類模型?
使用libsvm中的svmtrain函數來訓練多分類模型?
(5)測試?
使用libsvm中的svmpredict函數來測試分類精度
總結
- 上一篇: PHP 发送Email的几种方法
- 下一篇: java建一个conversion_Sc