转自:http://blog.csdn.net/a1154761720/article/details/50708398,感谢原作者的分享!
背景:通常一类问题出现在需要对训练样本进行一定比例的筛选,或者已知的训练样本都是正样本,而负样本却很少的情况。
这种情况下,往往需要训练一个对于训练样本紧凑的分类边界,就可以通过负样本实验。一个简单的实际例子是:一个工厂对于产品的合格性进行检查时,往往所知道是合格产品的参数,而不合格的产品的参数要么空间比较大,要么知道的很少。这种情况下就可以通过已知的合格产品参数来训练一个一类分类器,得到一个紧凑的分类边界,超出这个边界就认为是不合格产品。形式化的说明知乎上有个很好的例子:http://www.zhihu.com/question/22365729
原理:
它求解的模型如下所示:
其中的参数V特别注意,它的值在0-1之间,是一个比例值,它的含义是:你的训练样本中最后被分类为负样本的比例。比如你有100个训练样本,V设为0.1,去学一个one class SVM,然后在学到的SVM上测试你之前用的训练集,最后可以看到有10个左右的样本的标签为-1,被分为负样本。下面还会通过实验进行说明。模型的求解等其他理论细节请参考大牛Bernhard Scholkopf的文章:Support Vector Method for Novelty Detection
http://papers.nips.cc/paper/1723-support-vector-method-for-novelty-detection.pdf
实验:
libsvm中有关于one class SVM的实现,算法就是根据上面Bernhard Scholkopf的文章。可以用下面代码进行测试:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
通过上面的代码可以构造一个在圆内的训练样本,如下图所有:
这样我们就假设所有圆外的样本为负样本,下面我们就进行one-class SVM训练,可以看到有个参数-n,它就是我们上面提到的V,也就是这些训练样本中包含负样本的比例。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
上面的代码可以得到下面的结果:
其中预测为正的用绿色表示,预测为负的用红色表示。
为了说明参数V的作用,将-n设为0.3后可以得到如下结果:
(黑线圆圈里是我们的训练样本的点)
上面是对负样本的检测效果验证,当一个新样本在圆内时,我们还是希望分类器可以将新样本分为正样本,下面就通过一段代码验证了这个效果:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
上面的代码得到的效果如下图:
可以看到这些新样本的标签都分对了(n设为0.01的情况),另外,由于新样本(x1,y1)满足x1+y1=1所以显示在一条直线上。