在Matlab中用SVM编写成本函数的正确方法 - 无法理解'成本'矩阵

时间:2018-06-08 19:27:59

标签: matlab machine-learning deep-learning classification svm

我想将SVM应用于不平衡的数据集,而answer1answer2建议可以通过调整fitcsvm函数的参数来实现。虽然,SVM可能不是不平衡数据的好选择,但我希望看到结果用于教育目的。

如何调整SVM中的参数,以便对真正的类(标记为1)的错误分类错误给予更大的惩罚,因为我的数据自然是不平衡的,1&#39的数量较少; s与0(假)相反。只有2%被标记为1

  • 数据集有1473个样本(98%)标记为0,27个样本(2%)标记为1

  • 训练数据有1000个样本标记为0和 12个样本为1

  • 测试数据有473个样本(97%)为0,15个样本(3%)为1。我使用成本矩阵1c施加了两次惩罚:
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。 请帮忙。

2 个答案:

答案 0 :(得分:1)

这可以使用一些测试数据显示,例如:

#Variant_1: 0.5s 5.78d for 1e6 groups of points
#Variant_2: 0.3s 3.25d for 1e6 groups of points
#Variant_3: 0.22s 2.54d for 1e6 groups of points

由于类不平衡,具有高斯核函数的简单SVM将无法正常工作:

rng(42)
X = randn(1000, 2);
y = rand(1000, 1) >= 0.98;
X(y==1, :) = X(y==1, :) + [2, 2];

正如您已经认识到的那样,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比类0更有可能发生,因此我们应该将类1(大多数)中的样本分类为类0(少数群体),以及将类1(少数群体)中的样本归类为类1(大多数)的高罚款。因此0应该很低,Cost(0, 1)应该很高。

通过设置Cost(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 中使用相同的权重,但切换cCost(0, 1),则会产生预期效果:

Cost(1, 0)

这确实改善了我们的结果:总的来说,我们有相似数量的错误分类:15个而不是16个错误分类,但我们的19个少数类样本中有12个在新模型中是正确的,而之前只有5个。

答案 1 :(得分:0)

根据您的结果,似乎这两个类属于同一个发行版。尝试对训练数据进行过采样(使用可用的阳性样本生成更多阳性样本)并在其上构建模型,然后在测试中测试模型。