转载自:http://blog.csdn.net/yangliuy/article/details/8152390算法
一、问题描述数据结构
作关系抽取就是要从产品评论中抽取出描述产品特征项的target短语以及修饰该target的opinion短语,在opinion mining里面属于很重要的task,不少DM、NLP相关的paper在作这方面的工做。基本的思路是:框架
(1)从sentence的parse tree(好比stanford parser)中选取候选target结点和候选opinion结点,而后对全部的候选target和opinion组合选取features,用SVM进行训练分类。函数
(2)给定种子opinion words,借助parse tree中的path rules,屡次迭代抽取新的target和opinion,称为Double Propagation (Qiu et al, IJCAI'09)测试
(3) 采用Tree kernel 的方法进行关系抽取(Wu et al, EMNLP'09)优化
若是采用第一种思路,在用SVM分类时就会遇到正负样例不均衡的问题。缘由是,即使候选target和opinion抽取的recall和presicion能够达到100%,其不一样的组合中也是负样例居多,正样例比例不多。我作实验时,遇到正负样例的比例为1:9,用SVM分类时,全部测试样例均被分类道来负样例中,这样的问题称为Unbalanced Data分类。this
二、解决办法spa
对不一样类别设置不一样的惩罚因子。要用到LibSVM 的–C及-W选项。详细解释见《LIBSVM: A Library for Support Vector Machines》论文第6部分Unbalanced Data and Solving the Two-variable Sub-problem。C是惩罚因子,能够针对正负样本使用不一样的惩罚值。 能够认为这个惩罚值 是指 对要训练的分类器 发生误判的惩罚程度。.net
好比:对于unbalanced的数据集,假设正样本+1占10%,负样本-1占90%, 正负样本比例为1:9. 按道理来讲,咱们训练svm分类器时,若是将+1样本误判为-1样本,咱们须要加大惩罚力度。结合Libsvm FAQ中所说的例子,“svm-train -s 0 -c 10 -w1 1 -w-15 data_file 。 the penalty for class"-1" is larger. Note that this -w option is for C-SVC only”。
那么要解决关系抽取中unbalance data问题,命令应该是:svm-train -s 0 -c 10 -w1 9-w-1 1 data_file ,至关于采用C-SVC模式,对+1误判惩罚为10*9=90, 对-1误判为10*1=10,这样的设置会让分类器倾向分出更多的正样例来,这样分类结果就再也不是全为-1了。而且,咱们还能够进一步实验不一样惩罚因子设置的状况下分类的准确率和召回率。blog
三、SVM中的松弛变量与惩罚因子
这一部分转自http://blog.csdn.net/qll125596718/article/details/6910921,对松弛变量和惩罚因子的介绍很是通俗易懂。
3.1 松弛变量
如今咱们已经把一个原本线性不可分的文本分类问题,经过映射到高维空间而变成了线性可分的。就像下图这样:
圆形和方形的点各有成千上万个(毕竟,这就是咱们训练集中文档的数量嘛,固然很大了)。如今想象咱们有另外一个训练集,只比原先这个训练集多了一篇文章,映射到高维空间之后(固然,也使用了相同的核函数),也就多了一个样本点,可是这个样本的位置是这样的:
就是图中黄色那个点,它是方形的,于是它是负类的一个样本,这单独的一个样本,使得本来线性可分的问题变成了线性不可分的。这样相似的问题(仅有少数点线性不可分)叫作“近似线性可分”的问题。
以咱们人类的常识来判断,说有一万个点都符合某种规律(于是线性可分),有一个点不符合,那这一个点是否就表明了分类规则中咱们没有考虑到的方面呢(于是规则应该为它而作出修改)?
其实咱们会以为,更有可能的是,这个样本点压根就是错误,是噪声,是提供训练集的同窗人工分类时一打瞌睡错放进去的。因此咱们会简单的忽略这个样本点,仍然使用原来的分类器,其效果丝绝不受影响。
但这种对噪声的容错性是人的思惟带来的,咱们的程序可没有。因为咱们本来的优化问题的表达式中,确实要考虑全部的样本点(不能忽略某一个,由于程序它怎么知道该忽略哪个呢?),在此基础上寻找正负类之间的最大几何间隔,而几何间隔自己表明的是距离,是非负的,像上面这种有噪声的状况会使得整个问题无解。这种解法其实也叫作“硬间隔”分类法,由于他硬性的要求全部样本点都知足和分类平面间的距离必须大于某个值。
所以由上面的例子中也能够看出,硬间隔的分类法其结果容易受少数点的控制,这是很危险的(尽管有句话说真理老是掌握在少数人手中,但那不过是那一小撮人聊以自慰的词句罢了,咱仍是得民主)。
但解决方法也很明显,就是仿照人的思路,容许一些点到分类平面的距离不知足原先的要求。因为不一样的训练集各点的间距尺度不太同样,所以用间隔(而不是几何间隔)来衡量有利于咱们表达形式的简洁。咱们原先对样本点的要求是:
意思是说离分类面最近的样本点函数间隔也要比1大。若是要引入容错性,就给1这个硬性的阈值加一个松弛变量,即容许:
由于松弛变量是非负的,所以最终的结果是要求间隔能够比1小。可是当某些点出现这种间隔比1小的状况时(这些点也叫离群点),意味着咱们放弃了对这些点的精确分类,而这对咱们的分类器来讲是种损失。可是放弃这些点也带来了好处,那就是使分类面没必要向这些点的方向移动,于是能够获得更大的几何间隔(在低维空间看来,分类边界也更平滑)。显然咱们必须权衡这种损失和好处。好处很明显,咱们获得的分类间隔越大,好处就越多。回顾咱们原始的硬间隔分类对应的优化问题:
||w||^2就是咱们的目标函数(固然系数无关紧要),但愿它越小越好,于是损失就必然是一个能使之变大的量(能使它变小就不叫损失了,咱们原本就但愿目标函数值越小越好)。那如何来衡量损失,有两种经常使用的方式,有人喜欢用:
而有人喜欢用:
其中L都是样本的数目。两种方法没有大的区别。若是选择了第一种,获得的方法的就叫作二阶软间隔分类器,第二种就叫作一阶软间隔分类器。把损失加入到目标函数里的时候,就须要一个惩罚因子(cost,也就是libSVM的诸多参数中的C),原来的优化问题就变成了下面这样:
这个式子有这么几点要注意:
(1)并不是全部的样本点都有一个松弛变量与其对应。实际上只有“离群点”才有,或者也能够这么看,全部没离群的点松弛变量都等于0(对负类来讲,离群点就是在前面图中,跑到H2右侧的那些负样本点,对正类来讲,就是跑到H1左侧的那些正样本点)。
(2)松弛变量的值实际上标示出了对应的点到底离群有多远,值越大,点就越远。
(3)惩罚因子C决定了你有多重视离群点带来的损失,显然当全部离群点的松弛变量的和必定时,你定的C越大,对目标函数的损失也越大,此时就暗示着你很是不肯意放弃这些离群点,最极端的状况是你把C定为无限大,这样只要稍有一个点离群,目标函数的值立刻变成无限大,立刻让问题变成无解,这就退化成了硬间隔问题。
(4)惩罚因子C不是一个变量,整个优化问题在解的时候,C是一个你必须事先指定的值,指定这个值之后,解一下,获得一个分类器,而后用测试数据看看结果怎么样,若是不够好,换一个C的值,再解一次优化问题,获得另外一个分类器,再看看效果,如此就是一个参数寻优的过程,但这和优化问题自己决不是一回事,优化问题在解的过程当中,C一直是定值,要记住。
(5)尽管加了松弛变量这么一说,但这个优化问题仍然是一个优化问题(汗,这不废话么),解它的过程比起原始的硬间隔问题来讲,没有任何更加特殊的地方。
从大的方面说优化问题解的过程,就是先试着肯定一下w,也就是肯定了前面图中的三条直线,这时看看间隔有多大,又有多少点离群,把目标函数的值算一算,再换一组三条直线(你能够看到,分类的直线位置若是移动了,有些原来离群的点会变得再也不离群,而有的原本不离群的点会变成离群点),再把目标函数的值算一算,如此往复(迭代),直到最终找到目标函数最小时的w。
啰嗦了这么多,读者必定能够立刻本身总结出来,松弛变量也就是个解决线性不可分问题的方法罢了,可是回想一下,核函数的引入不也是为了解决线性不可分的问题么?为何要为了一个问题使用两种方法呢?
其实二者还有微妙的不一样。通常的过程应该是这样,还以文本分类为例。在原始的低维空间中,样本至关的不可分,不管你怎么找分类平面,总会有大量的离群点,此时用核函数向高维空间映射一下,虽然结果仍然是不可分的,但比原始空间里的要更加接近线性可分的状态(就是达到了近似线性可分的状态),此时再用松弛变量处理那些少数“冥顽不化”的离群点,就简单有效得多啦。
本节中的(式1)也确实是支持向量机最最经常使用的形式。至此一个比较完整的支持向量机框架就有了,简单说来,支持向量机就是使用了核函数的软间隔线性分类法。
3.2 惩罚因子
接下来要说的东西其实不是松弛变量自己,但因为是为了使用松弛变量才引入的,所以放在这里也算合适,那就是惩罚因子C。回头看一眼引入了松弛变量之后的优化问题:
注意其中C的位置,也能够回想一下C所起的做用(表征你有多么重视离群点,C越大越重视,越不想丢掉它们)。这个式子是之前作SVM的人写的,你们也就这么用,但没有任何规定说必须对全部的松弛变量都使用同一个惩罚因子,咱们彻底能够给每个离群点都使用不一样的C,这时就意味着你对每一个样本的重视程度都不同,有些样本丢了也就丢了,错了也就错了,这些就给一个比较小的C;而有些样本很重要,决不能分类错误(好比中央下达的文件啥的,笑),就给一个很大的C。
固然实际使用的时候并无这么极端,但一种很经常使用的变形能够用来解决分类问题中样本的“偏斜”问题。
先来讲说样本的偏斜问题,也叫数据集偏斜(unbalanced),它指的是参与分类的两个类别(也能够指多个类别)样本数量差别很大。好比说正类有10,000个样本,而负类只给了100个,这会引发的问题显而易见,能够看看下面的图:
方形的点是负类。H,H1,H2是根据给的样本算出来的分类面,因为负类的样本不多不多,因此有一些原本是负类的样本点没有提供,好比图中两个灰色的方形点,若是这两个点有提供的话,那算出来的分类面应该是H’,H2’和H1,他们显然和以前的结果有出入,实际上负类给的样本点越多,就越容易出如今灰色点附近的点,咱们算出的结果也就越接近于真实的分类面。但如今因为偏斜的现象存在,使得数量多的正类能够把分类面向负类的方向“推”,于是影响告终果的准确性。
对付数据集偏斜问题的方法之一就是在惩罚因子上做文章,想必你们也猜到了,那就是给样本数量少的负类更大的惩罚因子,表示咱们重视这部分样本(原本数量就少,再抛弃一些,那人家负类还活不活了),所以咱们的目标函数中因松弛变量而损失的部分就变成了:
其中i=1…p都是正样本,j=p+1…p+q都是负样本。libSVM这个算法包在解决偏斜问题的时候用的就是这种方法。
那C+和C-怎么肯定呢?它们的大小是试出来的(参数调优),可是他们的比例能够有些方法来肯定。我们先假定说C+是5这么大,那肯定C-的一个很直观的方法就是使用两类样本数的比来算,对应到刚才举的例子,C-就能够定为500这么大(由于10,000:100=100:1嘛)。
可是这样并不够好,回看刚才的图,你会发现正类之因此能够“欺负”负类,其实并非由于负类样本少,真实的缘由是负类的样本分布的不够广(没扩充到负类本应该有的区域)。说一个具体点的例子,如今想给政治类和体育类的文章作分类,政治类文章不少,而体育类只提供了几篇关于篮球的文章,这时分类会明显偏向于政治类,若是要给体育类文章增长样本,但增长的样本仍然全都是关于篮球的(也就是说,没有足球,排球,赛车,游泳等等),那结果会怎样呢?虽然体育类文章在数量上能够达到与政治类同样多,但过于集中了,结果仍会偏向于政治类!因此给C+和C-肯定比例更好的方法应该是衡量他们分布的程度。好比能够算算他们在空间中占据了多大的体积,例如给负类找一个超球——就是高维空间里的球啦——它能够包含全部负类的样本,再给正类找一个,比比两个球的半径,就能够大体肯定分布的状况。显然半径大的分布就比较广,就给小一点的惩罚因子。
可是这样还不够好,由于有的类别样本确实很集中,这不是提供的样本数量多少的问题,这是类别自己的特征(就是某些话题涉及的面很窄,例如计算机类的文章就明显不如文化类的文章那么“天马行空”),这个时候即使超球的半径差别很大,也不该该赋予两个类别不一样的惩罚因子。
看到这里读者必定疯了,由于说来讲去,这岂不成了一个解决不了的问题?然而事实如此,彻底的方法是没有的,根据须要,选择实现简单又合用的就好(例如libSVM就直接使用样本数量的比)。