OCSVM: A toy example for beginner

目录

1. 概要

2. 导入需要的包

3. 构造数据

4. 训练和预测

5. Summary


1. 概要

        OCSVM(One-Class SVM), 很多人翻译成一类SVM,不过我觉得单类SVM可能更好一些。那什么是OC-SVM呢,与经典的SVM的有什么区别?。。。。。。--别问,问就是现在我也不知道也说不清楚,留作homework^-^(敬请等待后文,如果我没有走上从入门到放弃的路的话)。

        本文只是想介绍一个第一天接触OCSVM的小白的自创(就是各处抄了一些东西凑齐了而且还看上去运行起来了)的一个toy-example。看到这里你可以确定你是不是还要看下去了(判断依据是你是不是一个同等level的小白^-^)。

        经典的分类问题是将待识别对象分为两类或者多类,识别结果要么为这一类,要么为那一类。但是,在有些问题场景中,只需要确定待检测样本是否属于已知的某一特定分类,针对某个观测样本,其判断结果为是或者否。一个中文网络世界提及OCSVM的解释所经常给出的例子是:假设这样一个特殊的场景,比方说,有一个小和尚,他从小在寺庙长大,从来都只见过男生,没见过女生。那么对于一个男性,他能很快地基于这个男性与他之前接触的男性有类似的特征,给出这个人是男性的答案。但如果是一个女性,他会发现,这个女性与他之前所认知的男性的特征差异很大,进而会得出这个“新物种”不是男性的判断。但注意这里的“不是男性”并不意味着小和尚做出了这个“新物种”是女性的判断,他只是判断这个“新物种”跟他日常世界所接触过的人不是一类人,他甚至不一定有“男性”“女性”这个概念。写到这里,我也可以举一个“原创”的例子,就是(在对应于大航海时代以后的若干个世纪)一个与世隔绝的原始部落的人,突然有一天碰到一个入侵的金发碧眼的西欧强盗的时候,他没有什么外国人这个概念,甚至也没有物种的概念,但是他隐隐约约知道这个眼前的生物非我族类非我同种。。。

        好了,概念就只说这么多(事实上只能扯得出这么多了),下面介绍本小白基于scikit-learnOneClassSVM所构建的一个toy-example。本渣觉得跟概念和论文硬刚太费劲,最适合于小白入门学习的方法就是手撕代码从例子中学习。先学会调包调参,然后再自己写核心函数 ,然后。。。看造化了。

        以下代码是在Jupyter notebook中调试运行的,所以感兴趣的伙伴们可以把代码copy到Jupyter notebook中去运行。如果是作为普通的python脚本运行的话,可能需要一些修改。

        这个例子的思路是这样的:训练集是一组全部落在单位院内的二维数据,而测试集为x和y坐标均落在[-1,1]和[-1,1]的矩形内的随机数据。用训练集对svm.OneLcassSVM进行训练后,训练的目标是希望能够分辨出待测数据是否落在单位圆内。

2. 导入需要的包

        导入scikit-learn中的svm.OneLcassSVM以及其它一些需要的包。

import numpy as np
import random
import sys
from sklearn.svm import OneClassSVM
import matplotlib.pyplot as plt
%matplotlib inline  

3. 构造数据

         实验数据生成如下(借鉴自[2]

         isInUnitCircle()是一个helper function,用于实验数据构造中判断二维数据是否在单位圆内。

def isInUnitCircle(x,y):
    '''
    Judge whether (x,y) is within the range of unit circle
    '''    
    if x**2 + y**2 > 1:
        return False
    return True
n_train = 1000
n_test  = 100
X = np.zeros((n_train,2))
Y = np.zeros((n_test,2))
for i in range(n_train):
    x1 = random.uniform(-1.,1.)
    x2 = random.uniform(-1.,1.)
    if isInUnitCircle(x1,x2):
        X[i,:] = [x1,x2]
        
for i in range(100):
    y1 = random.uniform(-1.,1.)
    y2 = random.uniform(-1.,1.)
    Y[i,:] = [y1,y2]

        X是训练数据,全部落在单位圆内。Y是测试数据,一部分落在单位圆内,一部分落在单位圆外。以下看看数据长得啥样。

fig, ax = plt.subplots(1,2,figsize = (12,6))
ax[0].scatter(X[:,0],X[:,1])
ax[1].scatter(Y[:,0],Y[:,1])
ax[0].set_title('Train set')
ax[1].set_title('Test set')
fig.suptitle('Left: train set; Right: test set')

4. 训练和预测

clf = OneClassSVM(gamma=0.01, nu=0.01).fit(X)
X_pred = clf.predict(X)
Y_pred = clf.predict(Y)

        因为是调包嘛,所以就这么简单。只不过参数还是需要设置一下。完全使用缺省参数的话在本例中是不行的,有兴趣伙伴可以试一试将gamma和nu的设定去掉看看是什么效果。至于参数应该如何选取。。。呃。。。尴尬了,以后再商量^-^.

        先看看训练集本身的预测准确度(Accuracy)如何。

X_accuracy = np.sum(X_pred[X_pred > 0])/len(X_pred)
print('X_accuracy = {0:6.3f}'.format(X_accuracy))

        输出结果:X_accuracy = 0.991

        接下来,看看测试集的预测准确度(Accuracy)如何。

Y_pred_gt = 2 * ((Y[:,0]**2 + Y[:,1]**2) < 1) - 1
Y_diff = Y_pred_gt * Y_pred
Y_accuracy = np.sum(Y_diff[Y_diff > 0])/len(Y_diff)
print('Y_accuracy = {0:6.3f}'.format(Y_accuracy))

        输出结果:Y_accuracy = 0.980  

5. Summary

        一个最简单的例子,能运行而且基本上还预测正确说明对OneLcassSVM的调用方法的理解大致没错。可以继续前进了。。。

        在以上训练中,训练数据全部是处于单位圆内的。经过训练,分类器模型也的确搞明白了把单位圆内作为正常区域,在此之外的区域当作是异常数据。在对测试数据的判别中有98%的准确率,还是觉得挺神奇的。因为并没有给标签啊,分类器是怎么学习到要区分单位圆内和单位圆外的呢?仅仅是因为训练数据全部位于单位圆内这样一个规则的区域?

        欲知后事如何,且听下回分解。OCSVM: A toy example for beginner (2)https://blog.csdn.net/chenxy_bwave/article/details/120566251icon-default.png?t=L892https://blog.csdn.net/chenxy_bwave/article/details/120566251

[Reference]

[1] 什么是一类支持向量机(one class SVM),是指分两类的支持向量机吗? - 知乎

[2] 采用LibSVM实现One-Class SVM - 知乎

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨牛慢耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值