libSVM中SVM的数据不平衡问题

7
当我使用一个由75%'true'标签和25%'false'标签组成的不平衡数据集时,该如何设置libSVM中的gamma和Cost参数? 由于数据不平衡,我得到了所有预测标签都设为“True”的常数错误。

如果问题不在于libSVM,而是在于我的数据集,从理论机器学习的角度来看,我应该如何处理这种不平衡?*我使用的特征数量在4-10之间,数据点数量很少,只有250个。


2
FAQ页面中有一个类似的问题,可能会有所帮助:问:我的数据不平衡。libsvm能处理这样的问题吗? http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f410 - mckelvin
3个回答

6
类别不平衡与C和gamma的选择无关,为了解决这个问题,应该使用类别加权方案,例如在 scikit-learn 包(建立在libsvm上)中有提供。
使用网格搜索和交叉验证来选择最佳的Cgamma值。你应该尝试广泛的数值范围,对于C,选择1到10^15之间的值是合理的,而gamma的简单而好的启发式方法是计算所有数据点之间的成对距离,并根据此分布的百分位数选择gamma值。想象一下,在每个点中放置方差等于1/gamma的高斯分布——如果您选择了这样的gamma,那么这个分布将会与许多点重叠,从而得到非常“平滑”的模型,而使用小方差则会导致过拟合。

1
类别加权方案意味着在实际的SVM训练问题中会改变C,因此即使它发生在幕后,类别平衡仍然与C的选择有关。 - Marc Claesen
1
这只是语言上的问题,因为我的意图是选择C不会解决不平衡问题。然而,解决这个问题的方案会改变C,我并没有看到真正的矛盾。 - lejlot

6
不平衡的数据集可以用各种方式来解决。类别平衡对于RBF核心参数(如gamma)等没有影响。最流行的两种方法是:
1. 为每个类使用不同的错误分类惩罚,这基本上意味着改变C。通常是给较小的类分配更高的权重,一种常见的方法是npos * wpos = nneg * wneg。LIBSVM允许您使用其-wX标志来执行此操作。
2. 对过度表示的类别进行子采样,以获得相同数量的正面和负面,并像处理平衡集时一样进行训练。请注意,通过这种方式基本上忽略了大量数据,这在直观上是一个坏主意。

2
为什么不对较小的进行过采样呢?这样就不会忽略任何信息。 - lejlot
1
@lejlot,大多数使用后一种策略的情况都是大规模问题(例如数百万到数十亿个实例),在这些问题中,忽略部分数据实际上被用作降低复杂性的一种方法。过采样较小的集合基本上是前一种方法的低效方式(过采样与重新加权完全相同)。 - Marc Claesen
1
我完全明白,只是想知道为什么您没有包括这个选项。过采样的主要优点是它是一种通用方法,即使在不允许您加权样本的模型(及其实现)中也可以使用(以效率为代价)。 - lejlot
2
我认为不过度采样少数类的主要原因是,除非你非常小心地控制这个过程,否则它会使交叉验证或留存测试无用,因为重复的示例可能会出现在多个折叠中。虽然我想你可以先提取一个留存集,然后再对训练集进行过度采样。 - Desty

3

我知道这个问题已经被问过一段时间了,但我想回答一下,因为你可能会发现我的答案有用。

正如其他人提到的,你可能希望考虑为少数类使用不同权重或使用不同的误分类惩罚。然而,处理不平衡数据集的更聪明的方法是使用SMOTESynthetic Minority Over-sampling Technique)算法生成合成的少数类数据。这是一种可以很好地处理一些不平衡数据集的简单算法。

在算法的每次迭代中,SMOTE考虑两个随机的少数类实例,并在它们之间添加一个同类别的人造实例。该算法不断注入样本,直到两个类别平衡或达到其他某些标准(例如添加一定数量的实例)。下面你可以找到一个描述SMOTE算法在2D特征空间的简单数据集上所做的事情的图片。

将权重与少数类相关联是该算法的一种特殊情况。当你将权重$w_i$与实例i相关联时,实际上是在实例i之上添加额外的$w_i-1$个实例!

SMOTE

  • 你需要做的是用该算法创建的样本增强你的初始数据集,并使用这个新的数据集训练SVM。你还可以在不同的编程语言中找到许多实现,例如Python和Matlab。

  • 还有其他扩展这个算法的方式,如果你需要我可以指向更多材料。

  • 要测试分类器,你需要将数据集分成测试集和训练集,在训练集中添加合成实例(请勿将其添加到测试集中),在训练集上训练模型,最后在测试集上进行测试。如果在测试时考虑生成的实例,你将得到一个偏斜的(和明显更高的)准确率和召回率。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接