[英]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.