1

我在用 Matlab 中的 RBF 内核训练 SVM 时遇到了一个奇怪的问题。问题是,在进行网格搜索时,使用 10 倍交叉验证,对于 C 和 Sigma 值,我总是得到等于大约 0.50 的 AUC 值(在 0.48 和 0.54 之间变化,具体取决于)——我得到了这个from:实际测试集标签[X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1);在哪里,预测标签在哪里。分类器只预测占数据的 90% 以上的多数类。dSet1Label(test)label

经过进一步调查,当查看分数时(从[label,score] = predict(svmStruct, dSet1(test,:));哪里获得svmStruct的模型是在 9/10 的数据上训练的,剩下的 1/10 是从哪里获得dSet1(test,:)的),它们都是相同的:

0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
  .         .
  .         .
  .         .
0.8323   -0.8323

数据由 443 个特征和 6,453 个实例组成,其中 542 个属于正类。[0,1]根据标准 SVM 协议,这些功能已扩展到 0 范围内。类由 表示{-1,1}

我的代码如下:

load('datafile.m');
boxVals = [1,2,5,10,20,50,100,200,500,1000];
rbfVals = [.0001,.01,.1,1,2,3,5,10,20];
[m,n] = size(dataset1);
[c,v] = size(boxVals);
[e,r] = size(rbfVals);
auc_holder = [];
accuracy_holder = [];
for i = 1:v
     curBox = boxVals(i)
     for j = 1:r
         curRBF = rbfVals(j)
         valInd = crossvalind('Kfold', m, 10);
         temp_auc = [];
         temp_acc = [];
         cp = classperf(dSet1Label);
         for k = 1:10
             test = (valInd==k); train = ~test;
             svmStruct = fitcsvm(dSet1(train,:), dSet1Label(train), 'KernelFunction', 'rbf', 'BoxConstraint', curBox, 'KernelScale', curRBF);
             [label,score] = predict(svmStruct, dSet1(test,:));
             accuracy = sum(dSet1Label(test) == label)/numel(dSet1Label(test));
             [X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1);
             temp_auc = [temp_auc AUC];
             temp_acc = [temp_acc accuracy];
         end
         avg_auc = mean(temp_auc);
         avg_acc = mean(temp_acc);
         auc_holder = [auc_holder avg_auc];
         accuracy_holder = [accuracy_holder avg_acc];
     end
end

谢谢!

*编辑1:看来,无论我将框约束设置为什么,所有数据点都被视为支持向量。

4

1 回答 1

1

除非您有一些实现错误(使用合成的、分离良好的数据测试您的代码),否则问题可能在于类不平衡。这可以通过调整错误分类成本来解决(参见 CV 中的讨论)。我会使用cost参数fitcsvm将少数类的错误分类成本提高到比多数类大 9 倍,然后查看问题是否仍然存在。另一个需要考虑的问题是类分层(参见 crossvalind 文档 - 您必须定义一个group参数,以便每个折叠都具有相似的类比例)。

于 2015-06-22T15:01:16.407 回答