[英]Proper way to write the cost function in SVM in Matlab - unable to understand 'Cost' matrix
我想將SVM應用於不平衡的數據集, answer1 , answer2建議可以通過調整fitcsvm
函數的參數來實現。 盡管SVM可能不是平衡數據的理想選擇,但我還是希望出於教育目的查看結果。
我如何在SVM中調整參數,以對真實類(標記為1
)的錯誤分類錯誤進行更大的懲罰,因為我的數據自然不平衡,與0
(假)相比,其1
的數量更少。 只有2%標記為1
。
該數據集具有1473個樣本(98%)標為0
和27個樣品(2%),為1
。
訓練數據具有標記為0
1000個樣本和標記為1
12個樣本。
0
和15個樣本(占3%)作為1
。 我通過使用成本矩陣c
對1
施加了兩次懲罰: c=[0 2.2;1 0]; model = fitcsvm(train_x,train_y,'KernelFunction', 'rbf', 'Cost',c); [predLabel,score] = predict(model,test_x);
結果是
Precision for label 0: 9.692623e-01
Precision for label 1: NaN
Recall for label 0: 1
Recall for label 1: 0
Accuracy = 96.9%
Average err = 0.03
混淆矩陣為
473 0
15 0
predict
向量中的答案都是1
標簽。 顯然,成本矩陣無法正常工作。 如果我對0(多數階層)或1(少數階層)的錯誤分類進行懲罰,我不太了解成本矩陣。 為什么第一行和第一列元素= 0,而另一個為2。請幫助。
可以使用一些測試數據來顯示,例如:
rng(42)
X = randn(1000, 2);
y = rand(1000, 1) >= 0.98;
X(y==1, :) = X(y==1, :) + [2, 2];
由於類不平衡,具有高斯內核功能的簡單SVM無法正常工作:
model = fitcsvm(X, y, 'KernelFunction', 'rbf')
confusionmat(y, model.predict(X))
ans =
979 2
14 5
正如您已經認識到的那樣, 'Cost'
參數可用於通過對少數族裔類別的錯誤分類施加更高的懲罰來補償不平衡。 在二維情況下,成本矩陣的建立如下:
[ Cost(0, 0), Cost(0, 1)
Cost(1, 0), Cost(1, 1) ]
現在, Cost(0, 0)
是屬於類樣品分類的成本0
作為類0
。 這是正確的分類,因此通常將成本設置為0。接下來, Cost(0, 1)
是將屬於類0
的點分類為類1
的成本,即錯誤的分類。
在您的示例中,與類別1
相比,類別0
更可能發生,因此對於將類別0
(多數)的樣本歸為類別1
(少數),我們應處以較低的罰款,而對類別0
(多數)中的樣本進行分類應給予較高的罰款。 1
類(少數)作為0
類(多數)。 因此Cost(0, 1)
應該低,而Cost(1, 0)
應該高。
通過設置c = [0, 2.2; 1, 0]
c = [0, 2.2; 1, 0]
,您做了相反的工作-建議fitcsvm
函數將少數樣本歸為多數而不是相反:
c = [0, 2.2; 1, 0];
model = fitcsvm(X, y, 'KernelFunction', 'rbf', 'Cost', c);
confusionmat(y, model.predict(X))
ans =
981 0
19 0
如果在成本矩陣c
使用相同的權重,但切換Cost(0, 1)
和Cost(1, 0)
,則將發生所需的效果:
c = [0, 1; 2.2, 0];
model = fitcsvm(X, y, 'KernelFunction', 'rbf', 'Cost', c);
confusionmat(y, model.predict(X))
ans =
973 8
7 12
這確實改善了我們的結果:總的來說,我們有相似數量的錯誤分類:15個錯誤分類,而不是16個錯誤分類,但是在19個少數族裔樣本中,有12個使用新模型是正確的,而以前只有5個。
根據您的結果,似乎兩個類都屬於同一分布。 嘗試對訓練數據進行過度采樣(使用可用的陽性樣本生成更多的陽性樣本)並在此基礎上建立模型,然后在測試中測試模型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.