异常检测算法(二):OneClassSVM【严格讲,不是outlier检测方法,而是novelty检测方法】【但数据维度很高或对相关数据分布没任何假设情况下,也可作为一种很好的outlier检测方法】

异常检测算法(二):OneClassSVM【严格讲,不是outlier检测方法,而是novelty检测方法】【但数据维度很高或对相关数据分布没任何假设情况下,也可作为一种很好的outlier检测方法】,第1张

OneClassSVM两个功能:

  • 无监督异常值检测;
  • 解决非平衡样本分类;

在做非平衡样本分类的问题时,其中如果有一类比例严重失调,就可以直接用这个方式来做:OneClassSVM

OneClassSVM还有一个功能就是异常值检测。

scikit-learn官网:2.7. Novelty and Outlier Detection

严格地讲,OneClassSVM不是一种outlier detection方法,而是一种novelty detection方法:它的训练集不应该掺杂异常点,因为模型可能会去匹配这些异常点。 但在数据维度很高,或者对相关数据分布没有任何假设的情况下,OneClassSVM也可以作为一种很好的outlier detection方法。

在分类问题中,当两类样本及其不平衡时,也可以将个数比例极小的那部分当做异常点来处理,从另外一种角度来完成分类任务!

一、OneClass、二分类、多分类

典型的2类问题:识别邮件是否是垃圾邮件,一类“是”,另一类“不是”

典型的多类问题:人脸识别,每个人对应的脸就是一个类,然后把待识别的脸分到对应的类中去

而OneClassClassification,它只有一个类,属于该类就返回结果“是”,不属于就返回结果“不是”,乍一听感觉与2分类没什么区别,其实他们的思想有很大差异。在2分类问题中,训练集中就由两个类的样本组成,训练出的模型是一个2分类模型;而OneClassClassification中的训练样本只有一类,因此训练出的分类器将不属于该类的所有其他样本判别为“不是”即可,而不是由于属于另一类才返回的“不是”结果。

现实场景中的OneClassClassification例子:现在有一堆某商品的历史销售数据,记录着买该产品的用户信息,此外还有一些没有购买过该产品的用户信息,想通过2分类来预测他们是否会买该产品,也就是弄两个类,一类是“买”,一类是“不买”。当我们要开始训练2分类器的时候问题来了,一般来说没买的用户数会远远大于已经买了的用户数,当将数量不均衡的正负样本投入训练时,训练出的分类器会有较大的bias(偏向值)。因此,这时可以使用OneCLassClassification方法来解决,即训练集中只有已经买过该产品的用户数据,在识别一个新用户是否会买该产品时,识别结果就是“会”或者“不会”。

来看图,一分类就是左图中一大堆点的区域,当有超过这一堆的就会分到另外一类。

一、关于一类SVM的形象解释

首先先看下我们的问题,我们希望确定新的训练数据是否属于某个特定类?怎么会有这样的应用场景呢?比方说,我们要判断一张照片里的人脸,是男性还是女性,这是个二分类问题。就是将一堆已标注了男女性别的人脸照片(假设男性是正样本,女性是负样本),提取出有区分性别的特征(假设这种能区分男女性别的特征已构建好)后,通过svm中的支持向量,找到这男女两类性别特征点的最大间隔。进而在输入一张未知性别的照片后,经过特征提取步骤,就可以通过这个训练好的svm很快得出照片内人物的性别,此时我们得出的结论,我们知道要么是男性,不是男性的话,那一定是女性。以上情况是假设,我们用于训练的样本,包括了男女两类的图片,并且两类图片的数目较为均衡。现实生活中的我们也是这样,我们只有在接触了足够多的男生女生,知道了男生女生的性别特征差异后(比方说女性一般有长头发,男性一般有胡子等等),才能准确判断出这个人到底是男是女。

但如果有一个特殊的场景,比方说,有一个小和尚,他从小在寺庙长大,从来都只见过男生,没见过女生,那么对于一个男性,他能很快地基于这个男性与他之前接触的男性有类似的特征,给出这个人是男性的答案。但如果是一个女性,他会发现,这个女性与他之前所认知的男性的特征差异很大,进而会得出她不是男性的判断。但注意这里的“她不是男性”不能直接归结为她是女性。

再比如,在工厂设备中,控制系统的任务是判断是是否有意外情况出现,例如产品质量过低、机器产生奇怪的震动或者温度上升等。相对来说容易收集到正常场景下的训练数据,但故障系统状态的收集示例数据可能相当昂贵,或者根本不可能。 如果可以模拟一个错误的系统状态,但必然无法保证所有的错误状态都被模拟到,从而在传统的两类问题中得到识别。

二、OneClassSVM主要参数和方法
class sklearn.svm.OneClassSVM(
								kernel=’rbf’, 
				                degree=3, 
				                gamma=’auto’, 
				                coef0=0.0, 
				                tol=0.001, 
				                nu=0.5, 
				                shrinking=True, 
				                cache_size=200, 
				                verbose=False, 
				                max_iter=-1, 
				                random_state=None)
1、参数
  • kernel:核函数(一般用高斯核)
  • nu:设定训练误差(0, 1]
2、方法
  • fit(x):训练,根据训练样本和上面两个参数探测边界。(注意是无监督哦!)
  • predict(x):返回预测值,+1就是正常样本,-1为异常样本。
  • decision_function(X):返回各样本点到超平面的函数距离(signed distance),正的为正常样本,负的为异常样本。
3、OneClassSVM官方实例
#!/usr/bin/python
# -*- coding:utf-8 -*-
 
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager
from sklearn import svm
 
xx, yy = np.meshgrid(np.linspace(-5, 5, 500), np.linspace(-5, 5, 500))
# Generate train data
X = 0.3 * np.random.randn(100, 2)
X_train = np.r_[X + 2, X - 2]
# Generate some regular novel observations
X = 0.3 * np.random.randn(20, 2)
X_test = np.r_[X + 2, X - 2]
# Generate some abnormal novel observations
X_outliers = np.random.uniform(low=-4, high=4, size=(20, 2))
 
# fit the model
clf = svm.OneClassSVM(nu=0.1, kernel="rbf", gamma=0.1)
clf.fit(X_train)
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
n_error_train = y_pred_train[y_pred_train == -1].size
n_error_test = y_pred_test[y_pred_test == -1].size
n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size
 
# plot the line, the points, and the nearest vectors to the plane
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
 
plt.title("Novelty Detection")
plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)  #绘制异常样本的区域
a = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='darkred')  #绘制正常样本和异常样本的边界
plt.contourf(xx, yy, Z, levels=[0, Z.max()], colors='palevioletred')   #绘制正常样本的区域
s = 40
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white', s=s, edgecolors='k')
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='blueviolet', s=s,
                 edgecolors='k')
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='gold', s=s,
                edgecolors='k')
plt.axis('tight')
plt.xlim((-5, 5))
plt.ylim((-5, 5))
plt.legend([a.collections[0], b1, b2, c],
           ["learned frontier", "training observations",
            "new regular observations", "new abnormal observations"],
           loc="upper left",
           prop=matplotlib.font_manager.FontProperties(size=11))
plt.xlabel(
    "error train: %d/200 ; errors novel regular: %d/40 ; "
    "errors novel abnormal: %d/40"
    % (n_error_train, n_error_test, n_error_outliers))
plt.show()




参考资料:
异常检测(一)——OneClassSVM
无监督︱异常、离群点检测 一分类——OneClassSVM
One-Class SVM介绍
scikit-learn官网:2.7. Novelty and Outlier Detection
sklearn之OneClassSVM
什么是一类支持向量机(one class SVM),是指分两类的支持向量机吗?
One-class SVM with non-linear kernel (RBF)
什么是一类支持向量机(one class SVM),是指分两类的支持向量机吗?

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/727622.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存