Matlab -- SVM -- 所有多数 Class 具有相同分数和 AUC = .50 的预测
Matlab -- SVM -- All Majority Class Predictions with Same Score and AUC = .50
我在 Matlab 中使用 RBF 内核训练 SVM 时遇到了一个奇怪的问题。问题是,在进行网格搜索时,使用 10 折交叉验证,对于 C 和 Sigma 值,我总是得到大约等于 .50 的 AUC 值(在 .48 和 .54 之间变化,具体取决于)——我得到了这个from: [X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1);
其中 dSet1Label(test)
是实际测试集标签,label
是预测标签。 classifier 仅预测大多数 class,占数据的 90% 以上。
经过进一步调查,在查看分数时(从 [label,score] = predict(svmStruct, dSet1(test,:));
获得,其中 svmStruct
是在 9/10 的数据上训练的模型,dSet1(test,:)
是剩余的 1/ 10) 他们都一样:
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 个是阳性 class。根据标准 SVM 协议,这些功能已扩展到 [0,1]
的范围。 classes 由 {-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:看来,无论我将框约束设置为什么,所有数据点都被视为支持向量。
除非您有一些实施错误(使用合成的、分离良好的数据测试您的代码),否则问题可能在于 class 不平衡。这可以通过调整 missclassification cost (See this discussion in CV) 来解决。我会使用 fitcsvm
的 cost
参数来增加少数 class 的未命中 class 化成本,使其比多数 class 大 9 倍,并且查看问题是否仍然存在。另一个需要考虑的问题是 class 分层(请参阅 crossvalind 文档 - 您必须定义一个 group
参数,以便每个折叠都有相似的 class 比例)。
我在 Matlab 中使用 RBF 内核训练 SVM 时遇到了一个奇怪的问题。问题是,在进行网格搜索时,使用 10 折交叉验证,对于 C 和 Sigma 值,我总是得到大约等于 .50 的 AUC 值(在 .48 和 .54 之间变化,具体取决于)——我得到了这个from: [X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1);
其中 dSet1Label(test)
是实际测试集标签,label
是预测标签。 classifier 仅预测大多数 class,占数据的 90% 以上。
经过进一步调查,在查看分数时(从 [label,score] = predict(svmStruct, dSet1(test,:));
获得,其中 svmStruct
是在 9/10 的数据上训练的模型,dSet1(test,:)
是剩余的 1/ 10) 他们都一样:
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 个是阳性 class。根据标准 SVM 协议,这些功能已扩展到 [0,1]
的范围。 classes 由 {-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:看来,无论我将框约束设置为什么,所有数据点都被视为支持向量。
除非您有一些实施错误(使用合成的、分离良好的数据测试您的代码),否则问题可能在于 class 不平衡。这可以通过调整 missclassification cost (See this discussion in CV) 来解决。我会使用 fitcsvm
的 cost
参数来增加少数 class 的未命中 class 化成本,使其比多数 class 大 9 倍,并且查看问题是否仍然存在。另一个需要考虑的问题是 class 分层(请参阅 crossvalind 文档 - 您必须定义一个 group
参数,以便每个折叠都有相似的 class 比例)。