上一个博客中,我们讨论了基于统计学的异常检测算法,其中还通过pyod库展示了两个demo,分别是一元正态分布的例子和HBOS的例子。在这篇博客中,我们将会讨论另一个类别的异常检测算法–基于线性模型的异常检测。
在基于线性模型的异常检测中,常常可以通过训练出一个线性分类器来检测新的样本点是否为异常样本。如下图:
在这个图片中,通过输入训练样本集的特征矩阵X,学习一个分类器 c ( x ) c(x) c(x),等到新的样本来临时,通过将 c ( x ) c(x) c(x)的值与阈值 λ \lambda λ进行比较。
熟悉机器学习的同学们,是不是觉得上述模型很像 用逻辑回归做二分类问题呢?
真实数据集中不同维度的数据通常具有高度的相关性,这是因为不同的属性往往是由相同的基础过程以密切相关的方式产生的。在古典统计学中,这被称为——回归建模,一种参数化的相关性分析。
一类相关性分析试图通过其他变量预测单独的属性值,另一类方法用一些潜在变量来代表整个数据。前者的代表是 线性回归,后者一个典型的例子是 主成分分析。本文将会用这两种典型的线性相关分析方法进行异常检测。
需要明确的是,这里有两个重要的假设:
假设一:近似线性相关假设。线性相关假设是使用两种模型进行异常检测的重要理论基础。
假设二:子空间假设。子空间假设认为数据是镶嵌在低维子空间中的,线性方法的目的是找到合适的低维子空间使得异常点(o)在其中区别于正常点(n)。
基于这两点假设,在异常检测的第一阶段,为了确定特定的模型是否适合特定的数据集,对数据进行探索性和可视化分析是非常关键的。
在线性回归中,我们假设不同维度的变量具有一定的相关性,并可以通过一个相关系数矩阵进行衡量。因此对于特定的观测值,可以通过线性方程组来建模。在实际应用中,观测值的数量往往远大于数据的维度,导致线性方程组是一个超定方程,不能直接求解。因此需要通过优化的方法,最小化模型预测值与真实数据点的误差。
这里先回顾一下线性回归模型,这里参考一下吴恩达老师的机器学习,感谢中科院黄海广博士对吴恩达老师机器学习课程的学习笔记。
让我们通过一个例子来开始:这个例子是预测住房价格的,我们要使用一个数据集,数 据集包含俄勒冈州波特兰市的住房价格。在这里,我要根据不同房屋尺寸所售出的价格,画 出我的数据集。比方说,如果你朋友的房子是 1250 平方尺大小,你要告诉他们这房子能卖 多少钱。那么,你可以做的一件事就是构建一个模型,也许是条直线,从这个数据模型上来 看,也许你可以告诉你的朋友,他能以大约 220000(美元)左右的价格卖掉这个房子。这就是回归算法的一个例子。
再形式化一些:
以之前的房屋交易问题为例,假使我们回归问题的训练集(Training Set)如下表所示:
我们可以看到这里有我们的训练集里房屋价格 我们把它喂给我们的学习算法,学习算法的工作了,然后输出一个函数,通常表示为小写 ℎ 表示。ℎ 代表 hypothesis(假设),ℎ表示一个函数,输入是房屋尺寸大小,就像你朋友想出售 的房屋,因此 ℎ 根据输入的 值来得出 值, 值对应房子的价格 因此,ℎ 是一个从 到 的函数映射。
那么, 对于我们的房价预测问题,我们该如何表达 ℎ? 一种可能的表达方式为:ℎ () = 0 + 1,因为只含有一个特征/输入变量,因此这样 的问题叫作单变量线性回归问题
。
同样也有``多变量线性回归问题。 ℎ 表示为:ℎ
() = 0 + 11 + 22+. . . +,`。
再说一说线性回归的优化问题。
代价函数的求解方式梯度下降方法
和最小二乘法的正规方程
.等。
以上简单回顾了线性回归模型,下面回到正题。
线性回归是统计学中一个重要的应用,这个重要的应用往往是指通过一系列自变量去预测一个特殊因变量的值。在这种情况下,异常值是根据其他自变量对因变量的影响来定义的,而自变量之间相互关系中的异常则不那么重要。这里的异常点检测主要用于数据降噪,避免异常点的出现对模型性能的影响,因而这里关注的兴趣点主要是正常值(n)。而我们通常所说的异常检测中并不会对任何变量给与特殊对待,异常值的定义是基于基础数据点的整体分布,这里我们关注的兴趣点主要是异常值(o)。
广义的回归建模只是一种工具,这种工具既可以用来进行数据降噪也可以进行异常点检测。
对于目标函数的优化,一般有两种思路,一种是最小二乘法(正规方程),二是梯度下降方法,下面简单说一下。
就上文的预测房价的例子而言,假设线性函数形式:。
代价函数(采用误差的平方和)为:
我们当然希望,代价函数越小越好,代价函数越小说明模型更准确(但是要特别注意过拟合的问题!!!)。
梯度下降法
背后思想:开始时我们随机选择一个参数的组合(0, 1, . . . . . . , ),计算代 价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。我们持续这么做直到到 到一个局部最小值(local minimum),因为我们并没有尝试完所有的参数组合,所以不能确 定我们得到的局部最小值是否便是全局最小值(global minimum),选择不同的初始参数组 合,可能会找到不同的局部最小值。
算法:
最小二乘法(正规方程)也是一种用来求参数使其代价函数最优的方法。
最小二乘法可以将误差方程转化为有确定解的代数方程组(其方程式数目正好等于未知数的个数),从而可求解出这些未知参数。这个有确定解的代数方程组称为最小二乘法估计的正规方程(或称为法方程)。
一句话总结特征数少数据集小适合正规方程法,大数据集适合梯度下降法。
拓展资料:吴恩达机器学习笔记。链接:https://pan.baidu.com/share/init?surl=G1mDEKmPSr2feoPwbgOu8w密码:9wi4
前一节讨论了这样一种情况:即一个特定的变量被认为是特殊的,最优平面是通过最小化该特殊变量的均方误差而确定的。而我们通常所说的异常检测中并不会对任何变量给与特殊对待,异常值的定义是基于基础数据点的整体分布,因此需要采用一种更一般的回归建模:即以相似的方式对待所有变量,通过最小化数据对该平面的投影误差确定最佳回归平面。在这种情况下,假设我们有一组变量 X 1 … X d X_{1}… X_{d} X1…Xd, 对应的回归平面如下:
a 1 ⋅ X 1 + … + a d ⋅ X d + a d + 1 = 0 a_{1} \cdot X_{1}+\ldots+a_{d} \cdot X_{d}+a_{d+1}=0 a1⋅X1+…+ad⋅Xd+ad+1=0
为了后续计算的方便,对参数进行如下约束:
∑ i = 1 d a i 2 = 1 \sum\limits_{i = 1}^d {a_i^2 = 1} i=1∑dai2=1
以 L 2 L_{2} L2范数作为目标函数:
L = ∥ U ⋅ A ∥ 2 L = {\left\| {U \cdot A} \right\|_2} L=∥U⋅A∥2
L2范数是什么?
L2范数是指向量各元素的平方和然后求平方根,L2对大数,对outlier离群点更敏感!
这样的一个问题可以通过主成分分析方法得到有效解决,我们会单独用一个部分进行讨论。
上一节的最小二乘法试图找到一个与数据具有最佳匹配 ( d − 1 ) (d−1) (d−1) 维超平面。主成分分析方法可用于解决这一问题的广义版本。具体来说,它可以找到任意 k ( k < d ) k( k
对于 d d d 维,包含 N N N 个样本的数据,用 R i R_{i} Ri 表示其中第 i i i 行为: [ x i 1 . . . x i d ] [x_{i1}... x_{id}] [xi1...xid]。由此可以得到 d × d d \times d d×d 的协方差矩阵(标准的PCA应当计算相关系数矩阵,即对数据进行均值为0方差为1的标准化处理,而协方差矩阵只需要减去均值即可):
Σ = ( R − R ˉ ) T ⋅ ( R − R ˉ ) Σ = (R - \bar{R})^{T} \cdot (R - \bar{R}) Σ=(R−Rˉ)T⋅(R−Rˉ)
易知协方差矩阵 Σ Σ Σ 是对称并且半正定的,因此可以进行相似对角化:
Σ = P ⋅ D ⋅ P T Σ = P \cdot D \cdot P^{T} Σ=P⋅D⋅PT
这里的 D D D 为对角矩阵,对角元素为特征值; P P P 为标准正交矩阵,每一行为对应的特征向量;这些标准正交向量提供了数据应该投影的轴线方向。与异常检测相关的主成分分析的主要性质如下:
- 如果前 k k k 的特征向量选定之后(根据最大的 k k k个特征值),由这些特征向量定义的 k k k 维超平面是在所有维度为 k k k 的超平面中,所有数据点到它的均方距离尽可能小的平面。
- 如果将数据转换为与正交特征向量对应的轴系,则转换后的数据沿每个特征向量维的方差等于相应的特征值。在这种新表示中,转换后的数据的协方差为0。
- 由于沿特征值小的特征向量的转换数据的方差很低,因此沿这些方向的变换数据与平均值的显着偏差可能表示离群值。
需要注意的是,相比2.2节的内容,这里提供了一个更加普遍的解决方法。2.2中的内容可以归为主成分分析中只保留最大特征值对应的特征向量的情况。
在得到这些特征值和特征向量之后,可以将数据转换到新的坐标系中。以 Y 1 . . . Y N Y_{1}...Y_{N} Y1...YN 表示新坐标系中的数据,这些数据可以通过原始向量 R i R_{i} Ri 与包含新轴系的标准正交特征向量矩阵 P P P 的乘积来实现。
Y i = R i ⋅ P {Y_i} = {R_i} \cdot P Yi=Ri⋅P
在许多涉及高维数据集的真实场景中,很大一部分特征值往往非常接近于零。这意味着大多数数据都沿着一个低维的子空间排列。从异常检测的角度来看,这是非常方便的,因为离这些投影方向非常远的观测值可以被假定为离群值。例如,对于特征值较小(方差较小)的特征向量 j j j,第 i i i 条记录的 y i j y_{ij} yij 与 y k j y_{kj} ykj 的其他值的偏差较大,说明有离群行为。这是因为当 j j j固定而 k k k变化时, y k j y_{kj} ykj 的值应当变化不大。因此, y i j y_{ij} yij 值是不常见的。
在不选取任何特定的 k k k 维集合的情况下,一种更精确的异常检测建模方法是使用特征值来计算数据点沿每个主分量方向到质心的归一化距离。设 e j e_{j} ej为第 j j j 个特征向量, λ j λ_{j} λj 为沿该方向的方差(特征值)。数据点 X ˉ \bar{X} Xˉ相对于对数据质心$\bar{\mu} $的总体归一化异常得分可以由下式给出:
S core ( X ˉ ) = ∑ j = 1 d ∣ ( X ˉ − μ ˉ ) ⋅ e ˉ j ∣ 2 λ j S \operatorname{core}(\bar{X})=\sum_{j=1}^{d} \frac{\left|(\bar{X}-\bar{\mu}) \cdot \bar{e}_{j}\right|^{2}}{\lambda_{j}} Score(Xˉ)=j=1∑dλj∣∣(Xˉ−μˉ)⋅eˉj∣∣2
值得注意的是,对异常得分的大部分贡献是由 λ j λ_{j} λj 值较小的主成分的偏差提供的,这一点上文中有提及过。主成分分析比因变量回归能更稳定地处理少数异常值的存在。这是因为主成分分析是根据最优超平面来计算误差的,而不是一个特定的变量。当数据中加入更多的离群点时,最优超平面的变化通常不会大到影响离群点的选择。因此,这种方法更有可能选择正确的异常值,因为回归模型一开始就更准确。
当不同维度的尺度差别较大时,使用 P C A PCA PCA 有时并不能得到直观有效的结果。例如,考虑一个包含年龄和工资等属性的人口统计数据集。工资属性的范围可能是几万,而年龄属性几乎总是小于100,使用主成分分析会导致主成分被高方差属性所控制。对于一个只包含年龄和工资的二维数据集,最大的特征向量几乎与工资轴平行,这会降低异常点检测过程的有效性。因此,一个自然的解决方案是对数据进行均值为0方差为1的标准化处理。这隐含地导致在主成分分析中使用相关矩阵而不是协方差矩阵。当然,这个问题并不是线性建模所独有的,对于大多数异常检测算法,都需要使用这样的预处理。
from pyod.models.pca import PCA
from pyod.utils.data import generate_data
from pyod.utils.data import evaluate_print
from pyod.utils.example import visualize
# Generate sample data
X_train, y_train, X_test, y_test = \
generate_data(n_train=1000, # number of training points
n_test=300, # number of testing points
n_features=2,
contamination=0.05, # percentage of outliers
random_state=123)
# train one_class_svm detector
clf_name = 'PCA'
clf = PCA()
clf.fit(X_train)
# get the prediction labels and outlier scores of the training data
y_train_pred = clf.labels_ # binary labels (0: inliers, 1: outliers)
y_train_scores = clf.decision_scores_ # raw outlier scores
# get the prediction on the test data
y_test_pred = clf.predict(X_test) # outlier labels (0 or 1)
y_test_scores = clf.decision_function(X_test) # outlier scores
# evaluate and print the results
print("\nOn Training Data:")
evaluate_print(clf_name, y_train, y_train_scores)
print("\nOn Test Data:")
evaluate_print(clf_name, y_test, y_test_scores)
visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,y_test_pred, show_figure=True, save_figure=False)
PCA结果:
On Training Data:
PCA ROC:0.9804, precision @ rank n:0.88
On Test Data:
PCA ROC:0.9846, precision @ rank n:0.8667
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UjTiEIX-1621237036308)(C:\Users\32505\AppData\Roaming\Typora\typora-user-images\image-20210515210757277.png)]
我们在和上一节的使用HBOS的结果做个对比。
HBOS的结果如下:
On Training Data:
HBOS ROC:0.9947, precision @ rank n:0.8
On Test Data:
HBOS ROC:0.9744, precision @ rank n:0.6
可见PCA的效果稍优于HBOS。
真实数据中,数据不同属性之间往往具有显著的相关性。在这种情况下,线性建模可以提供一种有效的工具来从底层数据中移除异常值或者进行异常检测。对于其他基于因变量回归的应用,线性建模是一种工具,去除异常值对于提高此类应用的性能是非常重要的。在大多数情况下,主成分分析提供了去除异常值和进行异常检测最有效的方法,因为它对存在少数异常值的数据更有鲁棒性。
[1]Datawhale.异常检测.2021年.https://github.com/datawhalechina/team-learning-data-mining/tree/master/AnomalyDetection
[2]吴恩达.机器学习.https://www.coursera.org/learn/machine-learning
[3]黄海广.机器学习笔记.https://gitee.com/duan_xu_fu/Coursera-ML-AndrewNg-Notes?_from=gitee_search
[4]CSDN.无盐薯片.异常检测-线性模型.https://blog.csdn.net/weixin_43557816