无监督学习中的异常值检测
依据训练数据是否被污染, 检测可分为离群点检测
和新奇点检测
- 离群点检测: 训练数据包含离群点,即远离其它内围点。离群点检测估计器会尝试拟合出训练数据中内围点聚集的区域, 会忽略有偏离的观测值。也被称之为无监督异常检测
- 新奇点检测: 训练数据未被离群点污染,我们对新观测值是否为离群点感兴趣。在这个语境下,离群点被认为是新奇点。也被称之为 半监督异常检测。
简单来说:训练数据中包含异常值的为离群点检测,否则为新奇点检测。
孤立森林(Isolation Forest)
定义
在高维数据集中实现离群点检测的一种有效方法是使用随机森林。
ensemble.IsolationForest
通过随机选择一个特征,然后随机选择所选特征的最大值和最小值之间的分割值来"隔离"观测。由于递归划分可以由树形结构表示,因此隔离样本所需的分割次数等同于从根节点到终止节点的路径长度。
在这样的随机树的森林中取平均的路径长度是数据正态性和我们的决策功能的量度。
随机划分能为异常观测产生明显的较短路径。 因此,当随机树的森林共同地为特定样本产生较短的路径长度时,这些样本就很有可能是异常的。
ensemble.IsolationForest的实现,是基于tree.ExtraTreeRegressor全体.按照隔离森林的原始论文,每棵树的最大深度设置为
log2(n)
,其中n是构建树所用的样本数量。
概括来说就是:
假设我们用一个随机超平面来切割(split)数据空间(data space), 切一次可以生成两个子空间(想象拿刀切蛋糕一分为二)。之后我们再继续用一个随机超平面来切割每个子空间,循环下去,直到每子空间里面只有一个数据点为止。
直观上来讲,我们可以发现那些密度很高的簇是可以被切很多次才会停止切割,但是那些密度很低的点很容易很早的就停到一个子空间里了。
孤立森林算法在大部分工业异常检测场景中,已经被证实是坠吼的(推眼镜)。参考链接
适用范围
- 异常数据占总样本量的比例很小;
- 异常点的特征值与正常点的差异很大。
注意点
- 若训练样本中异常样本的比例较高,可能会导致最终结果不理想,因为这违背了该算法的理论基础;
- 异常检测跟具体的应用场景紧密相关,因此算法检测出的 “异常” 不一定是实际场景中的真正异常,所以在特征选择时,要尽量过滤不相关的特征。
简单的Demo
ilf = IsolationForest(n_estimators=100, # 森林中树的颗数default=100
n_jobs=-1, # 使用全部cpu
verbose=2, # 控制树构建过程的冗长性
)
data = pd_base
data = data.fillna(0)
# 选取特征,不使用标签(类型)
X_cols = ['PARTICLE']# 'DEVICE_CODE','ERR_CODE',
# 训练
ilf.fit(data[X_cols])
test = data[X_cols]
# 预测
pred = ilf.predict(test)
data['pred'] =pred
data.to_csv('outliers.csv', columns=["pred",], header=False)
IsolationForest
参数详细说明:
-
n_estimators : int, optional (default=100)
指定该森林中生成的随机树数量
-
max_samples : int or float, optional (default=”auto”)
用来训练随机数的样本数量,即子采样的大小
- 如果设置的是一个int常数,那么就会从总样本X拉取max_samples个样本来生成一棵树Tree
- 如果设置的是一个float浮点数,那么就会从总样本X拉取max_samples *
X.shape[0]
个样本,X.shape[0]
表示总样本个数 - 如果设置的是"auto",则max_samples=min(256, n_samples),n_samples即总样本的数量
-
contamination : float in (0., 0.5), optional (default=0.1)
取值范围为(0., 0.5),表示异常数据占给定的数据集的比例
数据集中污染的数量,其实就是训练数据中异常数据的数量,比如数据集异常数据的比例。定义该参数值的作用是在决策函数中定义阈值。如果设置为'auto',则决策函数的阈值就和论文中定义的一样
在版本0.20中有变化:默认值从0.1变为0.22版本中的'auto'
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。