liblinear 的 50% 准确率问题

Posted

技术标签:

【中文标题】liblinear 的 50% 准确率问题【英文标题】:50% percent accuracy issue with liblinear 【发布时间】:2014-01-05 05:47:53 【问题描述】:

我是 Liblinear/Libsvm 的新手,我在这里遇到了一个很好的问题。

我有非常大的训练数据(2.883.584 个高度不平衡的样本,每个样本都是 21 维)和用于测试的大数据(262.144 个样本也有 21 维)。我正在使用 LIBSVM(或 LibLinear)的线性内核实现,因为我的数据具有大数据性质。文献警告我使用 RBF 内核处理这些数据的问题。

我的问题是:无论我做什么,分类器只预测一个类(样本较多的类,或者我实验中的负类)。

到目前为止我试过了:

1- 训练平衡和不平衡数据,不缩放数据,不选择参数。

2- 训练平衡和不平衡数据,用不同的范围([-1,1] 和 [0,1])缩放数据,但不选择参数。

3- 训练平衡和不平衡数据,通过参数选择缩放具有不同范围([-1,1] 和 [0,1])的数据。

所有这些实验的准确率都达到了 81%,但这些正确的预测都来自否定类。所有的正类都被线性支持向量机误分类了。

.model 文件非常奇怪,如下所示:

solver_type L2R_L2LOSS_SVC_DUAL
nr_class 2
label 1 -1
nr_feature 21
bias -1
w
0 
0 
nan 
nan 
0 
0 
0 
0 
0 
nan 
nan 
0 
0 
0 
0 
0 
nan 
nan 
0 
0 
0 

当我通过网格搜索进行参数选择时,最好的 C 总是给我 5 倍交叉验证的最佳准确率 50%。这就是我在 Matlab 中进行网格搜索的方式:

for log2c = 1:100,
    cmd = ['-v 5 -c ', num2str(2^log2c)];
    cv = train(label, inst, cmd);
    if (cv >= bestcv),
        bestcv = cv; bestc = 2^log2c; 
    end
    fprintf('%g %g (best c=%g, rate=%g)\n', log2c, cv, bestc, bestcv);
end

编辑:这是我的训练数据的正负样本:

 1  1:4.896000e+01 2:3.374349e+01 3:2.519652e-01 4:1.289031e+00 5:48 6:4.021792e-01 7:136 8:4.069388e+01 9:2.669129e+01 10:-3.017949e-02 11:3.096163e+00 12:36 13:3.322866e-01 14:136 15:4.003704e+01 16:2.168262e+01 17:1.101631e+00 18:3.496498e+00 19:36 20:2.285381e-01 21:136 
-1  1:5.040000e+01 2:3.251025e+01 3:2.260981e-01 4:2.523418e+00 5:48 6:4.021792e-01 7:136 8:4.122449e+01 9:2.680350e+01 10:5.681589e-01 11:3.273471e+00 12:36 13:3.322866e-01 14:136 15:4.027160e+01 16:2.245051e+01 17:6.281671e-01 18:2.977574e+00 19:36 20:2.285381e-01 21:136 

这是我的测试数据的一个正面和负面样本:

 1  1:71 2:2.562365e+01 3:3.154359e-01 4:1.728250e+00 5:76 6:0 7:121 8:7.067857e+01 9:3.185273e+01 10:-8.272995e-01 11:2.193058e+00 12:74 13:0 14:121 15:6.675556e+01 16:3.624485e+01 17:-1.863971e-01 18:1.382679e+00 19:76 20:3.533593e-01 21:128 
-1  1:5.606667e+01 2:2.480630e+01 3:1.291811e-01 4:1.477127e+00 5:65 6:0 7:76 8:5.610714e+01 9:3.602092e+01 10:-9.018124e-01 11:2.236301e+00 12:67 13:4.912373e-01 14:128 15:5.886667e+01 16:3.891050e+01 17:-5.167622e-01 18:1.527146e+00 19:69 20:3.533593e-01 21:128 

我的数据有问题吗?我应该增加网格搜索中的 C 范围吗?还是应该使用其他分类器?

【问题讨论】:

你有没有尝试过其他模型(可能是其他内核,RBF)以确保不是格式化数据的问题? @Ray:看看我的编辑,我在其中显示了一些数据。我认为它们是 Libsvm/Liblinear 格式,或者不是?无论如何,我会尝试您与其他内核相关的建议。感谢您的回复。 我不确定,因为我不太熟悉 libsvm。对我来说很好看。 :) 您的数据集中的某些特征的值比其他特征大一个数量级(即 #20 与 #21),这会给您带来一些数值上的麻烦,您是否尝试过规范化您的数据?不平衡数据本身也是一个问题,我建议您尝试解决数据的一小部分平衡子集,然后当您有一个稳定的模型时,从那里添加整个数据集 @mad 好吧,您发布的数据没有缩放,所以我假设您在执行 svm-scale 后没有发布数据。您可以发布它以便我们为您提供更好的见解吗?正如您已经猜到的那样,从您发布的模型中可以得出结论,该算法没有学习,看起来是因为您的数据集中存在数值问题。 【参考方案1】:

对于不平衡的情况,假阳性和假阴性错误的代价是不一样的,所以正负类的惩罚应该是不同的。您可能需要为每个班级选择权重 C+ 和 C-。如果你的消极模式多于积极模式,那么你可能想让 C+ 大于 C-

model = svmtrain(trainLabels, trainFeatures, '-h 0 -b 1 -s 0 -t 0 -c 10 -w1 C+ -w-1 C-');

通常C+ * N+ = C- * N-,其中N+和N-分别是正类和负类的样本数。

还要确保选择正确的options。对于您的训练样本数远大于特征数的情况,线性内核是您在帖子中所说的最佳选择。

【讨论】:

我不同意最后一点。如果输入空间的维度很小,数据集很大 谢谢你。在这种情况下,逻辑回归可能会更好。如果特征较小(10^0 - 10^3)而数据集中等(10^1 - 10^4),则非线性核可能最适合。

以上是关于liblinear 的 50% 准确率问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥 LibSvm 准确率不超过 50%?

训练期间接近 100% 的准确率,但在图像分类器的测试/验证期间 <50%

MKMapItem.openInMaps() 50% 的时间准确地显示地点标记

简单分析实现运维利器---webssh终端libl

图神经网络让预估到达准确率提升50%,谷歌地图实现新突破

自动写代码指日可待!Facebook迁移学习新突破,代码补全准确率超50%!